diff options
| author | George Marshall <george@georgemarshall.name> | 2015-11-16 22:28:03 -0800 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-11-24 11:10:23 -0500 |
| commit | 581b9e504752840fd7716e44c5c30292636355a4 (patch) | |
| tree | ad92e447219b54359728709a3fe597b742b798fc | |
| parent | acaf30ad17709c1f9e678cbd7ca65ea6b3e55b90 (diff) | |
[1.8.x] Fixed #25767 -- Fixed data truncation possibility with Positive(Small)IntegerField on MySQL.
Backport of 710e11d076b9e5ef3e3b486dfb70bb55b788691c from master
| -rw-r--r-- | django/db/backends/mysql/operations.py | 4 | ||||
| -rw-r--r-- | docs/releases/1.8.7.txt | 5 | ||||
| -rw-r--r-- | tests/model_fields/tests.py | 32 |
3 files changed, 36 insertions, 5 deletions
diff --git a/django/db/backends/mysql/operations.py b/django/db/backends/mysql/operations.py index bc53f59ec5..ee01a7e4fc 100644 --- a/django/db/backends/mysql/operations.py +++ b/django/db/backends/mysql/operations.py @@ -13,8 +13,8 @@ class DatabaseOperations(BaseDatabaseOperations): # MySQL stores positive fields as UNSIGNED ints. integer_field_ranges = dict(BaseDatabaseOperations.integer_field_ranges, - PositiveSmallIntegerField=(0, 4294967295), - PositiveIntegerField=(0, 18446744073709551615), + PositiveSmallIntegerField=(0, 65535), + PositiveIntegerField=(0, 4294967295), ) def date_extract_sql(self, lookup_type, field_name): diff --git a/docs/releases/1.8.7.txt b/docs/releases/1.8.7.txt index b11ea9781a..25f7712f10 100644 --- a/docs/releases/1.8.7.txt +++ b/docs/releases/1.8.7.txt @@ -46,3 +46,8 @@ Bugfixes * Fixed ``set_FOO_order()`` crash when the ``ForeignKey`` of a model with ``order_with_respect_to`` references a model with a ``OneToOneField`` primary key (:ticket:`25786`). + +* Fixed incorrect validation for ``PositiveIntegerField`` and + ``PositiveSmallIntegerField`` on MySQL resulting in values greater than + 4294967295 or 65535, respectively, passing validation and being silently + truncated by the database (:ticket:`25767`). diff --git a/tests/model_fields/tests.py b/tests/model_fields/tests.py index 9fe905dfc1..2858086324 100644 --- a/tests/model_fields/tests.py +++ b/tests/model_fields/tests.py @@ -506,6 +506,12 @@ class IntegerFieldTests(test.TestCase): model = IntegerModel documented_range = (-2147483648, 2147483647) + @property + def backend_range(self): + field = self.model._meta.get_field('value') + internal_type = field.get_internal_type() + return connection.ops.integer_field_range(internal_type) + def test_documented_range(self): """ Ensure that values within the documented safe range pass validation, @@ -527,14 +533,34 @@ class IntegerFieldTests(test.TestCase): self.assertEqual(qs.count(), 1) self.assertEqual(qs[0].value, max_value) + def test_backend_range_save(self): + """ + Ensure that backend specific range can be saved without corruption. + """ + min_value, max_value = self.backend_range + + if min_value is not None: + instance = self.model(value=min_value) + instance.full_clean() + instance.save() + qs = self.model.objects.filter(value__lte=min_value) + self.assertEqual(qs.count(), 1) + self.assertEqual(qs[0].value, min_value) + + if max_value is not None: + instance = self.model(value=max_value) + instance.full_clean() + instance.save() + qs = self.model.objects.filter(value__gte=max_value) + self.assertEqual(qs.count(), 1) + self.assertEqual(qs[0].value, max_value) + def test_backend_range_validation(self): """ Ensure that backend specific range are enforced at the model validation level. ref #12030. """ - field = self.model._meta.get_field('value') - internal_type = field.get_internal_type() - min_value, max_value = connection.ops.integer_field_range(internal_type) + min_value, max_value = self.backend_range if min_value is not None: instance = self.model(value=min_value - 1) |
