mirror of
https://github.com/django/django.git
synced 2025-08-04 02:48:35 +00:00
Fixed #27397 -- Prevented integer overflows on integer field lookups.
This prevents a sqlite3 crash and address a potential DDoS vector on PostgreSQL caused by full-table-scans on overflows.
This commit is contained in:
parent
cc67344db9
commit
dde2537fbb
2 changed files with 78 additions and 4 deletions
|
@ -1,3 +1,5 @@
|
|||
from unittest import SkipTest
|
||||
|
||||
from django.core import validators
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import IntegrityError, connection, models
|
||||
|
@ -94,6 +96,43 @@ class IntegerFieldTests(TestCase):
|
|||
instance.value = max_value
|
||||
instance.full_clean()
|
||||
|
||||
def test_backend_range_min_value_lookups(self):
|
||||
min_value = self.backend_range[0]
|
||||
if min_value is None:
|
||||
raise SkipTest("Backend doesn't define an integer min value.")
|
||||
underflow_value = min_value - 1
|
||||
self.model.objects.create(value=min_value)
|
||||
# A refresh of obj is necessary because last_insert_id() is bugged
|
||||
# on MySQL and returns invalid values.
|
||||
obj = self.model.objects.get(value=min_value)
|
||||
with self.assertNumQueries(0), self.assertRaises(self.model.DoesNotExist):
|
||||
self.model.objects.get(value=underflow_value)
|
||||
with self.assertNumQueries(1):
|
||||
self.assertEqual(self.model.objects.get(value__gt=underflow_value), obj)
|
||||
with self.assertNumQueries(1):
|
||||
self.assertEqual(self.model.objects.get(value__gte=underflow_value), obj)
|
||||
with self.assertNumQueries(0), self.assertRaises(self.model.DoesNotExist):
|
||||
self.model.objects.get(value__lt=underflow_value)
|
||||
with self.assertNumQueries(0), self.assertRaises(self.model.DoesNotExist):
|
||||
self.model.objects.get(value__lte=underflow_value)
|
||||
|
||||
def test_backend_range_max_value_lookups(self):
|
||||
max_value = self.backend_range[-1]
|
||||
if max_value is None:
|
||||
raise SkipTest("Backend doesn't define an integer max value.")
|
||||
overflow_value = max_value + 1
|
||||
obj = self.model.objects.create(value=max_value)
|
||||
with self.assertNumQueries(0), self.assertRaises(self.model.DoesNotExist):
|
||||
self.model.objects.get(value=overflow_value)
|
||||
with self.assertNumQueries(0), self.assertRaises(self.model.DoesNotExist):
|
||||
self.model.objects.get(value__gt=overflow_value)
|
||||
with self.assertNumQueries(0), self.assertRaises(self.model.DoesNotExist):
|
||||
self.model.objects.get(value__gte=overflow_value)
|
||||
with self.assertNumQueries(1):
|
||||
self.assertEqual(self.model.objects.get(value__lt=overflow_value), obj)
|
||||
with self.assertNumQueries(1):
|
||||
self.assertEqual(self.model.objects.get(value__lte=overflow_value), obj)
|
||||
|
||||
def test_redundant_backend_range_validators(self):
|
||||
"""
|
||||
If there are stricter validators than the ones from the database
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue