Fixed #28730 -- Fixed loss of precision for large integer literals in templates

Thanks Fraser Nevett for the report and Tim Graham for patch edits.
This commit is contained in:
Claude Paroz 2017-10-21 12:24:20 +02:00
parent 45d5d2dcaa
commit 9ec7d8e514
2 changed files with 15 additions and 11 deletions

View File

@ -762,17 +762,16 @@ class Variable:
# Note that this could cause an OverflowError here that we're not # Note that this could cause an OverflowError here that we're not
# catching. Since this should only happen at compile time, that's # catching. Since this should only happen at compile time, that's
# probably OK. # probably OK.
# Try to interpret values containg a period or an 'e'/'E'
# (possibly scientific notation) as a float; otherwise, try int.
if '.' in var or 'e' in var.lower():
self.literal = float(var) self.literal = float(var)
# So it's a float... is it an int? If the original value contained a
# dot or an "e" then it was a float, not an int.
if '.' not in var and 'e' not in var.lower():
self.literal = int(self.literal)
# "2." is invalid # "2." is invalid
if var.endswith('.'): if var.endswith('.'):
raise ValueError raise ValueError
else:
self.literal = int(var)
except ValueError: except ValueError:
# A ValueError means that the variable isn't a number. # A ValueError means that the variable isn't a number.
if var.startswith('_(') and var.endswith(')'): if var.startswith('_(') and var.endswith(')'):

View File

@ -1,4 +1,4 @@
from django.template.base import VariableDoesNotExist from django.template.base import Variable, VariableDoesNotExist
from django.test import SimpleTestCase from django.test import SimpleTestCase
@ -6,3 +6,8 @@ class VariableDoesNotExistTests(SimpleTestCase):
def test_str(self): def test_str(self):
exc = VariableDoesNotExist(msg='Failed lookup in %r', params=({'foo': 'bar'},)) exc = VariableDoesNotExist(msg='Failed lookup in %r', params=({'foo': 'bar'},))
self.assertEqual(str(exc), "Failed lookup in {'foo': 'bar'}") self.assertEqual(str(exc), "Failed lookup in {'foo': 'bar'}")
class VariableTests(SimpleTestCase):
def test_integer_literals(self):
self.assertEqual(Variable('999999999999999999999999999').literal, 999999999999999999999999999)