mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[4.0.x] Fixed #33033 -- Prevented models.DecimalField from accepting NaN values.
Backport of b7fd668b37 from main
			
			
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							a9479202d7
						
					
				
				
					commit
					6f31041794
				
			| @@ -2,6 +2,7 @@ import collections.abc | |||||||
| import copy | import copy | ||||||
| import datetime | import datetime | ||||||
| import decimal | import decimal | ||||||
|  | import math | ||||||
| import operator | import operator | ||||||
| import uuid | import uuid | ||||||
| import warnings | import warnings | ||||||
| @@ -1539,6 +1540,12 @@ class DecimalField(Field): | |||||||
|         if value is None: |         if value is None: | ||||||
|             return value |             return value | ||||||
|         if isinstance(value, float): |         if isinstance(value, float): | ||||||
|  |             if math.isnan(value): | ||||||
|  |                 raise exceptions.ValidationError( | ||||||
|  |                     self.error_messages['invalid'], | ||||||
|  |                     code='invalid', | ||||||
|  |                     params={'value': value}, | ||||||
|  |                 ) | ||||||
|             return self.context.create_decimal_from_float(value) |             return self.context.create_decimal_from_float(value) | ||||||
|         try: |         try: | ||||||
|             return decimal.Decimal(value) |             return decimal.Decimal(value) | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import math | ||||||
| from decimal import Decimal | from decimal import Decimal | ||||||
|  |  | ||||||
| from django.core import validators | from django.core import validators | ||||||
| @@ -65,6 +66,13 @@ class DecimalFieldTests(TestCase): | |||||||
|         bd = BigD.objects.get(pk=bd.pk) |         bd = BigD.objects.get(pk=bd.pk) | ||||||
|         self.assertEqual(bd.d, Decimal('12.9')) |         self.assertEqual(bd.d, Decimal('12.9')) | ||||||
|  |  | ||||||
|  |     def test_save_nan_invalid(self): | ||||||
|  |         msg = '“nan” value must be a decimal number.' | ||||||
|  |         with self.assertRaisesMessage(ValidationError, msg): | ||||||
|  |             BigD.objects.create(d=float('nan')) | ||||||
|  |         with self.assertRaisesMessage(ValidationError, msg): | ||||||
|  |             BigD.objects.create(d=math.nan) | ||||||
|  |  | ||||||
|     def test_fetch_from_db_without_float_rounding(self): |     def test_fetch_from_db_without_float_rounding(self): | ||||||
|         big_decimal = BigD.objects.create(d=Decimal('.100000000000000000000000000005')) |         big_decimal = BigD.objects.create(d=Decimal('.100000000000000000000000000005')) | ||||||
|         big_decimal.refresh_from_db() |         big_decimal.refresh_from_db() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user