Updates the template preparser to exclude namespaced SVG style tags (':svg:style') from the style elements set.
Previously, ':svg:style' elements were incorrectly classified as PreparsedElementType.STYLE, which caused them to be completely stripped from the final template DOM tree during the Render3 template transform and pushed into standard component stylesheets. By limiting the style element parsing to standard 'style' tags, namespaced SVG style tags remain safely in the template AST as normal DOM elements, preserving local SVG styling.
Closes#68977
Removes the legacy profile property/attribute from the directives hostBindings specs to align with modern DOM security schema changes. Also cleans up minor redundant formatting lines in the compiler and core targets.
Custom XML/XHTML namespaced elements (e.g., <xhtml:a>) fall back to the standard HTML namespace during element creation at compile-time/runtime. However, their property and security context lookups inside the schema registry were incorrectly performed using the full namespaced tag name (e.g., :xhtml:a), which bypassed the default a|href sanitization registry and incorrectly returned SecurityContext.NONE instead of SecurityContext.URL.
This commit introduces tag name normalization inside DomElementSchemaRegistry for custom namespaces (other than the built-in svg and math namespaces). Custom namespaced tag names are now normalized to their simple HTML element counterparts for all registry queries, ensuring that correct property schema validation and dynamic security sanitization rules (such as URL sanitization) are enforced at runtime.
Dynamic bindings to `href` and `xlink:href` attributes on SVG `<a>` elements (`<svg:a>`) were previously unmapped in the DOM security schema. As a result, they bypassed sanitization completely, creating a potential XSS vulnerability if bound to untrusted user inputs (e.g., `javascript:` URLs).
This fix mitigates this risk by:
1. Registering `href` and `xlink:href` on `<svg:a>` elements under the `SecurityContext.URL` context in both the compiler and core DOM security schemas.
2. Enabling template compilation to output runtime URL sanitization checks (`ɵɵsanitizeUrl`) on these attributes.
3. Adding regression and verification test cases to ensure dynamic SVG link bindings are safely sanitized at runtime while static values are correctly allowed.
Ensures that namespaced <script> elements (such as :svg:script) are correctly classified as PreparsedElementType.SCRIPT by the template preparser and stripped during compilation to prevent potential XSS vulnerabilities. Consequently, obsolete security schema mappings and runtime sanitization checks for <script> attributes have been removed since these elements are never present in compiled template outputs.
Updates `DomElementSchemaRegistry` to strip `:svg:` and `:math:` namespace prefixes
from tag names before querying `SECURITY_SCHEMA` at compile-time. This allows SVG
and MathML attributes to correctly match their security contexts during compilation.
Refactors the element security schema lookups and runtime attribute validation to
consistently account for SVG and MathML namespaces. This improves the modularity
and accuracy of security context mapping during template compilation and runtime
constant evaluation, eliminating redundant or false-positive lifecycle checks.
This commit updates the DOM security schema and sanitization logic to properly recognize and sanitize `href` and `xlink:href` attributes on SVG `<script>` elements.
This commit implements a security fix to prevent XSS vulnerabilities where SVG animation elements (`<animate>`, `<set>`, etc.) could be used to modify the `href` or `xlink:href` attributes of other elements to `javascript:` URLs.
The fix introduces a runtime validation step:
- A new [ɵɵValidateAttribute](cci:1://file:///usr/local/google/home/alanagius/git/angular/packages/core/src/sanitization/sanitization.ts:276:0-288:1) instruction is used when `attributeName` is bound on SVG animation elements.
- If executed, a `RuntimeError` is thrown, preventing the binding.
- The compiler now identifies `attributeName` on SVG animation elements as security-sensitive and injects this validation.
Additionally, the DOM security schema has been updated to include a comprehensive list of MathML and SVG elements that accept `href` or `xlink:href` attributes, ensuring they are correctly treated as `SecurityContext.URL` and sanitized. This prevents malicious URLs from being bound to these attributes.
http://b/463880509
Avoids duplication of the `FactoryTarget` enums. This is necessary
now because we are exposing the previously deeply-imported JIT facade
now via the exports; and the typing integration tests surface a type
conflict due to the different duplicated enums.
PR Close#61571
These helpers are often imported by various tests throughout the
repository, but the helpers aren't exported/exposed from the public
entry-point; even though they confusingly reside in there.
This commit fixes this, and moves the helpers into
`packages/private/testing`. This is a preparation for the `ts_project`
migration where we don't want to leverage deep imports between packages.
PR Close#61571
Currently we construct the HMR replacement URL inline by calling into the native `URL` constructor. This can cause conflicts with user code that defines a symbol called `URL`.
These changes resolve the issue by moving the URL construction into a separate function. This has a secondary benefit of making the generated code easier to follow and allowing us to update the URL without changing the compiled code.
Fixes#61517.
PR Close#61550
As part of the Bazel toolchain migration we noticed that implicit types
generated by the TypeScript compiler sometimes end up referencing types
from other packages (i.e. cross-package imports).
These imports currently work just because the Bazel `ts_library` and
`ng_module` rules automatically inserted a `<amd-module
name="@angular/x" />` into `.d.ts` of packages. This helped TS figure
out how to import a given file. Notably this is custom logic that is not
occuring in vanilla TS or Angular compilations—so we will drop this
magic as part of the toolchain cleanup!
To improve code quality and keep the existing behavior working, we are
doing the following:
- adding a lint rule that reduces the risk of such imports breaking. The
failure scenario without the rule is that API goldens show unexpected
diffs, and types might be duplicated in a different package!
- keeping the `<amd-module` headers, but we manually insert them into
the package entry-points. This should ensure we don't regress
anywhere; while we also improved general safety around this above.
Long-term, isolated declarations or a lint rule from eslint-typescript
can make this even more robust.
PR Close#61316
We don't need this tooling anymore because we are already validating
that there are no circular dependencies via the `ng-dev` tooling that
checks `.ts` files directly.
Also these tests never actually failed to my knowledge.
PR Close#61209
The `TemplateLiteralElementExpr` has some logic where it tries to estimate the `rawText` if one isn't provided by looking at the node's source span. The problem with this approach is that we have some long-standing issues with our expression AST parser (see https://github.com/angular/angular/pull/60267#discussion_r1986402524) where it might not produce accurate spans if escape sequences are involved. This in turn can lead to unrecoverable errors, because TypeScript will throw an error if the raw string doesn't match the cooked one when constructing a TypeScript AST node.
These changes remove the logic that depends on the source span and relies purely on the secondary fallback that inserts escaped characters manually.
It's also worth noting that the `rawText` doesn't seem to matter much at this point, because the main usage of it is when downlevelling template literals to ES5 which we no longer support.
Fixes#60528.
PR Close#60529
PR Close#60753
Note that this is not a public-facing change because the compiler is not
supposed to be used directly. See `public-api-surface.md`
We are changing this because in the current state, for advanced setups
like our Bazel infrastructure in Material, this peer dependency can
result in a cycle. That is because we may decide to link the
`@angular/core` package using the compiler-cli/compiler; while
transitively the compiler has a dependency on core. That's a cycle
(surfacing in Bazel w/ `rules_js`).
Dropping this optional peer dependency is acceptable because `core`,
since recently, also has an optional peer dependency on the compiler.
This one makes more sense and is also more user-facing (people generally
never install the compiler directly).
Notably the compiler does not have any runtime dependency on `core` and
this was purely added for some safety checking. See:
https://github.com/angular/angular/commit/8c171da29f499648273e61cfb5bffaa4278097e5
PR Close#60437
Fixes that we were producing zero-length spans for template literals and template literal elements.
Fixes#60320.
Fixes#60319.
PR Close#60323
PR Close#60331
Currently `R3TargetBinder.bind` gets a set of data back from `DirectiveBinder.apply` and `TemplateBinder.applyWithScope`. This will be annoying if we have multiple sources of data, because we'd have to do merge them at the end.
These changes switch to constructing the various data structures ahead of time and passing them into the binders to populate them instead.
I also extracted some of the less trivial types into type aliases so we don't have to repeat them.
PR Close#60191
Historically we've had to be VERY cautious about the way we import
things between entry-points. That is because the `ng_package` rule
bundling is subject to silently introducing code duplication, breaking
singletons etc. We've had this surface a couple of times already, and
dev-infra tried to help detect such cases by adding safety analysis into
`ng_package`.
Long-term we want to get to an approach where it's easy to simply share
code between chunks. Precisely, with the upcoming `rules_js` migration,
this will be necessary as we will have different import "guidelines"
that would currently, before this commit, result in code duplication, or
trigger our "safety check/lint".
This commit prepares `ng_package` to support relative imports between
entry-points, so that we only need the safety check for cross-package
imports/exports. The result is that `ng_package`/APF is now smartly able
to generate shared chunks for things that are needed between multiple
entry-points. Yay!
Note that those shared chunks still remain private, and are guarded by
our `package.json` "exports"; so no new public API surface is
exposed.
PR Close#60241
Currently when we generate the tracking expression for a `@for` block, we process its expression in the context of the creation block. This is incorrect, because the expression may require ops of its own for cases like nullish coalescing or safe reads. The result is that while we do generate the correct variable, they're added to the creation block rather than the tracking function which causes an error at runtime.
These changes address the issue by keeping track of a separate set of ops for the `track` expression that are prepended to the generated function, similarly to how we handle event listeners.
Fixes#56256.
PR Close#58520
Adjusts the code we generate for HMR so that it passes in the HMR ID and `import.meta` to the `replaceMetadata` call. This is necessary so we can do better logging of errors.
PR Close#59854
When we generate an HMR replacement function, we determine which locals from the file are used and we pass them by reference. This works fine in most cases, but breaks down for const enums which don't have a runtime representation.
These changes work around the issue by passing in all the values as an object literal.
Fixes#59800.
PR Close#59815
Makes the following cleanups in the output AST:
* The `TemplateLiteral` and `TemplateLiteralElement` nodes have been renamed to `TemplateLiteralExpr` and `TemplateLiteralElementExpr` respectively for consistency and to avoid overlaps with the expression AST nodes.
* The `TemplateLiteralExpr` and `TemplateLiteralElementExpr` have been refactored to be `Expression`s for correctness. This involves updating some existing code.
* The `TaggedTemplateExpr` has been renamed to `TaggedTemplateLiteralExpr` for consistency.
PR Close#59230
Reworks the lexer's scanner to produce more than one token at a time. This can be useful for the cases where one token means the end of another one.
Also cleans up the scanner by making all non-essential methods private and using strict equality everywhere.
PR Close#59230
Both `:host` and `:host-context` work by looking for a specific character sequence that is terminated by `,` or `{` and replacing selectors inside of it with scoped versions. This is implemented as a regex which isn't aware of things like nested selectors. Normally this is fine for `:host`, because each `:host` produces one scoped selector which doesn't affect any child selectors, however it breaks down with `:host-context` which replaces each instance with two selectors. For example, if we have a selector in the form of `:host-context(.foo) a:not(.a, .b)`, the compiler ends up determining that `.a,` is the end selector and produces `.foo[a-host] a[contenta]:not(.a, .foo [a-host] a[contenta]:not(.a, .b) {}`.
These changes resolve the issue by splitting the CSS alogn top-level commas, processing the `:host-context` in them individually, and stiching the CSS back together.
PR Close#59276
The URL that is dynamically imported to fetch a potential component update
for HMR is now based on the value of `import.meta.url`. This ensures that
the request is sent to the same location that was used to retrieve the
application code. For some development server setups the HTML base HREF
may not be the location of the Angular development server. By using the
application code location which was generated by the development server,
HMR requests can continue to work as expected in these scenarios. In
most common cases, this change will not have any effect as the HTML base
HREF aligns with the location of the application code files.
PR Close#59459
Some time ago we narrowed down the expressions we support in two-way bindings, because in most cases any apart from property reads doesn't make sense. This ended up preventing users from using `$any` in the binding since it's considered a function call.
These changes update the validation logic to allow `$any`.
Fixes#51165.
PR Close#59362
'parameter' was spelled as 'paramater'.
Fix spelling error in Update r3_control_flow.ts
'parameter' was spelled as 'paramater'.
Fix spelling error in r3_template_transform_spec.ts
'parameter' was spelled as 'paramater'.
PR Close#59289