that contains calendar
+ calendarLinkName: 'calendarlink', // name of the link that is used to toggle
+ clockDivName: 'clockbox', // name of clock
that gets toggled
+ clockLinkName: 'clocklink', // name of the link that is used to toggle
shortCutsClass: 'datetimeshortcuts', // class of the clock and cal shortcuts
timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch
timezoneOffset: 0,
diff -Nru python-django-1.11.21/django/contrib/admin/static/admin/js/core.js python-django-1.11.22/django/contrib/admin/static/admin/js/core.js
--- python-django-1.11.21/django/contrib/admin/static/admin/js/core.js 2019-06-03 06:44:24.000000000 -0300
+++ python-django-1.11.22/django/contrib/admin/static/admin/js/core.js 2019-07-01 03:39:45.000000000 -0300
@@ -191,9 +191,9 @@
return result;
};
-// ----------------------------------------------------------------------------
-// String object extensions
-// ----------------------------------------------------------------------------
+ // ----------------------------------------------------------------------------
+ // String object extensions
+ // ----------------------------------------------------------------------------
String.prototype.pad_left = function(pad_length, pad_string) {
var new_string = this;
for (var i = 0; new_string.length < pad_length; i++) {
@@ -209,18 +209,18 @@
var day, month, year;
while (i < split_format.length) {
switch (split_format[i]) {
- case "%d":
- day = date[i];
- break;
- case "%m":
- month = date[i] - 1;
- break;
- case "%Y":
- year = date[i];
- break;
- case "%y":
- year = date[i];
- break;
+ case "%d":
+ day = date[i];
+ break;
+ case "%m":
+ month = date[i] - 1;
+ break;
+ case "%Y":
+ year = date[i];
+ break;
+ case "%y":
+ year = date[i];
+ break;
}
++i;
}
diff -Nru python-django-1.11.21/django/contrib/admin/static/admin/js/inlines.js python-django-1.11.22/django/contrib/admin/static/admin/js/inlines.js
--- python-django-1.11.21/django/contrib/admin/static/admin/js/inlines.js 2019-06-03 06:44:24.000000000 -0300
+++ python-django-1.11.22/django/contrib/admin/static/admin/js/inlines.js 2019-07-01 03:39:45.000000000 -0300
@@ -63,8 +63,8 @@
var template = $("#" + options.prefix + "-empty");
var row = template.clone(true);
row.removeClass(options.emptyCssClass)
- .addClass(options.formCssClass)
- .attr("id", options.prefix + "-" + nextIndex);
+ .addClass(options.formCssClass)
+ .attr("id", options.prefix + "-" + nextIndex);
if (row.is("tr")) {
// If the forms are laid out in table rows, insert
// the remove button into the last table cell:
@@ -131,16 +131,16 @@
/* Setup plugin defaults */
$.fn.formset.defaults = {
- prefix: "form", // The form prefix for your django formset
- addText: "add another", // Text for the add link
- deleteText: "remove", // Text for the delete link
- addCssClass: "add-row", // CSS class applied to the add link
- deleteCssClass: "delete-row", // CSS class applied to the delete link
- emptyCssClass: "empty-row", // CSS class applied to the empty row
- formCssClass: "dynamic-form", // CSS class applied to each form in a formset
- added: null, // Function called each time a new form is added
- removed: null, // Function called each time a form is deleted
- addButton: null // Existing add button to use
+ prefix: "form", // The form prefix for your django formset
+ addText: "add another", // Text for the add link
+ deleteText: "remove", // Text for the delete link
+ addCssClass: "add-row", // CSS class applied to the add link
+ deleteCssClass: "delete-row", // CSS class applied to the delete link
+ emptyCssClass: "empty-row", // CSS class applied to the empty row
+ formCssClass: "dynamic-form", // CSS class applied to each form in a formset
+ added: null, // Function called each time a new form is added
+ removed: null, // Function called each time a form is deleted
+ addButton: null // Existing add button to use
};
@@ -149,8 +149,8 @@
var $rows = $(this);
var alternatingRows = function(row) {
$($rows.selector).not(".add-row").removeClass("row1 row2")
- .filter(":even").addClass("row1").end()
- .filter(":odd").addClass("row2");
+ .filter(":even").addClass("row1").end()
+ .filter(":odd").addClass("row2");
};
var reinitDateTimeShortCuts = function() {
diff -Nru python-django-1.11.21/django/contrib/admin/static/admin/js/urlify.js python-django-1.11.22/django/contrib/admin/static/admin/js/urlify.js
--- python-django-1.11.21/django/contrib/admin/static/admin/js/urlify.js 2019-06-03 06:44:24.000000000 -0300
+++ python-django-1.11.22/django/contrib/admin/static/admin/js/urlify.js 2019-07-01 03:39:45.000000000 -0300
@@ -119,7 +119,7 @@
var Downcoder = {
'Initialize': function() {
- if (Downcoder.map) { // already made
+ if (Downcoder.map) { // already made
return;
}
Downcoder.map = {};
@@ -168,12 +168,12 @@
// characters, whitespace, and dash; remove other characters.
s = XRegExp.replace(s, XRegExp('[^-_\\p{L}\\p{N}\\s]', 'g'), '');
} else {
- s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars
+ s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars
}
- s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
- s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens
- s = s.toLowerCase(); // convert to lowercase
- return s.substring(0, num_chars); // trim to first num_chars chars
+ s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
+ s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens
+ s = s.toLowerCase(); // convert to lowercase
+ return s.substring(0, num_chars); // trim to first num_chars chars
}
window.URLify = URLify;
})();
diff -Nru python-django-1.11.21/django/contrib/gis/static/gis/js/OLMapWidget.js python-django-1.11.22/django/contrib/gis/static/gis/js/OLMapWidget.js
--- python-django-1.11.21/django/contrib/gis/static/gis/js/OLMapWidget.js 2019-06-03 06:44:25.000000000 -0300
+++ python-django-1.11.22/django/contrib/gis/static/gis/js/OLMapWidget.js 2019-07-01 03:39:46.000000000 -0300
@@ -207,15 +207,15 @@
} else {
geometry = features[0].getGeometry().clone();
for (var j = 1; j < features.length; j++) {
- switch(geometry.getType()) {
- case "MultiPoint":
- geometry.appendPoint(features[j].getGeometry().getPoint(0));
- break;
- case "MultiLineString":
- geometry.appendLineString(features[j].getGeometry().getLineString(0));
- break;
- case "MultiPolygon":
- geometry.appendPolygon(features[j].getGeometry().getPolygon(0));
+ switch (geometry.getType()) {
+ case "MultiPoint":
+ geometry.appendPoint(features[j].getGeometry().getPoint(0));
+ break;
+ case "MultiLineString":
+ geometry.appendLineString(features[j].getGeometry().getLineString(0));
+ break;
+ case "MultiPolygon":
+ geometry.appendPolygon(features[j].getGeometry().getPolygon(0));
}
}
}
diff -Nru python-django-1.11.21/django/http/request.py python-django-1.11.22/django/http/request.py
--- python-django-1.11.21/django/http/request.py 2019-06-03 06:44:25.000000000 -0300
+++ python-django-1.11.22/django/http/request.py 2019-07-01 03:39:53.000000000 -0300
@@ -199,13 +199,14 @@
def scheme(self):
if settings.SECURE_PROXY_SSL_HEADER:
try:
- header, value = settings.SECURE_PROXY_SSL_HEADER
+ header, secure_value = settings.SECURE_PROXY_SSL_HEADER
except ValueError:
raise ImproperlyConfigured(
'The SECURE_PROXY_SSL_HEADER setting must be a tuple containing two values.'
)
- if self.META.get(header) == value:
- return 'https'
+ header_value = self.META.get(header)
+ if header_value is not None:
+ return 'https' if header_value == secure_value else 'http'
return self._get_scheme()
def is_secure(self):
diff -Nru python-django-1.11.21/docs/ref/settings.txt python-django-1.11.22/docs/ref/settings.txt
--- python-django-1.11.21/docs/ref/settings.txt 2019-06-03 06:44:25.000000000 -0300
+++ python-django-1.11.22/docs/ref/settings.txt 2019-07-01 03:39:53.000000000 -0300
@@ -2189,10 +2189,13 @@
"https://". This is important for Django's CSRF protection, and may be used
by your own code or third-party apps.
-If your Django app is behind a proxy, though, the proxy may be "swallowing" the
-fact that a request is HTTPS, using a non-HTTPS connection between the proxy
-and Django. In this case, ``is_secure()`` would always return ``False`` -- even
-for requests that were made via HTTPS by the end user.
+If your Django app is behind a proxy, though, the proxy may be "swallowing"
+whether the original request uses HTTPS or not. If there is a non-HTTPS
+connection between the proxy and Django then ``is_secure()`` would always
+return ``False`` -- even for requests that were made via HTTPS by the end user.
+In contrast, if there is an HTTPS connection between the proxy and Django then
+``is_secure()`` would always return ``True`` -- even for requests that were
+made originally via HTTP.
In this situation, you'll want to configure your proxy to set a custom HTTP
header that tells Django whether the request came in via HTTPS, and you'll want
diff -Nru python-django-1.11.21/docs/releases/1.11.21.txt python-django-1.11.22/docs/releases/1.11.21.txt
--- python-django-1.11.21/docs/releases/1.11.21.txt 2019-06-03 06:38:19.000000000 -0300
+++ python-django-1.11.22/docs/releases/1.11.21.txt 2019-07-01 03:39:09.000000000 -0300
@@ -16,6 +16,6 @@
``AdminURLFieldWidget`` now validates the provided value using
:class:`~django.core.validators.URLValidator` before displaying the clickable
-link. You may customise the validator by passing a ``validator_class`` kwarg to
+link. You may customize the validator by passing a ``validator_class`` kwarg to
``AdminURLFieldWidget.__init__()``, e.g. when using
:attr:`~django.contrib.admin.ModelAdmin.formfield_overrides`.
diff -Nru python-django-1.11.21/docs/releases/1.11.22.txt python-django-1.11.22/docs/releases/1.11.22.txt
--- python-django-1.11.21/docs/releases/1.11.22.txt 1969-12-31 21:00:00.000000000 -0300
+++ python-django-1.11.22/docs/releases/1.11.22.txt 2019-07-01 03:39:53.000000000 -0300
@@ -0,0 +1,27 @@
+============================
+Django 1.11.22 release notes
+============================
+
+*July 1, 2019*
+
+Django 1.11.22 fixes a security issue in 1.11.21.
+
+CVE-2019-12781: Incorrect HTTP detection with reverse-proxy connecting via HTTPS
+--------------------------------------------------------------------------------
+
+When deployed behind a reverse-proxy connecting to Django via HTTPS,
+:attr:`django.http.HttpRequest.scheme` would incorrectly detect client
+requests made via HTTP as using HTTPS. This entails incorrect results for
+:meth:`~django.http.HttpRequest.is_secure`, and
+:meth:`~django.http.HttpRequest.build_absolute_uri`, and that HTTP
+requests would not be redirected to HTTPS in accordance with
+:setting:`SECURE_SSL_REDIRECT`.
+
+``HttpRequest.scheme`` now respects :setting:`SECURE_PROXY_SSL_HEADER`, if it
+is configured, and the appropriate header is set on the request, for both HTTP
+and HTTPS requests.
+
+If you deploy Django behind a reverse-proxy that forwards HTTP requests, and
+that connects to Django via HTTPS, be sure to verify that your application
+correctly handles code paths relying on ``scheme``, ``is_secure()``,
+``build_absolute_uri()``, and ``SECURE_SSL_REDIRECT``.
diff -Nru python-django-1.11.21/docs/releases/index.txt python-django-1.11.22/docs/releases/index.txt
--- python-django-1.11.21/docs/releases/index.txt 2019-06-03 06:44:25.000000000 -0300
+++ python-django-1.11.22/docs/releases/index.txt 2019-07-01 03:39:46.000000000 -0300
@@ -26,6 +26,7 @@
.. toctree::
:maxdepth: 1
+ 1.11.22
1.11.21
1.11.20
1.11.19
diff -Nru python-django-1.11.21/docs/releases/security.txt python-django-1.11.22/docs/releases/security.txt
--- python-django-1.11.21/docs/releases/security.txt 2019-06-03 04:27:55.000000000 -0300
+++ python-django-1.11.22/docs/releases/security.txt 2019-07-01 03:39:09.000000000 -0300
@@ -936,3 +936,28 @@
* Django 2.0 :commit:`(patch <1f42f82566c9d2d73aff1c42790d6b1b243f7676>` and
:commit:`correction) <392e040647403fc8007708d52ce01d915b014849>`
* Django 1.11 :commit:`(patch) <0bbb560183fabf0533289700845dafa94951f227>`
+
+June 3, 2019 - :cve:`2019-11358`
+--------------------------------
+
+Prototype pollution in bundled jQuery. `Full description
+
`__
+
+Versions affected
+~~~~~~~~~~~~~~~~~
+
+* Django 2.2 :commit:`(patch)
`
+* Django 2.1 :commit:`(patch) <95649bc08547a878cebfa1d019edec8cb1b80829>`
+
+June 3, 2019 - :cve:`2019-12308`
+--------------------------------
+
+XSS via "Current URL" link generated by ``AdminURLFieldWidget``. `Full
+description `__
+
+Versions affected
+~~~~~~~~~~~~~~~~~
+
+* Django 2.2 :commit:`(patch) `
+* Django 2.1 :commit:`(patch) <09186a13d975de6d049f8b3e05484f66b01ece62>`
+* Django 1.11 :commit:`(patch) `
diff -Nru python-django-1.11.21/js_tests/admin/inlines.test.js python-django-1.11.22/js_tests/admin/inlines.test.js
--- python-django-1.11.21/js_tests/admin/inlines.test.js 2019-06-03 06:44:25.000000000 -0300
+++ python-django-1.11.22/js_tests/admin/inlines.test.js 2019-07-01 03:39:46.000000000 -0300
@@ -54,7 +54,7 @@
QUnit.test('existing add button', function(assert) {
var $ = django.jQuery;
- $('#qunit-fixture').empty(); // Clear the table added in beforeEach
+ $('#qunit-fixture').empty(); // Clear the table added in beforeEach
$('#qunit-fixture').append($('#tabular-formset').text());
this.table = $('table.inline');
this.inlineRow = this.table.find('tr');
diff -Nru python-django-1.11.21/package.json python-django-1.11.22/package.json
--- python-django-1.11.21/package.json 2019-02-11 07:55:38.000000000 -0200
+++ python-django-1.11.22/package.json 2019-07-01 03:39:09.000000000 -0300
@@ -9,7 +9,7 @@
"npm": ">=1.3.0 <3.0.0"
},
"devDependencies": {
- "eslint": "^0.22.1",
+ "eslint": "^4.18.2",
"grunt": "^1.0.1",
"grunt-cli": "^1.2.0",
"grunt-contrib-qunit": "^1.2.0"
diff -Nru python-django-1.11.21/tests/gis_tests/test_geoip2.py python-django-1.11.22/tests/gis_tests/test_geoip2.py
--- python-django-1.11.21/tests/gis_tests/test_geoip2.py 2019-06-03 06:44:26.000000000 -0300
+++ python-django-1.11.22/tests/gis_tests/test_geoip2.py 2019-07-01 03:39:46.000000000 -0300
@@ -24,7 +24,7 @@
"GeoIP is required along with the GEOIP_PATH setting."
)
class GeoIPTest(unittest.TestCase):
- addr = '128.249.1.1'
+ addr = '75.41.39.1'
fqdn = 'tmc.edu'
def test01_init(self):
@@ -99,7 +99,7 @@
@mock.patch('socket.gethostbyname')
def test04_city(self, gethostbyname):
"GeoIP city querying methods."
- gethostbyname.return_value = '128.249.1.1'
+ gethostbyname.return_value = '75.41.39.1'
g = GeoIP2(country='')
for query in (self.fqdn, self.addr):
@@ -122,7 +122,7 @@
# City information dictionary.
d = g.city(query)
self.assertEqual('US', d['country_code'])
- self.assertEqual('Houston', d['city'])
+ self.assertEqual('Dallas', d['city'])
self.assertEqual('TX', d['region'])
geom = g.geos(query)
diff -Nru python-django-1.11.21/tests/settings_tests/tests.py python-django-1.11.22/tests/settings_tests/tests.py
--- python-django-1.11.21/tests/settings_tests/tests.py 2019-06-03 06:44:26.000000000 -0300
+++ python-django-1.11.22/tests/settings_tests/tests.py 2019-07-01 03:39:53.000000000 -0300
@@ -334,6 +334,18 @@
req.META['HTTP_X_FORWARDED_PROTOCOL'] = 'https'
self.assertIs(req.is_secure(), True)
+ @override_settings(SECURE_PROXY_SSL_HEADER=('HTTP_X_FORWARDED_PROTOCOL', 'https'))
+ def test_xheader_preferred_to_underlying_request(self):
+ class ProxyRequest(HttpRequest):
+ def _get_scheme(self):
+ """Proxy always connecting via HTTPS"""
+ return 'https'
+
+ # Client connects via HTTP.
+ req = ProxyRequest()
+ req.META['HTTP_X_FORWARDED_PROTOCOL'] = 'http'
+ self.assertIs(req.is_secure(), False)
+
class IsOverriddenTest(SimpleTestCase):
def test_configure(self):