15383 Commits

Author SHA1 Message Date
Cameron Smick 152601ed94 refactor(core): add childSignalProp to ReactiveNodeKind
Add `childSignalProp` to `ReactiveNodeKind` in order to consolidate `ReactiveNodeKind` types and enable Client-Only Wiz to use it.

(cherry picked from commit ae6d8dae75)
2026-06-17 20:03:17 +00:00
arturovt 59dea13f80 fix(core): guard against DOM clobbering in declareExperimentalWebMcpTool
Previously, the modelContext truthiness check could be bypassed via DOM
clobbering (e.g. `<form id="modelContext">`), causing a truthy HTMLElement
to pass the guard and then throw when `registerTool` was called on it.

Replace the truthiness check with a duck-type check that asserts
`registerTool` is a function, rejecting both absent and clobbered values.

(cherry picked from commit 8cf7731468)
2026-06-17 20:02:14 +00:00
Andrew Scott 81cb4570b2 refactor(router): Add handling for ActivatedRoute-scoped injector
Add handling in navigation for creating and destroying injectors scoped
to `ActivatedRoute` life.
The code for creating the injectors is certainly more complicated
than it _could_ be since there's no actual feature built around this yet.

Keeps as much implementation code tree-shakeable as possible:
Raw size: +764 bytes
Gzipped size: +182 bytes

(cherry picked from commit 1e79dd3140)
2026-06-17 18:39:17 +00:00
Joost Koehoorn f902d1d35e perf(core): detect existing signal dependency without checking all producer links
This commit addresses a scaling issue in the signal dependency graph where
the detection of duplicate dependency links would perform a linear scan across
all consumer links of all producers. The linear scan is replaced with a version
comparison of the dependency edge against the current epoch; if they are
equal the existing dependency edge is known to be valid in this epoch. This means
that the link won't be eligible for removal and therefore doesn't have to be
recreated.

(cherry picked from commit 327744ac17)
2026-06-17 18:38:09 +00:00
rootvector2 e17e8d5422 fix(core): escape overlapping comment delimiters in escapeCommentText
`COMMENT_DISALLOWED` is matched globally, so overlapping delimiter
sequences are skipped: `<!-->` only escapes the leading `<!--` and
leaves a live `-->` that can close a programmatically created comment
node early. Drop the `^` anchors so a standalone `>`/`->` is escaped
wherever it appears, which neutralizes the trailing delimiter left
behind by an earlier match.

(cherry picked from commit ea1a3ed64c)
2026-06-17 18:37:12 +00:00
Andrew Scott 74f2b91c12 refactor(compiler): correct TcbInvalidReferenceOp initializer
initializer should use null! as any rather than simply '= any'

(cherry picked from commit a5ee50beac)
2026-06-17 15:14:55 +00:00
Angular Robot 0f1cfe3082 build: update cross-repo angular dependencies to v22.0.2
See associated pull request for more information.
2026-06-17 08:05:50 -07:00
Alex Rickabaugh ffbbbf9129 refactor(compiler): add support for @Input transforms under isolatedDeclarations
Adds support for `@Input` transform functions in isolated declarations mode (`emitDeclarationOnly: true`), allowing components and directives to specify `transform` functions without triggering fatal compiler errors.

Synthesizes the `ngAcceptInputType_` write type syntactically:
- For referenced functions (`transform: booleanAttribute`), emits `Parameters<typeof booleanAttribute>[0]`, relying on downstream template type checking to resolve the type.
- For inline functions (`transform: (v: string) => boolean`), extracts `parameters[0].type` directly from the local TypeScript AST.

(cherry picked from commit 86ade07de6)
2026-06-16 17:27:23 +00:00
Alex Rickabaugh 568bd3a816 refactor(compiler): add support for host directives under isolatedDeclarations
Removes restrictions around using external references and local directives in `hostDirectives` under isolated declarations mode (`emitDeclarationOnly: true`).

By wrapping the host directive reference in a `WrappedNodeExpr`, TypeScript's declaration emitter seamlessly emits `typeof hostReference.node`, preserving existing imports or local identifiers exactly as authored. Also adds support for translating `PropertyAccessExpression` inside `WrappedNodeExpr` into `QualifiedName` for `.d.ts` emission, ensuring namespace imports (`import * as n from './dir'`) are preserved correctly.

(cherry picked from commit 5d2b1c4100)
2026-06-16 17:27:23 +00:00
SkyZeroZx b32ee7ceb3 fix(core): treat iframe credentialless as security-sensitive
Mark the iframe `credentialless` attribute as security-sensitive so dynamic
bindings are handled consistently with other iframe attributes that affect the
initial navigation, such as `sandbox`, `allow`, `referrerPolicy`, `csp`, and
`fetchPriority`.

Because `credentialless` must be present before the iframe starts loading to
affect the navigation’s credential mode, late dynamic updates can leave the final
DOM looking correct while the initial request was not loaded credentiallessly.

(cherry picked from commit 0152e3cbdf)
2026-06-16 16:05:57 +00:00
Kristiyan Kostadinov 93d0a5f95c fix(core): prevent unsubscribe during emit from throwing off other listeners
Fixes that when a listener unsubscribes from an `output` within its own callback, it was preventing subsequent listeners from running.

These changes fix the issue by not mutating the array while the emit loop is running, but replacing the listener with `null` and coming back later to remove it.

Fixes #69325.

(cherry picked from commit 28cb15a2bb)
2026-06-16 15:29:36 +00:00
Andrew Scott fef8bcfb38 refactor(compiler-cli): Export indexer API for use in hybrid analysis
exports indexer API for use in hybrid analysis

(cherry picked from commit 83622ee519)
2026-06-15 18:53:40 +00:00
Andrew Scott be45e8e7cb refactor(compiler-cli): Change indexComponent file to be fileUrl
We do not need ParseSourceFile which contains the whole content. Only the file url is ever used.

(cherry picked from commit 21fccd4038)
2026-06-15 17:56:55 +00:00
Matthieu Riegler f309727ada refactor(compiler): Collect in-element comments
PR #67179 forgot to implement that part.

(cherry picked from commit 471dcb42ca)
2026-06-15 17:54:09 +00:00
SkyZeroZx 528a34f766 fix(core): avoid caching missing locale data
Only cache locale data loaded from the global locale registry when an actual locale entry is found.

This prevents attacker-controlled missing locale identifiers from being retained indefinitely in SSR when locale lookup falls back to a parent locale or the built-in English locale, avoiding unbounded process memory growth in locale-aware pipes and formatters.

(cherry picked from commit 98f42eaaae)
2026-06-15 17:53:12 +00:00
Alan Agius 6f1171991a fix(compiler): restrict possible event handler check to property names longer than 2 characters
Previously, the compiler disallowed translation of any attribute starting with 'on' for security reasons. This incorrectly disallowed translation of the 'on' attribute itself, which is not an event handler.

This commit introduces `isPossibleEventHandler` to verify that the property name has a length greater than 2 in addition to starting with 'on'. This allows attributes like 'on' to be translated while still correctly disallowing actual event handlers like 'onerror', 'onclick', etc.

(cherry picked from commit 417a4071a7)
2026-06-15 16:23:53 +00:00
Andrew Scott 06e9dbf9a5 refactor(core): ɵɵgetInheritedFactory should accept abstract type
An abstract component or directive can extend another class, meaning
ɵɵgetInheritedFactory needs to allow abstract

(cherry picked from commit 2112edefe1)
2026-06-15 16:22:39 +00:00
aparziale 15314c1736 fix(migrations): migration skip any target are not build or test
Fix migration behaviout that skip any target are not build or test

Fixes #66865

(cherry picked from commit 58efd86c78)
2026-06-12 16:24:47 +00:00
Alan Agius 8bb3947e99 refactor: optimize dom security schema lookups
Restructure the security schema map to index by property name instead of tag name, improving lookup efficiency.

(cherry picked from commit 32d7315094)
2026-06-12 16:20:40 +00:00
Andrew Scott 0f68807836 refactor(core): ComponentDef should allow abstract types too
d1539a8513 incorrectly assumed components wouldn't be abstract but
it is still possible (though probably should be an abstract directive instead).

(cherry picked from commit 8984c59626)
2026-06-11 20:08:13 +00:00
Kai Guo 3a48abc15c fix(core): preserve leave animation for sibling instances sharing a TNode
`animate.leave` was skipped — the element was removed from the DOM
synchronously instead of running its leave animation — whenever a
sibling instance of the same template entered in a different DOM parent
during the same change-detection tick (e.g. an exclusive-expansion
accordion or nav where opening section B collapses section A).

`leavingNodes` is keyed by `TNode`, which is shared by every instance of
a template. When a node was inserted, `cancelLeavingNodes` force-removed
any tracked leaving node whose DOM parent differed from the entering
node's parent (the `leavingParent !== newParent` branch added to
de-duplicate a dynamic component re-rendered into a fresh overlay pane).
For two distinct live sibling instances that merely share a `TNode`,
"different parent" is the normal situation, so the still-animating
sibling was ripped out.

Track the declaration view of each leaving element alongside it, and
only perform the cross-parent removal when the entering element belongs
to the same declaration view as the leaving one — i.e. the same logical
view re-rendered, the case the branch was written for. Two distinct
instances of a shared template have different declaration views, so
their `animate.leave` is now left to run to completion.

This preserves the dynamic-component/overlay de-duplication (#67032) and
the drag-and-drop node-move rescue (#67361), which are unchanged.

Fixes #69291

(cherry picked from commit 6b5616b2c7)
2026-06-11 17:39:01 +00:00
Hexix23 6867f77ec7 fix(http): distinguish repeated transfer cache params
Serialize transfer cache request parameters without comma-joining repeated values so distinct HttpClient requests cannot reuse the same cached response.

(cherry picked from commit a6c7fc5c13)
2026-06-11 16:59:31 +00:00
SkyZeroZx 6c1f3e9d49 fix(common): skip transfer cache for uncacheable HTTP traffic (#69316)
Do not store HTTP transfer cache entries when either the request or response
uses `Cache-Control: no-store`, `Cache-Control: private`, or
`Cache-Control: no-cache`.

Also skip transfer cache when requests use the Fetch API `cache` option with
`no-store` or `no-cache`.

Because transfer cache serializes SSR HTTP responses into the rendered HTML,
Angular now treats these directives conservatively to avoid exposing sensitive
or explicitly uncacheable data through `TransferState`.

PR Close #69316
2026-06-11 16:58:24 +00:00
SkyZeroZx 7ef1399068 fix(http): skip transfer cache for fetch credentialed requests (#69316)
Treat HttpClient requests using `credentials: 'include'` and `same-origin` as credentialed
when deciding whether a response can be stored in the HTTP transfer cache.

The transfer cache already skips requests with `withCredentials`, `Cookie`,
`Authorization`, or `Proxy-Authorization` because those responses may contain
user-specific data. Fetch-backed requests can express the same credentialed
behavior through the `credentials` option, so these responses must not be
serialized into the SSR HTML.

This keeps credentialed SSR responses out of TransferState and aligns the
cache eligibility check with the fetch request options supported by HttpClient.

PR Close #69316
2026-06-11 16:58:24 +00:00
arturovt 21bdff55da fix(zone.js): harden zoneSymbolEventNames against __proto__ key (defense-in-depth)
Initialize zoneSymbolEventNames with Object.create(null) instead of {}.

This is hardening only. addEventListener('__proto__', fn) is not
directly attacker-controllable — its presence in an application is
itself an application bug and a prerequisite for any issue here.

Without this change, if that application bug exists, two unexpected
behaviors follow depending on environment:

Browser: zoneSymbolEventNames['__proto__'] reads the __proto__ getter
and returns Object.prototype (truthy), bypassing prepareEventNames.
symbolEventName resolves to undefined and window['undefined'] = []
throws TypeError.

Node.js + --disable-proto=throw: the assignment
zoneSymbolEventNames['__proto__'] = {} inside prepareEventNames
triggers the disabled __proto__ setter and throws.

Using Object.create(null) removes the __proto__ accessor from the
map so the key is treated as a plain missing property in both cases.

(cherry picked from commit fd7c2daf4d)
2026-06-11 16:41:12 +00:00
rootvector2 94ea403563 fix(common): escape anchor fragment in shadow DOM name selector
`findAnchorFromDocument` interpolates the raw url fragment into
`[name="${target}"]` for the shadow DOM lookup, so a fragment reachable
through the router when `anchorScrolling` is on can break out of the
attribute selector and make `querySelector` throw or match unrelated
nodes, and it also breaks legitimate anchor names containing a quote.
Wrap the value in `CSS.escape` so it stays a single attribute-value token.

(cherry picked from commit a69e56df71)
2026-06-11 16:37:32 +00:00
Angular Robot cbcf31bfa9 build: update cross-repo angular dependencies
See associated pull request for more information.
2026-06-11 09:25:30 -07:00
Matthieu Riegler 2dd65d21e6 fix(http): pass down the reportUploadProgress and reportDownloadProgress on post/patch requests
The `addBody` function did not pass the argument correctly

fixes #69241

(cherry picked from commit c092a002e4)
2026-06-10 18:37:50 +00:00
Andrew Scott 4645850e24 refactor(compiler): Remove 80 char limit on AbstractEmitterVisitor
This limit breaks ts-ignore comments when using this for our source->source transform.
Rather than overridding it there, it's just removed here since we don't care about the limit

(cherry picked from commit 54112d9393)
2026-06-10 17:57:30 +00:00
Andrew Scott 4b0c3b8b8f refactor(core): Update registerNgModuleType to support codegen typechecking
Updates types and adds test for source->source transformation with tsc downstream

(cherry picked from commit d25d2e1524)
2026-06-10 17:53:00 +00:00
Andrew Scott 3f055435f6 refactor(forms): fix initWebMcpForm description to be required
updates from breakage in https://github.com/angular/angular/commit/c121407c0da2456543a54822941d71a75490b703

(cherry picked from commit a7e7a2cf05)
2026-06-10 17:51:20 +00:00
Doug Parker dbf64c8eb5 test(core): fix AI tools test flake
This test flakes occasionally because it is called in production when a platform is created and unregistered when a platform is destroyed. However, not all tests properly clean up their platforms, meaning we can accidentally leak platforms between tests. If this happens, we end up have an event listener created from the production code path and a second event listener from the test. When the test emits the event, both listeners respond and it causes too many responses which fails the test.

Ideally, all tests would clean up the platforms correctly, but this seems difficult to guarantee for all Angular tests and is likely to break over time. The simplest solution is just destroy any leaked platform before the test starts. It's a bit elegant, but the safest option.

(cherry picked from commit 492e3a2a1f)
2026-06-10 17:29:05 +00:00
SkyZeroZx 045bb736b3 fix(core): validate lowercase SVG animation attribute names
Normalize SVG animation attributeName lookup to also recognize lowercase attributename before allowing dynamic animation value bindings.

Add runtime and platform-server SSR regression coverage for lowercase attributename retargeting.

(cherry picked from commit e640692452)
2026-06-10 17:22:34 +00:00
Hexix23 1ee224ca30 fix(compiler): disallow i18n event attributes
Reject translated event-handler attributes so localization cannot bypass Angular event-attribute validation.

(cherry picked from commit 6c41f5ca01)
2026-06-10 17:21:38 +00:00
SkyZeroZx 1bd5a562f5 docs: deprecate XHR support for server-side rendering in HTTP docs and recommend Fetch
(cherry picked from commit 2066225244)
2026-06-10 17:20:43 +00:00
arturovt 3c2892c8df fix(common): prevent prototype pollution in formatDateTime
Replace `in` operator with `Object.hasOwn` in
formatDateTime to prevent prototype pollution attacks.

The `in` operator traverses the prototype chain, meaning a polluted
Object.prototype key could be picked up as a valid replacement value.
This is especially critical in SSR environments where a single
prototype pollution attack persists across all subsequent requests in
the shared Node.js process, potentially injecting malicious content
into every user's rendered HTML.

Using `Object.hasOwn` restricts the lookup to
own properties only, blocking prototype chain traversal.

(cherry picked from commit 1ec125276d)
2026-06-10 17:19:34 +00:00
Matthieu Riegler 11836a670a fix(forms): delay mcp reading the form model by a tick
Reading the form model on init is unsafe as it could depend on inputs (eg a required input). We need to delay the read by a tick (after the inputs are set) to ensure that values can be safely read.

fixes #69262

(cherry picked from commit 9604ecfd8b)
2026-06-10 17:14:45 +00:00
Matthieu Riegler 5946c18275 fix(compiler): sanitize href/xlink:href attributes of any element of the MathML namespace
The ensures that future, present and past (and precated) elements of that namespace get sanitized.

(cherry picked from commit 3927a5b271)
2026-06-10 17:13:53 +00:00
arturovt e51ad374ea fix(forms): remove animationstart listener on component destroy to prevent memory leak
The `watchValidity` method in `AnimationInputValidityMonitor` was registering
an anonymous arrow function via `addEventListener` with no corresponding
`removeEventListener` call.

In V8, each closure is represented as a `JSFunction` holding a strong pointer
to a heap-allocated `Context` object containing captured variables
(`VariableLocation::CONTEXT` slots, decided at parse time by
`Scope::MustAllocateInContext`). In Blink, DOM event listeners are stored in
the element's `EventTargetData::event_listener_map` as `JSEventListener`
wrappers backed by a `v8::Persistent<JSFunction>` handle — a strong cross-heap
reference that keeps the function alive as long as the element is alive.

Because the callback passed to `watchValidity` closes over the calling
component/directive (which itself holds a reference back to the element), this
produced a cross-heap reference cycle:

```
  HTMLInputElement (Blink/Oilpan)
    └── EventTargetData → JSEventListener → v8::Persistent<JSFunction>
          └── Context → callback closure
                └── component → HTMLInputElement  ← cycle
```

Neither V8's nor Blink's GC could independently break this cycle because it
crosses the V8/Oilpan heap boundary. The element was therefore never collected
after being removed from the DOM.

The fix stores the listener in a named local variable and registers its removal
via `DestroyRef.onDestroy`, tying cleanup to the lifetime of the component that
owns the element. This ensures `removeEventListener` is called with the exact
same `JSFunction` reference, causing Blink to drop the `v8::Persistent` handle
and allowing both the function and the element to become GC-eligible.

(cherry picked from commit 6cc54e5ede)
2026-06-10 16:56:20 +00:00
Kristiyan Kostadinov b1f02eb5c5 refactor(core): add internal utility
Sets up a utility function that we need for an internal project.

(cherry picked from commit 158307cd63)
2026-06-10 16:54:40 +00:00
Matthieu Riegler 85d2d100e3 fix(forms): harden FormGroup control lookups against prototype shadowing
Guard FormGroup control-map presence checks with safe own-property checks to avoid inherited/prototype collisions from reserved keys such as hasOwnProperty and toString.

This prevents:
- crashes from shadowed hasOwnProperty access paths
- incorrect early-return and existence behavior for prototype-named controls

Adds regression tests for prototype-shadowed keys covering:
- register/add with toString
- contains/get with hasOwnProperty
- setControl/removeControl with toString
- FormRecord behavior with hasOwnProperty

(cherry picked from commit f06b96d181)
2026-06-10 02:28:00 +00:00
Matthieu Riegler 6e3d51d7df refactor(migrations): Improve safeNavigationMigration heuristic
There is no need to migrate expressions with a nullish comparison.

fixes #69274

(cherry picked from commit 6b0150faad)
2026-06-10 00:11:59 +00:00
Andrew Scott 01ea640539 refactor(core): Fix DirectiveDefinition interface to allow abstract classes
Interface should permit abstract classes since directives can be abstract

(cherry picked from commit d1539a8513)
2026-06-09 23:21:08 +00:00
Jad Chahed a704b08379 docs: add Signal Forms and v22 guidance to AI best-practices and llms.txt
Update the AI codegen resources for Angular v22:
- best-practices.md: OnPush is the default in v22+ (don't set it explicitly),
  recommend Signal Forms, and recommend the @Service decorator.
- llms.txt: add a Signal Forms reference, the httpResource guide, and an
  Accessibility section linking the Angular Aria overview.

(cherry picked from commit 248e9c146d)
2026-06-09 21:00:00 +00:00
Andrew Scott 43a0e28729 fix(language-service): prevent external template inlay hints from appearing in TS files
Inlay hints from external templates were being incorrectly applied to
TypeScript files because the compiler was processing all templates
associated with components found in the TS file, regardless of whether
the template was inline or external. This resulted in misplaced hints
due to mismatched offsets.

This change filters the templates and host bindings processed in
getInlayHintsForTemplate to only include those that belong to the
target file being queried.

Fixes #69224

(cherry picked from commit 2e4ed8027d)
2026-06-09 20:33:19 +00:00
Kristiyan Kostadinov 4289c4c840 fix(core): update comment for Default change detection
Updates the comment on `ChangeDetectionStrategy.Default` to mention that it's the same as `Eager`.

Fixes #69253.

(cherry picked from commit 5829177729)
2026-06-09 20:10:04 +00:00
Andrew Scott 562a566ead fix(core): Handle synchronous errors in PendingTasks.run function
catches synchronous errors coming out of the function passed to PendingTasks.run

(cherry picked from commit 0e16bb701f)
2026-06-09 19:24:26 +00:00
Andrew Scott 43edc8410f fix(router): use native URL object for navigation boundary and comparison
Previously, `NavigationStateManager` relied on string-based comparisons and `.substring()` to match `NavigateEvent` URLs against internal router transitions or the application root boundary. This was brittle against trailing slashes, query parameter order variations, and sibling application URLs.

This commit updates the logic to:

- Use the native `URL` object to strictly compare `origin` and `pathname` for `appRootURL` boundaries.

- Sort `searchParams` and use `Location.stripTrailingSlash()` to robustly compare the router destination against the event destination.

- Pre-compute and store `appRootUrl` as a `URL` object to avoid redundant parsing on every navigation.

(cherry picked from commit fe721868a6)
2026-06-09 11:15:20 -07:00
arturovt c4b5fa3c92 fix(common): escape CSS string-terminating characters in escapeCssUrl
The `escapeCssUrl` helper used by `NgOptimizedImage` to sanitize placeholder URLs for use in the `background-image` CSS property previously escaped only backslashes and double quotes. However, several characters that can terminate a CSS quoted string according to the CSS Syntax Level 3 specification were left unescaped, allowing a crafted placeholder URL to break out of the `url("...")` context and inject arbitrary CSS.

This change additionally escapes the following characters using CSS hex escapes:

* `U+000A` (LINE FEED) → `\A `
* `U+000D` (CARRIAGE RETURN) → `\D `
* `U+000C` (FORM FEED) → `\C `
* `U+0000` (NULL) → `\0 `

For example:

```text id="1w5vkp"
x.com/img\nx.jpg  →  x.com/img\A x.jpg
x.com/img\rx.jpg  →  x.com/img\D x.jpg
x.com/img\fx.jpg  →  x.com/img\C x.jpg
x.com/img\0x.jpg  →  x.com/img\0 x.jpg
```

The trailing space is required by the CSS tokenizer to terminate the escape sequence and prevent the following character from being interpreted as part of the escape.

The backslash replacement remains first in the chain to avoid double-escaping the backslashes introduced by subsequent replacements.

(cherry picked from commit 3dd35c242c)
2026-06-09 10:40:25 -07:00
cexbrayat cdcea80327 fix(core): require WebMCP tool descriptions
The WebMCP ModelContextTool dictionary marks description as required: https://webmachinelearning.github.io/webmcp/#modelcontexttool-dictionary

(cherry picked from commit c121407c0d)
2026-06-09 10:29:15 -07:00