Resolve the approved relative workspace tsdk path to an absolute path by checking workspace folders. This ensures the path is correctly resolved on the server side.
Fixes#69276
(cherry picked from commit fbe807ca12)
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)
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)
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)
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)
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)
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)
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)
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)
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)
adev is cross-origin isolated (COOP same-origin + COEP require-corp) so the
embedded WebContainer editor can use SharedArrayBuffer. Under require-corp the
cross-origin YouTube iframe in `<docs-video>` only loaded in Chromium, leaving
the player blank in Safari.
Switch COEP from `require-corp` to `credentialless`. The page stays cross-origin
isolated, so the editor keeps working, but cross-origin frames are now allowed
to load, which restores the inline player in Safari as well.
(cherry picked from commit 86cd166141)
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)
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)
Drops `position: absolute` from the version picker `<ul>` and tightens `max-height` to `70dvh` so the cdk-overlay-pane fits the viewport and the inner scroll reaches the last versions on mobile and desktop.
(cherry picked from commit 7d92cc8b46)
XHR support in `@angular/platform-server` is deprecated because the underlying `xhr2` library does not safely handle redirects. Specifically, it can forward `Authorization` headers on cross-origin redirects (which leaks credentials) and is susceptible to denial-of-service (DoS) via redirect loops.
DEPRECATED: XHR support in `@angular/platform-server` is deprecated. Use standard `fetch` APIs instead.
(cherry picked from commit 8446e46f8b)
- Run comparison benchmark in an isolated git worktree to prevent workspace pollution and local branch conflicts.
- Harden security by passing benchmark target and SHA as environment variables to prevent shell injection, and adding '--' to bazel query and git rev-parse.
- Optimize workflow by removing pnpm caching to mitigate cache poisoning risks.
- Improve robustness of benchmark log parsing, supporting both ZIP outputs and raw directories, and safely checking for JSON reports.
- Centralize git command execution on the dev-infra GitClient for consistency.
- Add tslib to benchpress dependencies to prevent module resolution failures.
(cherry picked from commit 547d85addf)
Preserve `referrer: ''` when constructing and cloning HttpRequest.
An empty string is a valid Fetch referrer value and is documented by
Angular as the way to omit referrer information for sensitive requests.
The previous truthy checks treated it as if the option was not provided,
causing requests to fall back to the browser default referrer behavior.
(cherry picked from commit cd771d3712)
Removes `Authorization`, `Cookie`, and `Proxy-Authorization` headers when a request is redirected to a different origin. This aligns with the Fetch API's redirect algorithm to prevent sensitive information from being sent to third-party origins.
(cherry picked from commit 47d68dcb26)
The "Override current locale for CurrencyPipe" example used `{{ amount | currency: 'en-US' }}`, but the first `CurrencyPipe` argument is the currency code, not the locale, so `'en-US'` was treated as an invalid currency code (rendered literally as the symbol) and the locale was never overridden. Since `locale` is the fourth positional argument, the example now passes a valid currency code, display, and digits before it (`'USD' : 'symbol' : '1.2-2' : 'en-US'`), matching the parameter order shown on the CurrencyPipe API page.
(cherry picked from commit a82f822057)
Reveal code copy controls on hover and focus so long code snippets stay readable while keyboard access and copy state feedback remain intact.
(cherry picked from commit b7cb5844cf)
Apply schema-derived sanitizer resolution to TwoWayProperty ops so native two-way DOM bindings emit the same sanitizer as one-way property bindings.
Add compiler compliance coverage for innerHTML, srcdoc, URL, resource URL, and security-sensitive attribute cases.
(cherry picked from commit 3c70270c96)
- promote to default-on (remove opt-in setting and gear-menu toggle)
- replace the <pre> value cell with a collapsible JSON tree
- add key filter and column sort (size sorts by raw bytes)
- show an educational empty state when the app has no transfer state
- iterate every root in the directive forest and merge their state
- guard size calculation against undefined and circular references
- register listener once with DestroyRef cleanup; add a loading timeout
- distinguish array/string badge colors via theme-aware tokens
- responsive value cell width; flex-based table scroll
- add a component spec; seed the harness fixture with more demo data
(cherry picked from commit 06db706238)
TypeScript enums compile to self-executing function expressions that
are not tree-shakable, even when unused. Replace LocaleDataIndex with
a plain const object using `as const` to produce the same numeric
indices and literal types without the IIFE side-effect.
(cherry picked from commit d3239a3ac2)
Introduces a maximum length of 256 characters for date format strings.
This prevents potential Denial of Service (DoS) attacks by throwing an
`INVALID_DATE_FORMAT` error if an excessively long format string is
provided to `formatDate` or `DatePipe`, safeguarding against performance
degradation or application crashes.
(cherry picked from commit eeb03f4ea3)
The v22 event hero PNG shipped with a wide transparent margin baked into
its 960x540 canvas. Under the shared `img { width: 100% }` rule that empty
border stretched along with the artwork, leaving visible space around the
image. Trims the canvas to the artwork bounds (831x473) so it renders
flush; the retained pixels are unchanged and the file shrinks from about
795 KB to 568 KB.
(cherry picked from commit af7cb63151)