fix(compiler): allow slashes inside unquoted attribute values#68804
Open
mohanrajvenkatesan23-04 wants to merge 1 commit into
Open
Conversation
Per the HTML spec, an unquoted attribute value is terminated by ASCII whitespace, `"`, `'`, `=`, `<`, `>` or EOF. Notably, `/` is _not_ a terminator, so HTML like `<a href=https://example.com>` and `<img src=path/to/foo.png>` is well-formed but Angular's lexer rejected it because it reused the attribute-name terminator predicate (which treats `/` as a name terminator to support `<br/>`). Introduce a dedicated `isUnquotedAttrValueEnd` predicate that omits `/`, and use it in the unquoted attribute-value branch of `_consumeAttribute`. The attribute-name predicate is unchanged, so self-closing tags such as `<br/>` and `<my-comp/>` continue to lex as before. This brings Angular's attribute-value tokenisation in line with the HTML spec. As a small behaviour change, an unquoted attribute value followed by `/>` such as `<input type=text/>` now lexes as attribute `type="text/"` on a non-self-closing tag (matching the HTML spec). Use quoted attribute values or a leading space (`<input type="text" />`) to express the original intent. Closes angular#36932
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Angular's HTML lexer rejects unquoted attribute values that contain a
/,even though the HTML spec allows them. For example:
both fail with an "unexpected character" / "tag opening" parse error,
because the lexer reuses the attribute-name terminator predicate
(
isNameEnd) for the unquoted attribute-value state, and that predicatetreats
/as a terminator so that<br/>is correctly tokenised.Issue Number: #36932
What is the new behavior?
A new predicate
isUnquotedAttrValueEndis introduced — identical toisNameEndminus$SLASH— and is used only in the unquotedattribute-value branch of
_consumeAttribute. The attribute-name statestill uses the original
isNameEnd, so self-closing tags like<br/>,<my-comp/>, and<input checked/>continue to lex as self-closing.Spec-compliant cases now lex correctly:
Behaviour change to call out
Because
/is no longer a terminator in the unquoted attribute-valuestate, an unquoted value immediately followed by
/>is now consumedinto the value (matching the HTML spec):
<input type=text/>type="text"+ self-closing tagtype="text/"+ non-self-closing tagAuthors who relied on the old behaviour should switch to a quoted value
or insert a space:
Self-closing forms that don't have an immediately-preceding unquoted
attribute value are not affected (
<br/>,<my-comp/>,<my-comp prop="x"/>,<my-comp prop='x'/>).Does this PR introduce a breaking change?
<tag attr=value/>(unquoted value followed by/>) now parses the/as part of the value, where it previously closed the tag. The fix is
mandated by the HTML spec and
unblocks the bug reported in #36932. Users can migrate by quoting the
value or inserting a space before
/>.Other information
Tests:
packages/compiler/test/ml_parser/lexer_spec.ts:URL value, path value,
<br/>regression-of-regression, and thespec-conformant
<input type=text/>→type="text/"case.packages/compiler/test/ml_parser/html_parser_spec.tsverifying both the URL and path examples round-trip through the full
HTML parser.