From 692fd7da5e5bfe1533c40f94999ea42f9b986356 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Mon, 22 Feb 2010 14:38:44 +0000 Subject: [PATCH] Fixed #7777 -- Added validation handling for NaN, Inf and -Inf in DecimalFields. Thanks to thebitguru for the patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@12490 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/forms/fields.py | 9 +++++++-- tests/regressiontests/forms/fields.py | 5 ++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/django/forms/fields.py b/django/forms/fields.py index f5f3abf49d..dd5ae1e427 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -283,6 +283,11 @@ class DecimalField(Field): super(DecimalField, self).validate(value) if value in validators.EMPTY_VALUES: return + # Check for NaN, Inf and -Inf values. We can't compare directly for NaN, + # since it is never equal to itself. However, NaN is the only value that + # isn't equal to itself, so we can use this to identify NaN + if value != value or value == Decimal("Inf") or value == Decimal("-Inf"): + raise ValidationError(self.error_messages['invalid']) sign, digittuple, exponent = value.as_tuple() decimals = abs(exponent) # digittuple doesn't include any leading zeros. @@ -467,7 +472,7 @@ class ImageField(FileField): f = super(ImageField, self).to_python(data) if f is None: return None - + # Try to import PIL in either of the two ways it can end up installed. try: from PIL import Image @@ -584,7 +589,7 @@ class ChoiceField(Field): def __init__(self, choices=(), required=True, widget=None, label=None, initial=None, help_text=None, *args, **kwargs): - super(ChoiceField, self).__init__(required=required, widget=widget, label=label, + super(ChoiceField, self).__init__(required=required, widget=widget, label=label, initial=initial, help_text=help_text, *args, **kwargs) self.choices = choices diff --git a/tests/regressiontests/forms/fields.py b/tests/regressiontests/forms/fields.py index d5eccfcee7..0c7493ee67 100644 --- a/tests/regressiontests/forms/fields.py +++ b/tests/regressiontests/forms/fields.py @@ -203,6 +203,9 @@ class FieldsTests(TestCase): self.assertEqual(f.clean('3.14'), Decimal("3.14")) self.assertEqual(f.clean(3.14), Decimal("3.14")) self.assertEqual(f.clean(Decimal('3.14')), Decimal("3.14")) + self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, 'NaN') + self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, 'Inf') + self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, '-Inf') self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, 'a') self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a number.']", f.clean, u'łąść') self.assertEqual(f.clean('1.0 '), Decimal("1.0")) @@ -498,7 +501,7 @@ class FieldsTests(TestCase): # hangs "forever" if catastrophic backtracking in ticket:#11198 not fixed self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://%s' % ("X"*200,)) - # a second test, to make sure the problem is really addressed, even on + # a second test, to make sure the problem is really addressed, even on # domains that don't fail the domain label length check in the regex self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://%s' % ("X"*60,))