Skip to content

fix(common): only strip a literal /index.html suffix in AngularJSUrlCodec#69023

Open
fg0x0 wants to merge 1 commit into
angular:mainfrom
fg0x0:fix/upgrade-strip-index-html-regex
Open

fix(common): only strip a literal /index.html suffix in AngularJSUrlCodec#69023
fg0x0 wants to merge 1 commit into
angular:mainfrom
fg0x0:fix/upgrade-strip-index-html-regex

Conversation

@fg0x0
Copy link
Copy Markdown

@fg0x0 fg0x0 commented May 30, 2026

PR Checklist

What is the current behavior?

AngularJSUrlCodec._stripIndexHtml in @angular/common/upgrade (packages/common/upgrade/src/params.ts:238) has an unescaped . in the strip regex /\/index.html$/. The unescaped dot matches any character, so suffixes such as /indexXhtml, /index_html, /index!html, and /index/html are all stripped to the empty string instead of being preserved.

This is the same bug class that was fixed by commit d109bf9 ("fix(common): only strip a literal /index.html suffix from URLs") in Location._stripIndexHtml (packages/common/src/location/location.ts:319), but the sibling copy in the upgrade package's AngularJSUrlCodec was not updated.

Repro (Node only, mirrors the buggy regex):

```js
function buggy(url) { return url.replace(//index.html$/, ""); }
function fixed(url) { return url.replace(//index.html$/, ""); }

console.log(buggy("/page/indexXhtml")); // "/page" <- bug
console.log(fixed("/page/indexXhtml")); // "/page/indexXhtml" <- intended
```

In hybrid AngularJS-Angular apps that wire up LocationUpgradeModule, this affects $location.path() / $location.url() (route resolves to the stripped URL instead of the literal one) and $location.replace change detection in location_shim.ts:198, which calls urlCodec.areEqual(oldUrl, newUrl). areEqual('/page', '/page/indexXhtml') returns true and the URL-change event is suppressed.

Issue Number: N/A

What is the new behavior?

Escape the dot so the regex only matches the literal /index.html suffix, matching the precedent set by Location._stripIndexHtml.

Does this PR introduce a breaking change?

  • Yes
  • No

AngularJSUrlCodec.encodePath now preserves trailing segments that happen to match /index<any>html (e.g. /indexXhtml, /index_html). Apps that intentionally relied on the lossy stripping to alias arbitrary index<x>html suffixes to the parent path were depending on a regex typo and are extremely unlikely to exist; the parallel Location._stripIndexHtml shipped this same change in d109bf9 without being flagged as breaking.

Other information

Tests added in packages/common/upgrade/test/params.spec.ts mirror the cases used in d109bf9's location_spec.ts addition.

@pullapprove pullapprove Bot requested a review from kirjs May 30, 2026 11:39
@google-cla
Copy link
Copy Markdown

google-cla Bot commented May 30, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@angular-robot angular-robot Bot added the area: common Issues related to APIs in the @angular/common package label May 30, 2026
@ngbot ngbot Bot added this to the Backlog milestone May 30, 2026
@JeanMeche
Copy link
Copy Markdown
Member

Your commit has 3 authors with 2 that haven't signed the CLA. Can you amend your commit and remove the unnecessary authors. Without this we can't accept this PR. Thank you for your understanding.

@fg0x0 fg0x0 force-pushed the fix/upgrade-strip-index-html-regex branch from c6396fe to e017869 Compare May 30, 2026 13:24
…odec

Sibling miss of the fix in `Location._stripIndexHtml` (commit d109bf9).
`AngularJSUrlCodec._stripIndexHtml` in `@angular/common/upgrade` has the
identical regex with an unescaped `.`, so it strips arbitrary single
characters between `index` and `html`. For example `encodePath` collapses
`/page/indexXhtml` and `/page/index_html` to `/page`, and `areEqual`
(used by `$locationShim` to detect URL changes) treats those URLs as
equal to `/page`, suppressing legitimate URL-change events in hybrid
AngularJS-Angular apps.

Escape the dot so only the literal `/index.html` suffix is stripped,
matching the precedent set by `Location._stripIndexHtml`.
@fg0x0 fg0x0 force-pushed the fix/upgrade-strip-index-html-regex branch from e017869 to e1cae21 Compare May 30, 2026 13:29
@google-cla google-cla Bot added cla: yes and removed cla: no labels May 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: common Issues related to APIs in the @angular/common package cla: yes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants