Skip to content

Commit f45d4ca

Browse files
authored
Revert "fix: normalize control characters in relative URLs (#15416)" (#15442)
This reverts commit 36bdbeb.
1 parent 1401852 commit f45d4ca

11 files changed

Lines changed: 11 additions & 90 deletions

File tree

packages/react-router/.changes/patch.normalize-url-control-characters.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

packages/react-router/__tests__/dom/link-href-test.tsx

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -129,26 +129,6 @@ describe("<Link> href", () => {
129129
expect(renderer.root.findByType("a").props.href).toEqual("//remix.run");
130130
});
131131

132-
test("normalizes special characters in relative <Link> values", () => {
133-
let renderer: TestRenderer.ReactTestRenderer;
134-
TestRenderer.act(() => {
135-
renderer = TestRenderer.create(
136-
<MemoryRouter initialEntries={["/inbox/messages"]}>
137-
<Routes>
138-
<Route path="inbox">
139-
<Route
140-
path="messages"
141-
element={<Link to={"/\t/nested/path"} />}
142-
/>
143-
</Route>
144-
</Routes>
145-
</MemoryRouter>,
146-
);
147-
});
148-
149-
expect(renderer.root.findByType("a").props.href).toEqual("/nested/path");
150-
});
151-
152132
test('<Link to="mailto:remix@example.com"> is treated as external link', () => {
153133
let renderer: TestRenderer.ReactTestRenderer;
154134
TestRenderer.act(() => {

packages/react-router/__tests__/router/browser-test.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,6 @@ describe("a browser history", () => {
4747
expect(href).toEqual("/the/path?the=query#the-hash");
4848
});
4949

50-
it("normalizes special characters in relative hrefs", () => {
51-
for (let char of ["\t", "\n", "\r"]) {
52-
expect(history.createHref(`/${char}/nested/path`)).toBe("/nested/path");
53-
}
54-
});
55-
5650
it("does not encode the generated path", () => {
5751
const encodedHref = history.createHref({
5852
pathname: "/%23abc",

packages/react-router/__tests__/router/redirects-test.ts

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createMemoryHistory } from "../../lib/router/history";
22
import { IDLE_NAVIGATION, createRouter } from "../../lib/router/router";
3-
import { redirect, replace } from "../../lib/router/utils";
3+
import { replace } from "../../lib/router/utils";
44
import type { TestRouteObject } from "./utils/data-router-setup";
55
import { cleanup, setup } from "./utils/data-router-setup";
66
import { createFormData, tick } from "./utils/utils";
@@ -482,25 +482,6 @@ describe("redirects", () => {
482482
}
483483
});
484484

485-
it("normalizes special characters in redirects", async () => {
486-
let router = createRouter({
487-
history: createMemoryHistory(),
488-
routes: [
489-
{ path: "/" },
490-
{ path: "/start", loader: () => redirect("/\t/parent") },
491-
{ path: "/parent" },
492-
],
493-
});
494-
router.initialize();
495-
await tick();
496-
497-
await router.navigate("/start");
498-
expect(router.state.location).toMatchObject({
499-
pathname: "/parent",
500-
});
501-
router.dispose();
502-
});
503-
504485
it("properly handles same-origin absolute URLs when using a basename", async () => {
505486
let t = setup({ routes: REDIRECT_ROUTES, basename: "/base" });
506487

packages/react-router/lib/dom/lib.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ import {
3838
defaultMapRouteProperties,
3939
ErrorResponseImpl,
4040
SUPPORTED_ERROR_TYPES,
41-
isAbsoluteUrl,
4241
joinPaths,
4342
matchPath,
4443
parseToInfo,
4544
resolveTo,
4645
stripBasename,
4746
} from "../router/utils";
47+
import { ABSOLUTE_URL_REGEX } from "../router/url";
4848

4949
// eslint-disable-next-line @typescript-eslint/no-unused-vars
5050
import type * as _ from "./global";
@@ -1334,7 +1334,7 @@ export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
13341334
) {
13351335
let { basename, navigator, useTransitions } =
13361336
React.useContext(NavigationContext);
1337-
let isAbsolute = typeof to === "string" && isAbsoluteUrl(to);
1337+
let isAbsolute = typeof to === "string" && ABSOLUTE_URL_REGEX.test(to);
13381338

13391339
let parsed = parseToInfo(to, basename);
13401340
to = parsed.to;
@@ -1944,7 +1944,8 @@ export const Form = React.forwardRef<HTMLFormElement, FormProps>(
19441944
let formAction = useFormAction(action, { relative });
19451945
let formMethod: HTMLFormMethod =
19461946
method.toLowerCase() === "get" ? "get" : "post";
1947-
let isAbsolute = typeof action === "string" && isAbsoluteUrl(action);
1947+
let isAbsolute =
1948+
typeof action === "string" && ABSOLUTE_URL_REGEX.test(action);
19481949

19491950
let submitHandler: React.SubmitEventHandler<HTMLFormElement> = (event) => {
19501951
onSubmit && onSubmit(event);

packages/react-router/lib/dom/server.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
convertRoutesToDataRoutes,
2525
isRouteErrorResponse,
2626
} from "../router/utils";
27-
import { ABSOLUTE_URL_REGEX, normalizeRelativeUrl } from "../router/url";
27+
import { ABSOLUTE_URL_REGEX } from "../router/url";
2828
import { DataRoutes, Router } from "../components";
2929
import {
3030
DataRouterContext,
@@ -457,7 +457,6 @@ function createHref(to: To) {
457457

458458
function encodeLocation(to: To): Path {
459459
let href = typeof to === "string" ? to : createPath(to);
460-
href = normalizeRelativeUrl(href);
461460
// Treating this as a full URL will strip any trailing spaces so we need to
462461
// pre-encode them since they might be part of a matching splat param from
463462
// an ancestor route

packages/react-router/lib/router/history.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { normalizeRelativeUrl, PROTOCOL_RELATIVE_URL_REGEX } from "./url";
1+
import { PROTOCOL_RELATIVE_URL_REGEX } from "./url";
22

33
////////////////////////////////////////////////////////////////////////////////
44
//#region Types and Constants
@@ -407,7 +407,7 @@ export function createBrowserHistory(
407407
}
408408

409409
function createBrowserHref(window: Window, to: To) {
410-
return normalizeRelativeUrl(typeof to === "string" ? to : createPath(to));
410+
return typeof to === "string" ? to : createPath(to);
411411
}
412412

413413
return getUrlBasedHistory(
@@ -798,7 +798,6 @@ export function createBrowserURLImpl(
798798
invariant(base, "No window.location.(origin|href) available to create URL");
799799

800800
let href = typeof to === "string" ? to : createPath(to);
801-
href = normalizeRelativeUrl(href);
802801

803802
// Treating this as a full URL will strip any trailing spaces so we need to
804803
// pre-encode them since they might be part of a matching splat param from

packages/react-router/lib/router/router.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ import {
7777
} from "./utils";
7878
import {
7979
normalizeProtocolRelativeUrl,
80-
normalizeRelativeUrl,
8180
PROTOCOL_RELATIVE_URL_REGEX,
8281
} from "./url";
8382

@@ -6909,8 +6908,6 @@ function normalizeRedirectLocation(
69096908
basename: string,
69106909
historyInstance: History,
69116910
): string {
6912-
location = normalizeRelativeUrl(location);
6913-
69146911
if (isAbsoluteUrl(location)) {
69156912
// Strip off the protocol+origin for same-origin + same-basename absolute redirects
69166913
let normalizedLocation = location;
Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,6 @@
11
export const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|[\\/]{2})/i;
22
export const PROTOCOL_RELATIVE_URL_REGEX = /^[\\/]{2}/;
33

4-
// Normalize characters ignored by the URL parser before determining whether a
5-
// URL is relative or absolute.
6-
export function normalizeRelativeUrl(url: string): string {
7-
if (ABSOLUTE_URL_REGEX.test(url)) {
8-
return url;
9-
}
10-
11-
let normalized = url.replace(/[\t\n\r]/g, "");
12-
if (!ABSOLUTE_URL_REGEX.test(normalized)) {
13-
return normalized;
14-
}
15-
16-
if (PROTOCOL_RELATIVE_URL_REGEX.test(normalized)) {
17-
return normalized.replace(/^[\\/]+/, "/");
18-
}
19-
20-
return normalized.replace(/^([a-z][a-z0-9+.-]*):/i, "$1%3A");
21-
}
22-
234
export function normalizeProtocolRelativeUrl(url: string, protocol: string) {
245
return protocol + url.replace(/\\/g, "/");
256
}

packages/react-router/lib/router/utils.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { invariant, parsePath, warning } from "./history";
55
import {
66
ABSOLUTE_URL_REGEX,
77
normalizeProtocolRelativeUrl,
8-
normalizeRelativeUrl,
98
PROTOCOL_RELATIVE_URL_REGEX,
109
} from "./url";
1110

@@ -1854,8 +1853,7 @@ export function prependBasename({
18541853
return pathname === "/" ? basename : joinPaths([basename, pathname]);
18551854
}
18561855

1857-
export const isAbsoluteUrl = (url: string) =>
1858-
ABSOLUTE_URL_REGEX.test(normalizeRelativeUrl(url));
1856+
export const isAbsoluteUrl = (url: string) => ABSOLUTE_URL_REGEX.test(url);
18591857

18601858
/**
18611859
* Returns a resolved {@link Path} object relative to the given pathname.
@@ -1876,7 +1874,6 @@ export function resolvePath(to: To, fromPathname = "/"): Path {
18761874

18771875
let pathname: string;
18781876
if (toPathname) {
1879-
toPathname = normalizeRelativeUrl(toPathname);
18801877
toPathname = removeDoubleSlashes(toPathname);
18811878
if (toPathname.startsWith("/")) {
18821879
pathname = resolvePathname(toPathname.substring(1), "/");
@@ -2410,9 +2407,7 @@ export function parseToInfo<T extends To | string>(
24102407
_to: T,
24112408
basename: string,
24122409
): ParsedLocationInfo<T | string> {
2413-
let to = (
2414-
typeof _to === "string" ? normalizeRelativeUrl(_to) : _to
2415-
) as string;
2410+
let to = _to as string;
24162411
if (typeof to !== "string" || !ABSOLUTE_URL_REGEX.test(to)) {
24172412
return {
24182413
absoluteURL: undefined,

0 commit comments

Comments
 (0)