Skip to content

fix(i18n): reject a meaning or description that would close its JSDoc comment, and escape @ in it - #650

Merged
Brooooooklyn merged 3 commits into
voidzero-dev:mainfrom
GabeSilvaDev:fix/i18n-jsdoc-comment
Oct 28, 2026
Merged

Brooooooklyn merged 3 commits into
voidzero-dev:mainfrom
GabeSilvaDev:fix/i18n-jsdoc-comment

Conversation

@GabeSilvaDev

@GabeSilvaDev GabeSilvaDev commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

An i18n meaning or description is written into the JSDoc comment above the Closure goog.getMsg message, as raw text. A */ in it ends the comment early, and whatever follows becomes code in the emitted module:

<img i18n-alt="*/ } steal(); if (0) { /*" alt="Logo" />
// before
if (((typeof ngI18nClosureMode !== "undefined") && ngI18nClosureMode)) {
  /** @desc */ } steal(); if (0) { /* */
  const MSG_C_TS__0 = goog.getMsg("Logo");
  (i18n_0 = MSG_C_TS__0);
} else {
  (i18n_0 = $localize `:*/ } steal(); if (0) { /*:Logo`);
}

The } closes the ngI18nClosureMode branch and if (0) { takes over the rest, so steal() runs every time the consts are built, not only in Closure mode, and the message still works. Other text after */ or /* breaks the output instead.

ngtsc never emits this: tagToString in output_ast.ts throws JSDoc text cannot contain "/*" and "*/" for such a text, and escapes @ as \@ so the text cannot start a JSDoc tag of its own.

This PR does both:

  • An i18n or i18n-* meaning or description with /* or */ is reported as a template error with Angular's message, so the component is not compiled. The check runs where the attribute is parsed (html_to_r3.rs), because errors that pipeline phases push to job.diagnostics don't reach transform_angular_file's diagnostics today.
  • @ in a meaning or description is emitted as \@ (/** @desc mail a\@b.c */).

Test plan

  • test_i18n_meta_that_would_close_its_jsdoc_comment_is_an_error: */ in a description, in an i18n-alt meaning, and /* in a meaning are reported with that error and emit no JSDoc comment.
  • test_i18n_meta_at_sign_is_escaped_in_jsdoc: @ in both texts is escaped.
  • Removing either of the two checks, or the escaping, fails a test.
  • cargo test --all-features, cargo fmt --all -- --check, and cargo run -p oxc_angular_conformance (1264/1264, snapshot unchanged).

Separately: compile_component_full collects job.diagnostics and drops them, so errors such as Unsupported expression in two-way action binding ([(x)]="a + b", which ngtsc rejects) are not reported either. Returning them as compile_template_for_hmr already does also surfaces a false AssertionError: unable to find a dependency function for this deferred block for @defer (on viewport(missing)), which ngtsc accepts, and fails 18 existing defer tests. So that is left out of this PR.

Copilot AI balanced review requested due to automatic review settings October 26, 2026 22:23
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review 🔄 Running since 2026-10-28T03:35:38.725276Z a85febf Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

@GabeSilvaDev
GabeSilvaDev force-pushed the fix/i18n-jsdoc-comment branch from 0c019bf to a88a106 Compare October 27, 2026 22:16
@GabeSilvaDev

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Something went wrong. Try again later by commenting “@codex review”.

An unknown error occurred
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Brooooooklyn and others added 2 commits October 28, 2026 11:34
…s printed

Angular's `tagToString` throws when it prints the JSDoc, so `ngc` compiles a template
whose `*/` meta has no message: an empty or comment-only `i18n` element, `<ng-content i18n>`,
an `i18n-title` that a later one replaces, an `i18n-alt` with no value, and partial
compilation. The check now runs where the message's JSDoc is built and goes out as an
error from full, template, HMR and linker compilation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Brooooooklyn

Copy link
Copy Markdown
Member

@codex review

@Brooooooklyn
Brooooooklyn merged commit d808cb0 into voidzero-dev:main Oct 28, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants