Fixes #198 Co-authored-by: Ben Kurtovic <ben.kurtovic@gmail.com>tags/v0.6
@@ -2628,7 +2628,11 @@ PyObject* Tokenizer_parse(Tokenizer* self, uint64_t context, int push) | |||||
return NULL; | return NULL; | ||||
} | } | ||||
else if (this == '=' && this_context & LC_TEMPLATE_PARAM_KEY) { | else if (this == '=' && this_context & LC_TEMPLATE_PARAM_KEY) { | ||||
if (Tokenizer_handle_template_param_value(self)) | |||||
if (!(self->global & GL_HEADING) && (!last || last == '\n') && next == '=') { | |||||
if (Tokenizer_parse_heading(self)) | |||||
return NULL; | |||||
} | |||||
else if (Tokenizer_handle_template_param_value(self)) | |||||
return NULL; | return NULL; | ||||
} | } | ||||
else if (this == next && next == '}' && this_context & LC_TEMPLATE) | else if (this == next && next == '}' && this_context & LC_TEMPLATE) | ||||
@@ -2668,7 +2672,7 @@ PyObject* Tokenizer_parse(Tokenizer* self, uint64_t context, int push) | |||||
} | } | ||||
else if (this == ']' && this_context & LC_EXT_LINK_TITLE) | else if (this == ']' && this_context & LC_EXT_LINK_TITLE) | ||||
return Tokenizer_pop(self); | return Tokenizer_pop(self); | ||||
else if (this == '=' && !(self->global & GL_HEADING)) { | |||||
else if (this == '=' && !(self->global & GL_HEADING) && !(this_context & LC_TEMPLATE)) { | |||||
if (!last || last == '\n') { | if (!last || last == '\n') { | ||||
if (Tokenizer_parse_heading(self)) | if (Tokenizer_parse_heading(self)) | ||||
return NULL; | return NULL; | ||||
@@ -1326,7 +1326,10 @@ class Tokenizer: | |||||
elif this == "|" and self._context & contexts.TEMPLATE: | elif this == "|" and self._context & contexts.TEMPLATE: | ||||
self._handle_template_param() | self._handle_template_param() | ||||
elif this == "=" and self._context & contexts.TEMPLATE_PARAM_KEY: | elif this == "=" and self._context & contexts.TEMPLATE_PARAM_KEY: | ||||
self._handle_template_param_value() | |||||
if not self._global & contexts.GL_HEADING and self._read(-1) in ("\n", self.START) and nxt == "=": | |||||
self._parse_heading() | |||||
else: | |||||
self._handle_template_param_value() | |||||
elif this == nxt == "}" and self._context & contexts.TEMPLATE: | elif this == nxt == "}" and self._context & contexts.TEMPLATE: | ||||
return self._handle_template_end() | return self._handle_template_end() | ||||
elif this == "|" and self._context & contexts.ARGUMENT_NAME: | elif this == "|" and self._context & contexts.ARGUMENT_NAME: | ||||
@@ -1350,7 +1353,7 @@ class Tokenizer: | |||||
self._parse_external_link(False) | self._parse_external_link(False) | ||||
elif this == "]" and self._context & contexts.EXT_LINK_TITLE: | elif this == "]" and self._context & contexts.EXT_LINK_TITLE: | ||||
return self._pop() | return self._pop() | ||||
elif this == "=" and not self._global & contexts.GL_HEADING: | |||||
elif this == "=" and not self._global & contexts.GL_HEADING and not self._context & contexts.TEMPLATE: | |||||
if self._read(-1) in ("\n", self.START): | if self._read(-1) in ("\n", self.START): | ||||
self._parse_heading() | self._parse_heading() | ||||
else: | else: | ||||
@@ -695,3 +695,31 @@ name: recursion_opens_and_closes | |||||
label: test potentially dangerous recursion: template openings and closings | label: test potentially dangerous recursion: template openings and closings | ||||
input: "{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}" | input: "{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}{{x|{{x}}" | ||||
output: [Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose()] | output: [Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose(), Text(text="{{x|"), TemplateOpen(), Text(text="x"), TemplateClose()] | ||||
--- | |||||
name: invalid_section_level_1 | |||||
label: level 1 headings inside a template are always invalid | |||||
input: "{{foo|bar\n=baz=\n}}" | |||||
output: [TemplateOpen(), Text(text="foo"), TemplateParamSeparator(), Text(text="bar\n"), TemplateParamEquals(), Text(text="baz=\n"), TemplateClose()] | |||||
--- | |||||
name: section_level_2 | |||||
label: valid level 2 heading inside a template | |||||
input: "{{foo|bar\n==baz==\n}}" | |||||
output: [TemplateOpen(), Text(text="foo"), TemplateParamSeparator(), Text(text="bar\n"), HeadingStart(level=2), Text(text="baz"), HeadingEnd(), Text(text="\n"), TemplateClose()] | |||||
--- | |||||
name: invalid_section_level_2 | |||||
label: invalid level 2 heading inside a template | |||||
input: "{{foo|bar==baz==\n}}" | |||||
output: [TemplateOpen(), Text(text="foo"), TemplateParamSeparator(), Text(text="bar"), TemplateParamEquals(), Text(text="=baz==\n"), TemplateClose()] | |||||
--- | |||||
name: section_level_2_after_template_parameter | |||||
label: level 2 heading inside a template after a parameter | |||||
input: "{{foo|bar=\n==baz==\n}}" | |||||
output: [TemplateOpen(), Text(text="foo"), TemplateParamSeparator(), Text(text="bar"), TemplateParamEquals(), Text(text="\n==baz==\n"), TemplateClose()] |