mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 04:52:12 +00:00
tools: Enforce '_html' suffix for unescaped hbs vars.
This adds a check to enforce the new convention of raw HTML variables having a `_html` suffix for better clarity. Discussion: https://chat.zulip.org/#narrow/channel/92-learning/topic/Marking.20commits.20to.20be.20squashed.20in.20PRs Signed-off-by: apoorvapendse <apoorvavpendse@gmail.com>
This commit is contained in:
committed by
Tim Abbott
parent
a935866601
commit
3188d9db31
@@ -81,6 +81,9 @@ def tokenize(text: str, template_format: str | None = None) -> list[Token]:
|
|||||||
def looking_at_handlebars_partial_block() -> bool:
|
def looking_at_handlebars_partial_block() -> bool:
|
||||||
return template_format == "handlebars" and looking_at("{{#>")
|
return template_format == "handlebars" and looking_at("{{#>")
|
||||||
|
|
||||||
|
def looking_at_handlebars_triple_stache() -> bool:
|
||||||
|
return template_format == "handlebars" and (looking_at("{{{") or looking_at("{{~{"))
|
||||||
|
|
||||||
def looking_at_html_start() -> bool:
|
def looking_at_html_start() -> bool:
|
||||||
return looking_at("<") and not looking_at("</")
|
return looking_at("<") and not looking_at("</")
|
||||||
|
|
||||||
@@ -184,6 +187,19 @@ def tokenize(text: str, template_format: str | None = None) -> list[Token]:
|
|||||||
s = get_handlebars_tag(text, state.i)
|
s = get_handlebars_tag(text, state.i)
|
||||||
tag = "else"
|
tag = "else"
|
||||||
kind = "handlebars_else"
|
kind = "handlebars_else"
|
||||||
|
elif looking_at_handlebars_triple_stache():
|
||||||
|
s = get_handlebars_triple_stache_tag(text, state.i)
|
||||||
|
start_offset = end_offset = 3
|
||||||
|
if s.startswith("{{~{"):
|
||||||
|
start_offset += 1
|
||||||
|
if s.endswith("}~}}"):
|
||||||
|
end_offset += 1
|
||||||
|
tag = s[start_offset:-end_offset].strip()
|
||||||
|
if not tag.endswith("_html"):
|
||||||
|
raise TemplateParserError(
|
||||||
|
"Unescaped variables in triple staches {{{ }}} must be suffixed with `_html`"
|
||||||
|
)
|
||||||
|
kind = "handlebars_triple_stache"
|
||||||
elif looking_at_handlebars_start():
|
elif looking_at_handlebars_start():
|
||||||
s = get_handlebars_tag(text, state.i)
|
s = get_handlebars_tag(text, state.i)
|
||||||
tag = s[3:-2].split()[0].strip("#").removeprefix("*")
|
tag = s[3:-2].split()[0].strip("#").removeprefix("*")
|
||||||
@@ -321,6 +337,7 @@ def tag_flavor(token: Token) -> str | None:
|
|||||||
"template_var",
|
"template_var",
|
||||||
"text",
|
"text",
|
||||||
"whitespace",
|
"whitespace",
|
||||||
|
"handlebars_triple_stache",
|
||||||
):
|
):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -632,6 +649,18 @@ def get_handlebars_tag(text: str, i: int) -> str:
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def get_handlebars_triple_stache_tag(text: str, i: int) -> str:
|
||||||
|
end = i + 3
|
||||||
|
while end < len(text) - 3 and text[end] != "}":
|
||||||
|
end += 1
|
||||||
|
if text[end : end + 3] == "}}}":
|
||||||
|
return text[i : end + 3]
|
||||||
|
elif end + 4 <= len(text) and text[end : end + 4] == "}~}}":
|
||||||
|
return text[i : end + 4]
|
||||||
|
else:
|
||||||
|
raise TokenizationError('Tag missing "}}}"', text[i : end + 3])
|
||||||
|
|
||||||
|
|
||||||
def get_spaces(text: str, i: int) -> str:
|
def get_spaces(text: str, i: int) -> str:
|
||||||
s = ""
|
s = ""
|
||||||
while i < len(text) and text[i] in " ":
|
while i < len(text) and text[i] in " ":
|
||||||
|
@@ -179,7 +179,7 @@ BAD_HTML8 = """
|
|||||||
{{#each test}}
|
{{#each test}}
|
||||||
{{#with this}}
|
{{#with this}}
|
||||||
{{#if foobar}}
|
{{#if foobar}}
|
||||||
<div class="anything">{{{test}}}</div>
|
<div class="anything">{{{test_html}}}</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if foobar2}}
|
{{#if foobar2}}
|
||||||
{{> teststuff}}
|
{{> teststuff}}
|
||||||
@@ -192,7 +192,7 @@ GOOD_HTML8 = """
|
|||||||
{{#each test}}
|
{{#each test}}
|
||||||
{{#with this}}
|
{{#with this}}
|
||||||
{{#if foobar}}
|
{{#if foobar}}
|
||||||
<div class="anything">{{{test}}}</div>
|
<div class="anything">{{{test_html}}}</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if foobar2}}
|
{{#if foobar2}}
|
||||||
{{> teststuff}}
|
{{> teststuff}}
|
||||||
|
@@ -147,6 +147,54 @@ class ParserTest(unittest.TestCase):
|
|||||||
template_format="handlebars",
|
template_format="handlebars",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_validate_triple_stache_var_1(self) -> None:
|
||||||
|
my_html = """
|
||||||
|
{{{ foo}}
|
||||||
|
"""
|
||||||
|
self._assert_validate_error(
|
||||||
|
'Tag missing "}}}" at line 2 col 13:"{{{ foo}}\n"',
|
||||||
|
text=my_html,
|
||||||
|
template_format="handlebars",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_validate_triple_stache_var_2(self) -> None:
|
||||||
|
my_html = """
|
||||||
|
{{{ foo}~}
|
||||||
|
"""
|
||||||
|
self._assert_validate_error(
|
||||||
|
'Tag missing "}}}" at line 2 col 13:"{{{ foo}~}"',
|
||||||
|
text=my_html,
|
||||||
|
template_format="handlebars",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_validate_triple_stache_var_3(self) -> None:
|
||||||
|
my_html = """
|
||||||
|
{{{ foo }}}
|
||||||
|
"""
|
||||||
|
self._assert_validate_error(
|
||||||
|
"Unescaped variables in triple staches {{{ }}} must be suffixed with `_html`",
|
||||||
|
text=my_html,
|
||||||
|
template_format="handlebars",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_validate_triple_stache_var_4(self) -> None:
|
||||||
|
my_html = """
|
||||||
|
{{{ foo_html }~}}
|
||||||
|
"""
|
||||||
|
validate(text=my_html, template_format="handlebars")
|
||||||
|
|
||||||
|
def test_validate_triple_stache_var_5(self) -> None:
|
||||||
|
my_html = "{{{ foo_html}}}"
|
||||||
|
validate(text=my_html, template_format="handlebars")
|
||||||
|
|
||||||
|
def test_validate_triple_stache_var_6(self) -> None:
|
||||||
|
my_html = "{{~{ bar_html}}}"
|
||||||
|
validate(text=my_html, template_format="handlebars")
|
||||||
|
|
||||||
|
def test_validate_triple_stache_var_7(self) -> None:
|
||||||
|
my_html = "{{~{ bar_html}~}}"
|
||||||
|
validate(text=my_html, template_format="handlebars")
|
||||||
|
|
||||||
def test_validate_incomplete_django_tag_1(self) -> None:
|
def test_validate_incomplete_django_tag_1(self) -> None:
|
||||||
my_html = """
|
my_html = """
|
||||||
{% foo
|
{% foo
|
||||||
|
Reference in New Issue
Block a user