diff -Nru python-django-2.2.11/debian/changelog python-django-2.2.12/debian/changelog --- python-django-2.2.11/debian/changelog 2020-03-04 16:01:27.000000000 +0000 +++ python-django-2.2.12/debian/changelog 2020-04-01 09:43:19.000000000 +0000 @@ -1,8 +1,20 @@ +python-django (2:2.2.12-1) unstable; urgency=medium + + * New upstream release. + + + -- Chris Lamb Wed, 01 Apr 2020 10:43:19 +0100 + python-django (2:2.2.11-1) unstable; urgency=medium + [ Chris Lamb ] * New upstream security release. (Closes: #953102) + [ Mattia Rizzolo ] + * Add a Breaks against python3-django-filters (<< 2.1.0). + * Mark python-django-doc as Multi-Arch:foreign (via the Multi-Arch hinter). + -- Chris Lamb Wed, 04 Mar 2020 08:01:27 -0800 python-django (2:2.2.10-1) unstable; urgency=medium diff -Nru python-django-2.2.11/django/__init__.py python-django-2.2.12/django/__init__.py --- python-django-2.2.11/django/__init__.py 2020-03-04 08:35:31.000000000 +0000 +++ python-django-2.2.12/django/__init__.py 2020-04-01 07:41:42.000000000 +0000 @@ -1,6 +1,6 @@ from django.utils.version import get_version -VERSION = (2, 2, 11, 'final', 0) +VERSION = (2, 2, 12, 'final', 0) __version__ = get_version(VERSION) diff -Nru python-django-2.2.11/django/utils/translation/trans_real.py python-django-2.2.12/django/utils/translation/trans_real.py --- python-django-2.2.11/django/utils/translation/trans_real.py 2020-03-04 08:33:59.000000000 +0000 +++ python-django-2.2.12/django/utils/translation/trans_real.py 2020-04-01 07:18:01.000000000 +0000 @@ -57,6 +57,63 @@ get_supported_language_variant.cache_clear() +class TranslationCatalog: + """ + Simulate a dict for DjangoTranslation._catalog so as multiple catalogs + with different plural equations are kept separate. + """ + def __init__(self, trans=None): + self._catalogs = [trans._catalog.copy()] if trans else [{}] + self._plurals = [trans.plural] if trans else [lambda n: int(n != 1)] + + def __getitem__(self, key): + for cat in self._catalogs: + try: + return cat[key] + except KeyError: + pass + raise KeyError(key) + + def __setitem__(self, key, value): + self._catalogs[0][key] = value + + def __contains__(self, key): + return any(key in cat for cat in self._catalogs) + + def items(self): + for cat in self._catalogs: + yield from cat.items() + + def keys(self): + for cat in self._catalogs: + yield from cat.keys() + + def update(self, trans): + # Merge if plural function is the same, else prepend. + for cat, plural in zip(self._catalogs, self._plurals): + if trans.plural.__code__ == plural.__code__: + cat.update(trans._catalog) + break + else: + self._catalogs.insert(0, trans._catalog) + self._plurals.insert(0, trans.plural) + + def get(self, key, default=None): + missing = object() + for cat in self._catalogs: + result = cat.get(key, missing) + if result is not missing: + return result + return default + + def plural(self, msgid, num): + for cat, plural in zip(self._catalogs, self._plurals): + tmsg = cat.get((msgid, plural(num))) + if tmsg is not None: + return tmsg + raise KeyError + + class DjangoTranslation(gettext_module.GNUTranslations): """ Set up the GNUTranslations context with regard to output charset. @@ -103,7 +160,7 @@ self._add_fallback(localedirs) if self._catalog is None: # No catalogs found for this language, set an empty catalog. - self._catalog = {} + self._catalog = TranslationCatalog() def __repr__(self): return "" % self.__language @@ -174,9 +231,9 @@ # Take plural and _info from first catalog found (generally Django's). self.plural = other.plural self._info = other._info.copy() - self._catalog = other._catalog.copy() + self._catalog = TranslationCatalog(other) else: - self._catalog.update(other._catalog) + self._catalog.update(other) if other._fallback: self.add_fallback(other._fallback) @@ -188,6 +245,18 @@ """Return the translation language name.""" return self.__to_language + def ngettext(self, msgid1, msgid2, n): + try: + tmsg = self._catalog.plural(msgid1, n) + except KeyError: + if self._fallback: + return self._fallback.ngettext(msgid1, msgid2, n) + if n == 1: + tmsg = msgid1 + else: + tmsg = msgid2 + return tmsg + def translation(language): """ diff -Nru python-django-2.2.11/Django.egg-info/PKG-INFO python-django-2.2.12/Django.egg-info/PKG-INFO --- python-django-2.2.11/Django.egg-info/PKG-INFO 2020-03-04 08:36:19.000000000 +0000 +++ python-django-2.2.12/Django.egg-info/PKG-INFO 2020-04-01 07:43:46.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Django -Version: 2.2.11 +Version: 2.2.12 Summary: A high-level Python Web framework that encourages rapid development and clean, pragmatic design. Home-page: https://www.djangoproject.com/ Author: Django Software Foundation @@ -75,5 +75,5 @@ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=3.5 -Provides-Extra: argon2 Provides-Extra: bcrypt +Provides-Extra: argon2 diff -Nru python-django-2.2.11/Django.egg-info/SOURCES.txt python-django-2.2.12/Django.egg-info/SOURCES.txt --- python-django-2.2.11/Django.egg-info/SOURCES.txt 2020-03-04 08:36:20.000000000 +0000 +++ python-django-2.2.12/Django.egg-info/SOURCES.txt 2020-04-01 07:43:47.000000000 +0000 @@ -3820,6 +3820,7 @@ docs/releases/2.2.1.txt docs/releases/2.2.10.txt docs/releases/2.2.11.txt +docs/releases/2.2.12.txt docs/releases/2.2.2.txt docs/releases/2.2.3.txt docs/releases/2.2.4.txt diff -Nru python-django-2.2.11/docs/releases/1.11.29.txt python-django-2.2.12/docs/releases/1.11.29.txt --- python-django-2.2.11/docs/releases/1.11.29.txt 2020-03-04 08:34:09.000000000 +0000 +++ python-django-2.2.12/docs/releases/1.11.29.txt 2020-03-19 11:17:43.000000000 +0000 @@ -4,7 +4,7 @@ *March 4, 2020* -Django 1.11.29 fixes a security issue in 1.11.29. +Django 1.11.29 fixes a security issue in 1.11.28. CVE-2020-9402: Potential SQL injection via ``tolerance`` parameter in GIS functions and aggregates on Oracle ============================================================================================================ diff -Nru python-django-2.2.11/docs/releases/2.2.12.txt python-django-2.2.12/docs/releases/2.2.12.txt --- python-django-2.2.11/docs/releases/2.2.12.txt 1970-01-01 00:00:00.000000000 +0000 +++ python-django-2.2.12/docs/releases/2.2.12.txt 2020-04-01 07:18:09.000000000 +0000 @@ -0,0 +1,13 @@ +=========================== +Django 2.2.12 release notes +=========================== + +*April 1, 2020* + +Django 2.2.12 fixes a bug in 2.2.11. + +Bugfixes +======== + +* Added the ability to handle ``.po`` files containing different plural + equations for the same language (:ticket:`30439`). diff -Nru python-django-2.2.11/docs/releases/index.txt python-django-2.2.12/docs/releases/index.txt --- python-django-2.2.11/docs/releases/index.txt 2020-03-04 08:34:09.000000000 +0000 +++ python-django-2.2.12/docs/releases/index.txt 2020-04-01 07:18:01.000000000 +0000 @@ -25,6 +25,7 @@ .. toctree:: :maxdepth: 1 + 2.2.12 2.2.11 2.2.10 2.2.9 diff -Nru python-django-2.2.11/docs/releases/security.txt python-django-2.2.12/docs/releases/security.txt --- python-django-2.2.11/docs/releases/security.txt 2020-03-04 08:03:27.000000000 +0000 +++ python-django-2.2.12/docs/releases/security.txt 2020-03-19 11:17:43.000000000 +0000 @@ -1068,3 +1068,17 @@ * Django 3.0 :commit:`(patch) <505826b469b16ab36693360da9e11fd13213421b>` * Django 2.2 :commit:`(patch) ` * Django 1.11 :commit:`(patch) <001b0634cd309e372edb6d7d95d083d02b8e37bd>` + +March 4, 2020 - :cve:`2020-9402` +-------------------------------- + +Potential SQL injection via ``tolerance`` parameter in GIS functions and +aggregates on Oracle. `Full description +`__ + +Versions affected +~~~~~~~~~~~~~~~~~ + +* Django 3.0 :commit:`(patch) <26a5cf834526e291db00385dd33d319b8271fc4c>` +* Django 2.2 :commit:`(patch) ` +* Django 1.11 :commit:`(patch) <02d97f3c9a88adc890047996e5606180bd1c6166>` diff -Nru python-django-2.2.11/docs/topics/i18n/translation.txt python-django-2.2.12/docs/topics/i18n/translation.txt --- python-django-2.2.11/docs/topics/i18n/translation.txt 2020-03-04 08:33:59.000000000 +0000 +++ python-django-2.2.12/docs/topics/i18n/translation.txt 2020-04-01 07:18:01.000000000 +0000 @@ -279,14 +279,9 @@ a format specification for argument 'name', as in 'msgstr[0]', doesn't exist in 'msgid' -.. note:: Plural form and po files +.. versionchanged: 2.2.12 - Django does not support custom plural equations in po files. As all - translation catalogs are merged, only the plural form for the main Django po - file (in ``django/conf/locale//LC_MESSAGES/django.po``) is - considered. Plural forms in all other po files are ignored. Therefore, you - should not use different plural equations in your project or application po - files. + Added support for different plural equations in ``.po`` files. .. _contextual-markers: diff -Nru python-django-2.2.11/PKG-INFO python-django-2.2.12/PKG-INFO --- python-django-2.2.11/PKG-INFO 2020-03-04 08:36:22.000000000 +0000 +++ python-django-2.2.12/PKG-INFO 2020-04-01 07:43:56.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Django -Version: 2.2.11 +Version: 2.2.12 Summary: A high-level Python Web framework that encourages rapid development and clean, pragmatic design. Home-page: https://www.djangoproject.com/ Author: Django Software Foundation @@ -75,5 +75,5 @@ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=3.5 -Provides-Extra: argon2 Provides-Extra: bcrypt +Provides-Extra: argon2 diff -Nru python-django-2.2.11/tests/gis_tests/geoapp/tests.py python-django-2.2.12/tests/gis_tests/geoapp/tests.py --- python-django-2.2.11/tests/gis_tests/geoapp/tests.py 2020-03-04 08:34:09.000000000 +0000 +++ python-django-2.2.12/tests/gis_tests/geoapp/tests.py 2020-04-01 07:18:02.000000000 +0000 @@ -581,10 +581,11 @@ srid=4326, ) self.assertIs( - forney_houston.equals( + forney_houston.equals_exact( City.objects.filter(point__within=tx).aggregate( Union('point', tolerance=32000), )['point__union'], + tolerance=10e-6, ), True, ) Binary files /tmp/tmpj76Tsj/pBOg9LX4XI/python-django-2.2.11/tests/i18n/other/locale/fr/LC_MESSAGES/django.mo and /tmp/tmpj76Tsj/5kaPyaDnyO/python-django-2.2.12/tests/i18n/other/locale/fr/LC_MESSAGES/django.mo differ diff -Nru python-django-2.2.11/tests/i18n/other/locale/fr/LC_MESSAGES/django.po python-django-2.2.12/tests/i18n/other/locale/fr/LC_MESSAGES/django.po --- python-django-2.2.11/tests/i18n/other/locale/fr/LC_MESSAGES/django.po 2019-04-24 06:51:45.000000000 +0000 +++ python-django-2.2.12/tests/i18n/other/locale/fr/LC_MESSAGES/django.po 2020-03-26 15:37:57.000000000 +0000 @@ -14,7 +14,10 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n==0 ? 1 : 2);\n" + +# Plural form is purposefully different from the normal French plural to test +# multiple plural forms for one language. #: template.html:3 # Note: Intentional: variable name is translated. @@ -24,4 +27,10 @@ #: template.html:3 # Note: Intentional: the variable name is badly formatted (missing 's' at the end) msgid "My other name is %(person)s." -msgstr "Mon autre nom est %(person)." \ No newline at end of file +msgstr "Mon autre nom est %(person)." + +msgid "%d singular" +msgid_plural "%d plural" +msgstr[0] "%d singulier" +msgstr[1] "%d pluriel1" +msgstr[2] "%d pluriel2" diff -Nru python-django-2.2.11/tests/i18n/tests.py python-django-2.2.12/tests/i18n/tests.py --- python-django-2.2.11/tests/i18n/tests.py 2020-03-04 08:33:59.000000000 +0000 +++ python-django-2.2.12/tests/i18n/tests.py 2020-04-01 07:18:02.000000000 +0000 @@ -98,6 +98,22 @@ self.assertEqual(g('%d year', '%d years', 1) % 1, '1 year') self.assertEqual(g('%d year', '%d years', 2) % 2, '2 years') + @override_settings(LOCALE_PATHS=extended_locale_paths) + @translation.override('fr') + def test_multiple_plurals_per_language(self): + """ + Normally, French has 2 plurals. As other/locale/fr/LC_MESSAGES/django.po + has a different plural equation with 3 plurals, this tests if those + plural are honored. + """ + self.assertEqual(ngettext("%d singular", "%d plural", 0) % 0, "0 pluriel1") + self.assertEqual(ngettext("%d singular", "%d plural", 1) % 1, "1 singulier") + self.assertEqual(ngettext("%d singular", "%d plural", 2) % 2, "2 pluriel2") + french = trans_real.catalog() + # Internal _catalog can query subcatalogs (from different po files). + self.assertEqual(french._catalog[('%d singular', 0)], '%d singulier') + self.assertEqual(french._catalog[('%d hour', 0)], '%d heure') + def test_override(self): activate('de') try: