Skip to content

Unmatched </p> or </br> inside foreign context needs a special parser rule #5113

@mfreed7

Description

@mfreed7

As the current parser spec is written, <svg></p></svg> and <svg></br></svg> both result in <p> and <br> DOM nodes as children of the <svg>. As mentioned in this Chromium bug and this blog post, this can be exploited as a sanitizer bypass. Here is an example DOM Viewer link showing the behavior.

By my reading of the spec:

  • In the "in body" insertion mode, for a </p> tag, if the stack of open elements does not have a p element in button scope, then this is a parse error; insert an HTML element for a "p" start tag token with no attributes. Close a p element. (This adds the <p> within <svg>.)
  • When parsing tokens in a foreign context, when "Any other end tag" is encountered, nothing special happens in this case, for a </p> found within an <svg>. Normal processing (the bullet point above) happens in step 7. All of the special "jumping out" behavior is specified for the start tags only, a bit higher up in the foreign context section. For those, the behavior is: Pop an element from the stack of open elements, and then keep popping more elements from the stack of open elements until the current node is a MathML text integration point, an HTML integration point, or an element in the HTML namespace. (This is what causes a <p> found within <svg> to close the </svg> and leave the <p> outside.)

Current implementations:

  • Blink leaves the <p> or <br> inside <svg>.
  • Webkit leaves the <p> or <br> inside <svg>.
  • Gecko (correctly?) moves the <p> or <br> outside the <svg>.

I believe the spec should follow current Gecko behavior. I think the easiest way to change the spec would be to add a special case within the foreign context section for end tags whose tag name is "p" or "br", which closes the foreign context and then processes the </p> or </br> as normal for a non-foreign context.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions