Skip to content

Commit

Permalink
add leading and trailing slash sanitization for params (#8276)
Browse files Browse the repository at this point in the history
* add leading and trailing slash sanitization for params

* chore: fix lint

* refactor: use shared trimSlashes util

---------

Co-authored-by: Nate Moore <[email protected]>
Co-authored-by: Nate Moore <[email protected]>
  • Loading branch information
3 people authored Aug 31, 2023
1 parent 84427f3 commit d3a6f9f
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/chilled-hornets-press.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Sanitize route params for leading and trailing slashes
5 changes: 4 additions & 1 deletion packages/astro/src/core/routing/params.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { GetStaticPathsItem, Params, RouteData } from '../../@types/astro';
import { validateGetStaticPathsParameter } from './validation.js';
import { trimSlashes } from '../path.js';

/**
* given an array of params like `['x', 'y', 'z']` for
Expand Down Expand Up @@ -32,7 +33,9 @@ export function stringifyParams(params: GetStaticPathsItem['params'], route: Rou
const validatedParams = Object.entries(params).reduce((acc, next) => {
validateGetStaticPathsParameter(next, route.component);
const [key, value] = next;
acc[key] = value?.toString();
if (value !== undefined) {
acc[key] = typeof value === 'string' ? trimSlashes(value) : value.toString()
}
return acc;
}, {} as Params);

Expand Down
66 changes: 66 additions & 0 deletions packages/astro/test/units/routing/route-sanitization.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {
createBasicSettings,
createFs,
createRequestAndResponse,
defaultLogger,
} from '../test-utils.js';
import { fileURLToPath } from 'node:url';
import { expect } from 'chai';
import { createContainer } from '../../../dist/core/dev/container.js';
import * as cheerio from 'cheerio';
import testAdapter from '../../test-adapter.js';

const root = new URL('../../fixtures/alias/', import.meta.url);
const fileSystem = {
'/src/pages/[...testSlashTrim].astro': `
---
export function getStaticPaths() {
return [
{
params: {
testSlashTrim: "/a-route-param-with-leading-trailing-slash/",
},
},
];
}
---
<p>Success!</p>
`,
};

describe('Route sanitization', () => {
let container;
let settings;

before(async () => {
const fs = createFs(fileSystem, root);
settings = await createBasicSettings({
root: fileURLToPath(root),
trailingSlash: 'never',
output: 'hybrid',
adapter: testAdapter(),
});
container = await createContainer({
fs,
settings,
logger: defaultLogger,
});
});

after(async () => {
await container.close();
});

describe('Request', () => {
it('should correctly match a route param with a trailing slash', async () => {
const { req, res, text } = createRequestAndResponse({
method: 'GET',
url: '/a-route-param-with-leading-trailing-slash',
});
container.handle(req, res);
const html = await text();
const $ = cheerio.load(html);
expect($('p').text()).to.equal('Success!');
});
});
});

0 comments on commit d3a6f9f

Please sign in to comment.