Disable parsing scientific/complex number notation in template type (#43170)

This commit is contained in:
Paulus Schoutsen 2020-11-13 13:22:29 +01:00 committed by GitHub
parent 7bcd92172a
commit 8dbd54bed1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 2 deletions

View File

@ -49,6 +49,8 @@ _RENDER_INFO = "template.render_info"
_ENVIRONMENT = "template.environment" _ENVIRONMENT = "template.environment"
_RE_JINJA_DELIMITERS = re.compile(r"\{%|\{\{|\{#") _RE_JINJA_DELIMITERS = re.compile(r"\{%|\{\{|\{#")
# Match "simple" ints and floats. -1.0, 1, +5, 5.0
_IS_NUMERIC = re.compile(r"^[+-]?\d*(?:\.\d*)?$")
_RESERVED_NAMES = {"contextfunction", "evalcontextfunction", "environmentfunction"} _RESERVED_NAMES = {"contextfunction", "evalcontextfunction", "environmentfunction"}
@ -373,7 +375,19 @@ class Template:
# render, by not returning right here. The evaluation of strings # render, by not returning right here. The evaluation of strings
# resulting in strings impacts quotes, to avoid unexpected # resulting in strings impacts quotes, to avoid unexpected
# output; use the original render instead of the evaluated one. # output; use the original render instead of the evaluated one.
if not isinstance(result, str): # Complex and scientific values are also unexpected. Filter them out.
if (
# Filter out string and complex numbers
not isinstance(result, (str, complex))
and (
# Pass if not numeric and not a boolean
not isinstance(result, (int, float))
# Or it's a boolean (inherit from int)
or isinstance(result, bool)
# Or if it's a digit
or _IS_NUMERIC.match(render_result) is not None
)
):
return result return result
except (ValueError, TypeError, SyntaxError, MemoryError): except (ValueError, TypeError, SyntaxError, MemoryError):
pass pass

View File

@ -346,7 +346,7 @@ def test_tan(hass):
(0, 0.0), (0, 0.0),
(math.pi, -0.0), (math.pi, -0.0),
(math.pi / 180 * 45, 1.0), (math.pi / 180 * 45, 1.0),
(math.pi / 180 * 90, 1.633123935319537e16), (math.pi / 180 * 90, "1.633123935319537e+16"),
(math.pi / 180 * 135, -1.0), (math.pi / 180 * 135, -1.0),
("'error'", "error"), ("'error'", "error"),
] ]
@ -2416,5 +2416,16 @@ async def test_parse_result(hass):
('{{ "{{}}" }}', "{{}}"), ('{{ "{{}}" }}', "{{}}"),
("not-something", "not-something"), ("not-something", "not-something"),
("2a", "2a"), ("2a", "2a"),
("123E5", "123E5"),
("1j", "1j"),
("1e+100", "1e+100"),
("0xface", "0xface"),
("123", 123),
("123.0", 123.0),
(".5", 0.5),
("-1", -1),
("-1.0", -1.0),
("+1", 1),
("5.", 5.0),
): ):
assert template.Template(tpl, hass).async_render() == result assert template.Template(tpl, hass).async_render() == result