mirror of
https://github.com/esphome/esphome.git
synced 2025-10-03 18:42:23 +01:00
@@ -1,9 +1,10 @@
|
||||
from ast import literal_eval
|
||||
import logging
|
||||
import math
|
||||
import re
|
||||
|
||||
import jinja2 as jinja
|
||||
from jinja2.nativetypes import NativeEnvironment
|
||||
from jinja2.sandbox import SandboxedEnvironment
|
||||
|
||||
TemplateError = jinja.TemplateError
|
||||
TemplateSyntaxError = jinja.TemplateSyntaxError
|
||||
@@ -70,7 +71,7 @@ class Jinja:
|
||||
"""
|
||||
|
||||
def __init__(self, context_vars):
|
||||
self.env = NativeEnvironment(
|
||||
self.env = SandboxedEnvironment(
|
||||
trim_blocks=True,
|
||||
lstrip_blocks=True,
|
||||
block_start_string="<%",
|
||||
@@ -90,6 +91,15 @@ class Jinja:
|
||||
**SAFE_GLOBAL_FUNCTIONS,
|
||||
}
|
||||
|
||||
def safe_eval(self, expr):
|
||||
try:
|
||||
result = literal_eval(expr)
|
||||
if not isinstance(result, str):
|
||||
return result
|
||||
except (ValueError, SyntaxError, MemoryError, TypeError):
|
||||
pass
|
||||
return expr
|
||||
|
||||
def expand(self, content_str):
|
||||
"""
|
||||
Renders a string that may contain Jinja expressions or statements
|
||||
@@ -106,7 +116,7 @@ class Jinja:
|
||||
override_vars = content_str.upvalues
|
||||
try:
|
||||
template = self.env.from_string(content_str)
|
||||
result = template.render(override_vars)
|
||||
result = self.safe_eval(template.render(override_vars))
|
||||
if isinstance(result, Undefined):
|
||||
# This happens when the expression is simply an undefined variable. Jinja does not
|
||||
# raise an exception, instead we get "Undefined".
|
||||
|
@@ -5,6 +5,9 @@ substitutions:
|
||||
var21: '79'
|
||||
value: 33
|
||||
values: 44
|
||||
position:
|
||||
x: 79
|
||||
y: 82
|
||||
|
||||
esphome:
|
||||
name: test
|
||||
@@ -26,3 +29,7 @@ test_list:
|
||||
- Literal $values ${are not substituted}
|
||||
- ["list $value", "${is not}", "${substituted}"]
|
||||
- {"$dictionary": "$value", "${is not}": "${substituted}"}
|
||||
- |-
|
||||
{{{ "x", "79"}, { "y", "82"}}}
|
||||
- '{{{"AA"}}}'
|
||||
- '"HELLO"'
|
||||
|
@@ -8,6 +8,9 @@ substitutions:
|
||||
var21: "79"
|
||||
value: 33
|
||||
values: 44
|
||||
position:
|
||||
x: 79
|
||||
y: 82
|
||||
|
||||
test_list:
|
||||
- "$var1"
|
||||
@@ -27,3 +30,7 @@ test_list:
|
||||
- !literal Literal $values ${are not substituted}
|
||||
- !literal ["list $value", "${is not}", "${substituted}"]
|
||||
- !literal {"$dictionary": "$value", "${is not}": "${substituted}"}
|
||||
- |- # Test parsing things that look like a python set of sets when rendered:
|
||||
{{{ "x", "${ position.x }"}, { "y", "${ position.y }"}}}
|
||||
- ${ '{{{"AA"}}}' }
|
||||
- ${ '"HELLO"' }
|
||||
|
Reference in New Issue
Block a user