fix(security): close SVG/i18n security-context gaps vs @angular/compiler v21.2.7#334
fix(security): close SVG/i18n security-context gaps vs @angular/compiler v21.2.7#334Brooooooklyn wants to merge 3 commits into
Conversation
Regenerate the conformance fixtures and angular.snap.md against the vendored Angular v21.2.7 submodule so `cargo run -p oxc_angular_conformance` is idempotent (git diff --exit-code clean). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ler v21.2.7 (#315) Bump the vendored @angular/compiler submodule to v21.2.7 and port the security-context fixes from issue #315, keeping oxc_angular_compiler a faithful 1:1 reimplementation of the pinned upstream. Issue #315 sub-gaps: - Host bindings now compute the security context (multi-selector union/merge plus case-sensitive :not(element) exclusions over allKnownElementNames). - AOT i18n: trusted-types sink attributes (e.g. iframe|src) are rejected for translation; the guard uses the resolved element tag. - Template preparser strips :svg:script (in addition to script), matching v21.2.7 SCRIPT_ELEMENTS. Faithfulness fixes surfaced during 22 adversarial-review iterations: - Namespaced security lookup: :svg:/:math: elements resolve by local name; the host-unknown scan skips the full phantom set of SECURITY_SCHEMA element segments that exist only namespaced (:svg:animate, :math:*) or are absent from the element schema, so it matches upstream allKnownElementNames reachability (no over-validation, no under-sanitization). - SVG/MathML namespace inheritance for implicit and selectorless children; namespaced raw-text and namespaced void-local close-tag handling. - Explicit parser is_component marker (uppercase element vs bare component) threaded through security, i18n, and AST construction. - Namespaced attribute codegen (mergeNsAndName) for template attr bindings; host bindings left unsplit, matching upstream. - ShadowCss: closed-comment-only handling, ECMAScript \s semantics, unanchored sourceURL detection, single-pass comment restore, and a scoping-leak fix. Validation: cargo fmt/check clean; full Rust test suite passes (0 failed, 1 pre-existing ignored); conformance 1259/1259 (100%, idempotent). The final adversarial review returned an approved verdict with no material findings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a2806b8621
ℹ️ 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".
| if lower_name == "script" { | ||
| return None; |
There was a problem hiding this comment.
Do not strip selectorless components named Script
In selectorless mode, a bare component like <Script></Script> is parsed with element.is_component == true, but this check runs before the component path and uses the component class name case-insensitively. That makes the transform drop the entire component as if it were a real <script> element; similarly Style/Link get routed through the special-element handling. The special HTML-element filtering should be skipped for selectorless components (or applied to the resolved host tag), otherwise valid selectorless components whose class name collides with these tag names disappear from the R3 AST.
Useful? React with 👍 / 👎.
Signed-off-by: Brandon Roberts <robertsbt@gmail.com>
Summary
Closes #315.
Bumps the vendored
@angular/compilersubmodule to v21.2.7 and ports the security-context fixes from issue #315, keepingoxc_angular_compilera faithful 1:1 reimplementation of the pinned upstream.Issue #315 sub-gaps
:not(element)exclusions overallKnownElementNames).iframe|src) for translation; the guard uses the resolved element tag.:svg:script(in addition toscript), matching v21.2.7SCRIPT_ELEMENTS.Faithfulness fixes surfaced during review
:svg:/:math:elements resolve by local name; the host-unknown scan skips the full phantom set ofSECURITY_SCHEMAelement segments that exist only namespaced (:svg:animate,:math:*) or are absent from the element schema, so it matches upstreamallKnownElementNamesreachability — no over-validation, no under-sanitization (verified: phantom set == {sec segments} − {bare known} exactly).is_componentmarker (uppercase element vs bare component) threaded through security, i18n, and AST construction.mergeNsAndName) for template attr bindings; host bindings left unsplit, matching upstream.\ssemantics, unanchored sourceURL detection, single-pass restore, and a scoping-leak fix.Validation
cargo fmt --all -- --check: clean ·cargo check: 0 errorscargo test -p oxc_angular_compiler: all binaries pass (0 failed, 1 pre-existing ignored)cargo run -p oxc_angular_conformance: 1259/1259 (100%), idempotent🤖 Generated with Claude Code
Note
Low Risk
Changes are generated JSON test fixtures only; no runtime compiler logic in this diff.
Overview
Regenerates
crates/angular_conformance/fixtures/*.jsonso the Rust conformance runner tracks the vendored@angular/compilertests at v21.2.7. Fixture metadata now points at theoxc-angular-compilercheckout path instead of the old monorepo layout.Most edits are serializer churn (multi-line
expectedarrays, trailing newlines). Meaningful catalog updates include new HTML parser coverage for named entities with digits (¹,½),@default neverswitch blocks, and clearer expansion-form / incomplete-block test names. The i18n extractor fixture disambiguates a duplicate ICU case name (…messages 2).The diff drops the binding error case for
(a b) => a + b(“missing comma between arrow function parameters”) and removes duplicate attribute-parser entries (unquoted interpolation / newline-bound inputs) that no longer appear in the extracted upstream spec.Reviewed by Cursor Bugbot for commit a2806b8. Bugbot is set up for automated code reviews on this repo. Configure here.