Skip to content

Commit 5cf42cb

Browse files
committed
Merge branch 'develop'
2 parents 38f19e1 + 74e5c05 commit 5cf42cb

7 files changed

Lines changed: 1269 additions & 951 deletions

File tree

cookbook/helper/template_helper.py

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,19 @@ def _plural_name_tag(singular, plural_name, amount, no_amount):
4646
"""
4747
if plural_name in (None, ""):
4848
return html.escape(singular)
49+
50+
try:
51+
amount_val = float(amount)
52+
except (ValueError, TypeError):
53+
amount_val = 0.0
54+
4955
return (
5056
f"<plural-name"
5157
f' singular="{html.escape(singular)}"'
5258
f' plural="{html.escape(plural_name)}"'
53-
f" v-bind:amount='{float(amount)}'"
59+
f" v-bind:amount='{amount_val}'"
5460
f" v-bind:factor='ingredient_factor'"
55-
f" :no-amount='{str(no_amount).lower()}'"
61+
f" :no-amount='{'true' if no_amount else 'false'}'"
5662
f"></plural-name>"
5763
)
5864

@@ -68,8 +74,12 @@ def __init__(self, ingredient):
6874
if ingredient.no_amount:
6975
self.amount = ""
7076
else:
71-
self.amount = f"<scalable-number v-bind:number='{bleach.clean(str(ingredient.amount))}' v-bind:factor='ingredient_factor'></scalable-number>"
72-
self.numeric_amount = float(ingredient.amount)
77+
try:
78+
amount_val = float(ingredient.amount)
79+
except (ValueError, TypeError):
80+
amount_val = 0.0
81+
self.amount = f"<scalable-number v-bind:number='{amount_val}' v-bind:factor='ingredient_factor'></scalable-number>"
82+
self.numeric_amount = amount_val
7383
self.unit = bleach.clean(_resolve_unit_name(ingredient))
7484
if ingredient.food:
7585
if ingredient.food.plural_name in (None, ""):
@@ -95,7 +105,7 @@ def __str__(self):
95105
def render_instructions(step): # TODO deduplicate markdown cleanup code
96106
instructions = step.instruction
97107

98-
tags = {
108+
allowed_tags = [
99109
"h1", "h2", "h3", "h4", "h5", "h6",
100110
"b", "i", "strong", "em", "tt",
101111
"p", "br",
@@ -105,33 +115,43 @@ def render_instructions(step): # TODO deduplicate markdown cleanup code
105115
"a",
106116
"sub", "sup",
107117
'pre', 'table', 'td', 'tr', 'th', 'tbody', 'thead',
108-
'scalable-number',
118+
]
119+
120+
allowed_attributes = {
121+
"*": ["id", "class", 'width', 'height'],
122+
"img": ["src", "alt", "title"],
123+
"a": ["href", "alt", "title"],
109124
}
110-
parsed_md = md.markdown(
125+
126+
# do a first, strict round of cleaning
127+
instructions = bleach.clean(instructions, allowed_tags, allowed_attributes)
128+
129+
# parse markdown
130+
instructions = md.markdown(
111131
instructions,
112132
extensions=[
113133
'markdown.extensions.fenced_code', 'markdown.extensions.sane_lists', 'markdown.extensions.nl2br', TableExtension(),
114134
UrlizeExtension(), MarkdownFormatExtension()
115135
]
116136
)
117-
markdown_attrs = {
118-
"*": ["id", "class", 'width', 'height'],
119-
"img": ["src", "alt", "title"],
120-
"a": ["href", "alt", "title"],
121-
"scalable-number": ["v-bind:number", "v-bind:factor"]
122-
}
123137

138+
# prepare template context
124139
ingredients = []
125140

126141
for i in step.ingredients.all():
127142
ingredients.append(IngredientObject(i))
128143

129144
def scale(number):
130-
return f"<scalable-number v-bind:number='{bleach.clean(str(number))}' v-bind:factor='ingredient_factor'></scalable-number>"
145+
try:
146+
number_val = float(number)
147+
except (ValueError, TypeError):
148+
number_val = 0.0
149+
return f"<scalable-number v-bind:number='{number_val}' v-bind:factor='ingredient_factor'></scalable-number>"
131150

151+
# compile template
132152
try:
133153
env = SandboxedEnvironment()
134-
instructions = env.from_string(parsed_md).render(ingredients=ingredients, scale=scale)
154+
instructions = env.from_string(instructions).render(ingredients=ingredients, scale=scale)
135155
except TemplateSyntaxError:
136156
return _('Could not parse template code.') + ' Error: Template Syntax broken'
137157
except TypeError:
@@ -143,8 +163,42 @@ def scale(number):
143163
except Exception as e:
144164
return _('Could not parse template code.') + f' Error generating template.'
145165

146-
instructions = bleach.clean(instructions, tags, markdown_attrs)
147-
166+
# do second cleaning that allows scalable-number
167+
def validate_scalable_number_attributes(tag, name, value):
168+
if name == 'v-bind:number':
169+
try:
170+
float(value)
171+
return True
172+
except (ValueError, TypeError):
173+
return False
174+
if name == 'v-bind:factor':
175+
return value == 'ingredient_factor'
176+
return False
177+
178+
def validate_plural_name_attributes(tag, name, value):
179+
if name == 'v-bind:amount':
180+
try:
181+
float(value)
182+
return True
183+
except (ValueError, TypeError):
184+
return False
185+
if name == 'v-bind:factor':
186+
return value == 'ingredient_factor'
187+
if name == ':no-amount':
188+
return value == 'true' or value == 'false'
189+
if name in ["singular", "plural", ]:
190+
return True
191+
return False
192+
193+
allowed_attributes["scalable-number"] = validate_scalable_number_attributes
194+
allowed_attributes["plural-name"] = validate_plural_name_attributes
195+
196+
allowed_tags.append('scalable-number')
197+
allowed_tags.append('plural-name')
198+
199+
instructions = bleach.clean(instructions, allowed_tags, allowed_attributes)
200+
201+
# remove any left over { }
148202
instructions = instructions.replace('{','')
149203
instructions = instructions.replace('}','')
150204

0 commit comments

Comments
 (0)