Skip to content

Commit aea31a8

Browse files
swachterStefan Wachter
and
Stefan Wachter
authored
Apply encodeURIComponent on path parameter value (#1696)
* Apply encodeURIComponent on path parameter value * add changeset * Fix "params / path / allows UTF-8 characters" test * Add more tests for path parameter encoding --------- Co-authored-by: Stefan Wachter <[email protected]>
1 parent 477ac30 commit aea31a8

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

.changeset/wet-days-crash.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"openapi-fetch": patch
3+
---
4+
5+
Fix: encode primitive path parameters

packages/openapi-fetch/src/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ export function defaultPathSerializer(pathname, pathParams) {
424424
nextURL = nextURL.replace(match, `;${serializePrimitiveParam(name, value)}`);
425425
continue;
426426
}
427-
nextURL = nextURL.replace(match, style === "label" ? `.${value}` : value);
427+
nextURL = nextURL.replace(match, style === "label" ? `.${encodeURIComponent(value)}` : encodeURIComponent(value));
428428
}
429429
return nextURL;
430430
}

packages/openapi-fetch/test/index.test.ts

+38-3
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,42 @@ describe("client", () => {
260260
);
261261
});
262262

263+
it("escapes reserved characters in path segment", async () => {
264+
const client = createClient<paths>({ baseUrl });
265+
const { getRequestUrl } = useMockRequestHandler({
266+
baseUrl,
267+
method: "get",
268+
path: "/blogposts/*",
269+
});
270+
271+
await client.GET("/blogposts/{post_id}", {
272+
params: { path: { post_id: ";/?:@&=+$,# " } },
273+
});
274+
275+
// expect post_id to be encoded properly
276+
const url = getRequestUrl();
277+
expect(url.pathname).toBe("/blogposts/%3B%2F%3F%3A%40%26%3D%2B%24%2C%23%20");
278+
});
279+
280+
it("does not escape allowed characters in path segment", async () => {
281+
const client = createClient<paths>({ baseUrl });
282+
const { getRequestUrl } = useMockRequestHandler({
283+
baseUrl,
284+
method: "get",
285+
path: "/blogposts/*",
286+
});
287+
288+
const postId = "aAzZ09-_.!~*'()";
289+
290+
await client.GET("/blogposts/{post_id}", {
291+
params: { path: { post_id: postId } },
292+
});
293+
294+
// expect post_id to stay unchanged
295+
const url = getRequestUrl();
296+
expect(url.pathname).toBe(`/blogposts/${postId}`);
297+
});
298+
263299
it("allows UTF-8 characters", async () => {
264300
const client = createClient<paths>({ baseUrl });
265301
const { getRequestUrl } = useMockRequestHandler({
@@ -269,13 +305,12 @@ describe("client", () => {
269305
});
270306

271307
await client.GET("/blogposts/{post_id}", {
272-
params: { path: { post_id: "post?id = 🥴" } },
308+
params: { path: { post_id: "🥴" } },
273309
});
274310

275311
// expect post_id to be encoded properly
276312
const url = getRequestUrl();
277-
expect(url.searchParams.get("id ")).toBe(" 🥴");
278-
expect(url.pathname + url.search).toBe("/blogposts/post?id%20=%20%F0%9F%A5%B4");
313+
expect(url.pathname).toBe("/blogposts/%F0%9F%A5%B4");
279314
});
280315
});
281316

0 commit comments

Comments
 (0)