JS Template Literal interpolations with embedded braces are parsed wrong
hundt opened this issue · comments
When inside a JS Template Literal interpolation, e.g. between the braces in `${val}`
, RawContextUpdater considers any "}" character to indicate an end to the interpolation and a return to the Template Literal context:
// if we are in a template, then this puts us back into the template string
// e.g. `foo${bar}`
if (prior.jsTemplateLiteralNestDepth > 0) {
return prior.toBuilder().withState(HtmlContext.JS_TEMPLATE_LITERAL).build();
}
// stay in js, this must be part of some control flow character
return prior;
However, any Javascript expression could appear in these interpolations, including many possible expressions with curly braces in them. For example: `${{a:1}['a']}`
evaluates to "1".
A test case to see this fail is to add assertTransition("JS", "`${{a:1}", "JS jsTemplateLiteralNestDepth=1");
to RawTextContentUpdaterTest.java:
expected: JS jsTemplateLiteralNestDepth=1
but was : JS_TEMPLATE_LITERAL DIV_OP jsTemplateLiteralNestDepth=1
(I'm not sure about the DIV_OP
part but the JS_TEMPLATE_LITERAL
part is definitely wrong.)
I don't know if it is currently possible to trigger a real-life rendering error via this bug. When I tried I found that compiling the template generally failed with a parse error if there were any braces inside an interpolation; I'm not sure if that is by design or if that is an additional bug. But I thought I'd point out the issue since I happened to spot it while browsing the source code.