| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Preserve createUrlTree command semantics, including custom serializer inputs, while keeping the single-leading-slash guarantee at the default serialization boundary. Expand coverage for command forms, public UrlTree values, secondary outlets, and preserved query parameters and fragments. Fixes angular#69700
There was a problem hiding this comment.
reviewed-for: public-api
Sorry, something went wrong.
|
This PR was merged into the repository. The changes were merged into the following branches: |
Sorry, something went wrong.
|
Note, we'll have to revert this fix, I was breaking inside G3. Not sure yet if it was a legit breakage or not. |
Sorry, something went wrong.
@JeanMeche Could we investigate the cause? I understand we should send another PR to try to see which tests failed or which cases broke. |
Sorry, something went wrong.
|
I'd had a hard time understanding what was the issue, but I believe it was a [routerLink]="['/'+ someVar, someId]" that was throwing. Unsure why. |
Sorry, something went wrong.
|
Well, according to GPT-5.6, I'm getting something like this; is there possibly some kind of "mock" that generates this behavior? it('rejects question-mark-prefixed relative commands with an explicit empty root segment', async () => {
@Component({
template: `<a [routerLink]="['?' + someVar, someId]">commands</a>`,
imports: [RouterLink],
})
class WithLink {
readonly someVar = 'search';
readonly someId = '123';
}
const snapshot: any = {
url: [new UrlSegment('', {})],
children: [],
outlet: PRIMARY_OUTLET,
};
snapshot.root = snapshot;
TestBed.configureTestingModule({
providers: [
provideRouter([{path: '', component: WithLink}]),
{provide: ActivatedRoute, useValue: {snapshot}},
],
});
const fixture = TestBed.createComponent(WithLink);
await expectAsync(fixture.whenStable()).toBeRejectedWithError(
/NG04019: Cannot serialize a UrlTree that would produce a protocol-relative URL/,
);
}); |
Sorry, something went wrong.
|
Fwiw, I wrote a typo, ? was a /. I doesn't look like they were mocks of such sort. |
Sorry, something went wrong.
|
From GPT:
it("can fail after a redirect promotes the link's trailing empty segment", async () => {
@Component({
template: `<a [routerLink]="['/' + someVar, someId]">commands</a>`,
imports: [RouterLink],
})
class WithLink {
readonly someVar = 'source';
readonly someId = '';
}
@Component({template: ''})
class Target {}
TestBed.configureTestingModule({
providers: [
provideRouter([
{path: '', pathMatch: 'full', component: WithLink},
{path: 'source/:id', redirectTo: '/:id/target'},
{path: '**', component: Target},
]),
],
});
const harness = await RouterTestingHarness.create('/');
const anchor = harness.fixture.nativeElement.querySelector('a');
// RouterLink itself produces a valid href.
expect(anchor.getAttribute('href')).toBe('/source/');
anchor.click();
// The redirect promotes the empty :id and produces //target.
await expectAsync(harness.fixture.whenStable()).toBeRejectedWithError(
/NG04019: Cannot serialize a UrlTree that would produce a protocol-relative URL/,
);
});
// Short variant
it('rejects an empty dynamic segment passed separately after the root command', async () => {
@Component({
template: `<a [routerLink]="['/', someVar, someId]">commands</a>`,
imports: [RouterLink],
})
class WithLink {
readonly someVar = '';
readonly someId = '123';
}
TestBed.configureTestingModule({
providers: [provideRouter([])],
});
const fixture = TestBed.createComponent(WithLink);
await expectAsync(fixture.whenStable()).toBeRejectedWithError(
/NG04019: Cannot serialize a UrlTree that would produce a protocol-relative URL/,
);
});As I understand it, the validation was apparently done too early before it could be confirmed that it was indeed a relative URL. |
Sorry, something went wrong.
|
I think generally the error is going to mostly surface issues with test data and potentially mistakes in the command construction. I still have extreme doubts that any of these are actual security issues. To avoid a breaking change here, I wonder if a better approach would be a dev mode warning (instead of throwing), coupled with modifying the serialization to simply return '/'. There is precedence for this in Router.parseUrl already: angular/packages/router/src/router.ts Lines 593 to 602 in d364c83 |
Sorry, something went wrong.
Avoid throwing when DefaultUrlSerializer encounters a UrlTree that would serialize to a protocol-relative URL. The exception surfaced existing test data and mistaken command construction as a breaking change after angular#69874. Warn in development mode and serialize the tree as "/" instead. Keep the browser-facing URL root-relative without changing command or route-recognition semantics. Follow the compatibility approach discussed in PR angular#69874: angular#69874 (comment) Address the g3 regression reported at: angular#69874 (comment) Fixes angular#69700
Avoid throwing when DefaultUrlSerializer encounters a UrlTree that would serialize to a protocol-relative URL. The exception surfaced existing test data and mistaken command construction as a breaking change after angular#69874. Warn in development mode and serialize the tree as "/" instead. Keep the browser-facing URL root-relative without changing command or route-recognition semantics. The original fix had to be reverted after a regression surfaced in g3: angular#69874 (comment) This uses the less disruptive fallback proposed in the follow-up discussion: angular#69874 (comment) Fixes angular#69700
| Back | FazBrowse Home | New Git URL |
Preserve createUrlTree command semantics, including custom serializer inputs, while keeping the single-leading-slash guarantee at the default serialization boundary.
Expand coverage for command forms, public UrlTree values, secondary outlets, and preserved query parameters and fragments.
Fixes #69700