Skip to content

Commit 25d5ecd

Browse files
authored
Merge pull request #425 from maryvilledev/issue422
Fix issue with snippet keys that contain apostrophes
2 parents bc5b4dc + f7df3f0 commit 25d5ecd

File tree

3 files changed

+25
-2
lines changed

3 files changed

+25
-2
lines changed

__tests__/util/requests.test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,18 @@ describe('util: requests', () => {
1616
expect(reqUtils.makeSaveEndpointUrl(username, snippet)).toEqual(expected);
1717
});
1818
});
19+
describe('sanitizeKey', () => {
20+
it('encodes characters that encodeURIComponent does not', () => {
21+
const str = './"!()*\'';
22+
const encoded = reqUtils.sanitizeKey(str);
23+
// Check that none of the characters in the original string appear in
24+
// the encoded string
25+
expect(str.split().every(ch => encoded.indexOf(ch) === -1)).toBe(true);
26+
});
27+
it('encodes titles with apostrophes', () => {
28+
const title = 'rick\'s_recipe_for_concentrated_dark_matter';
29+
const expected = 'rick%27s_recipe_for_concentrated_dark_matter';
30+
expect(reqUtils.sanitizeKey(title)).toEqual(expected);
31+
});
32+
});
1933
});

src/containers/AppBody.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
import { setPermissions } from '../actions/permissions';
1616
import { restoreUserCredentials } from '../actions/user';
1717
import { removeDeprecatedFiltersFromState } from '../util/codemirror-utils';
18+
import { sanitizeKey } from '../util/requests';
1819
import { setDefaults } from '../util/state-management';
1920

2021
const styles = {
@@ -82,7 +83,7 @@ export class AppBody extends Component {
8283

8384
// Reroute if not at the 'correct' location
8485
// So /:username/snippets/:id -> /:username/:id
85-
const nextRoute = `/${username}/${encodeURIComponent(snippetKey)}`;
86+
const nextRoute = `/${username}/${sanitizeKey(snippetKey)}`;
8687
if (router.location.pathname !== nextRoute) {
8788
router.push(nextRoute);
8889
}

src/util/requests.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
const API_URL = process.env.REACT_APP_API_URL;
22

3+
// encodeURIComponent does not convert all URI-unfriendly characters, necessitating
4+
// and enhanced encoding function
5+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent#Return_value
6+
export const sanitizeKey = str => (
7+
encodeURIComponent(str)
8+
.replace(/[!'.()*]/g, ch => `%${ch.charCodeAt(0).toString(16)}`)
9+
);
10+
311
/* Construct the endpoint to make a REST request to. Only the username is
412
* field is required; the snippetId will be left blank for POST requests,
513
* and can be supplied when needed (say, for PUT requests).
614
*/
715
export const makeSaveEndpointUrl = (username, snippetId = '') => {
816
if (snippetId) {
917
// Return a URL for GET & PUT requests
10-
return `${API_URL}/users/${username}/snippets/${encodeURIComponent(snippetId)}`;
18+
return `${API_URL}/users/${username}/snippets/${sanitizeKey(snippetId)}`;
1119
}
1220
// Return a URL for POST requests
1321
return `${API_URL}/users/${username}/snippets`;

0 commit comments

Comments
 (0)