Skip to content

Fixed a crash on JSX emit trying to emit unexpectedly recovered BinaryExpression in a JSX attribute - #64470

Open
Mateusz Burzyński (Andarist) wants to merge 2 commits into
microsoft:mainfrom
Andarist:fix/jsx-attribute-value-no-sibling-recovery
Open

Mateusz Burzyński (Andarist) wants to merge 2 commits into
microsoft:mainfrom
Andarist:fix/jsx-attribute-value-no-sibling-recovery

Conversation

@Andarist

Copy link
Copy Markdown
Contributor

fixes a crash reported here #64458 (comment)

…xpressions

parseJsxAttributeValue called parseJsxElementOrSelfClosingElementOrFragment with
mustBeUnary=false, so the "JSX expressions must have one parent element" recovery
could return a comma BinaryExpression as a JsxAttribute initializer, violating the
JsxAttributeValue contract and crashing the react/react-jsx transforms.

Fixes microsoft#64458
Copilot AI balanced review requested due to automatic review settings September 26, 2026 17:32
@typescript-automation typescript-automation Bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Sep 26, 2026
@typescript-automation

Copy link
Copy Markdown

This PR doesn't have any linked issues. Please open an issue that references this PR. From there we can discuss and prioritise.

return p.parseJsxElementOrSelfClosingElementOrFragment(true /*inExpressionContext*/, -1, nil, false)
// An attribute value must be a single JsxAttributeValue, so don't allow the sibling-element
// recovery to wrap it in a synthetic binary expression.
return p.parseJsxElementOrSelfClosingElementOrFragment(true /*inExpressionContext*/, -1 /*topInvalidNodePosition*/, nil /*openingTag*/, true /*mustBeUnary*/)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's best to handle this here - where the bad data was created. All of the other code just doesn't expect BinaryExpression here given:

type JsxAttributeValue = StringLiteral | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The targeted parser correction preserves AST invariants and includes relevant regression baselines.

Review effort: Balanced
Findings: None

What changed in this PR

Prevents JSX emit crashes by disallowing synthetic binary-expression recovery within JSX attribute values.

Changes:

  • Enforces the JsxAttributeValue AST invariant during parser recovery.
  • Adds regression coverage for classic and automatic JSX emit.
  • Updates affected diagnostic and emit baselines.
File Description
tsc/​internal/​parser/​parser.go Restricts sibling-element recovery in attribute values.
tsc/​testdata/​tests/​cases/​compiler/​jsxAttributeInitializerMultipleElementsNoCrash.tsx Adds the crash regression case.
tsc/​testdata/​baselines/​reference/​compiler/​jsxAttributeValueBinaryExpression.js Updates existing emit expectations.
tsc/​testdata/​baselines/​reference/​compiler/​jsxAttributeValueBinaryExpression.errors.txt Updates existing diagnostics.
tsc/​testdata/​baselines/​reference/​compiler/​jsxAttributeInitializerMultipleElementsNoCrash(jsx=react).js Records classic JSX emit.
tsc/​testdata/​baselines/​reference/​compiler/​jsxAttributeInitializerMultipleElementsNoCrash(jsx=react).errors.txt Records classic JSX diagnostics.
tsc/​testdata/​baselines/​reference/​compiler/​jsxAttributeInitializerMultipleElementsNoCrash(jsx=react-jsx).js Records automatic JSX emit.
tsc/​testdata/​baselines/​reference/​compiler/​jsxAttributeInitializerMultipleElementsNoCrash(jsx=react-jsx).errors.txt Records automatic JSX diagnostics.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

For Uncommitted Bug PR for untriaged, rejected, closed or missing bug

Projects

Status: Not started

Development

Successfully merging this pull request may close these issues.

2 participants