Commit 00a126aa authored by Thomas Randolph's avatar Thomas Randolph

Add URL Utility for making safe-ER URL paths

parent c39870f2
......@@ -16,6 +16,36 @@ function decodeUrlParameter(val) {
return decodeURIComponent(val.replace(/\+/g, '%20'));
}
/**
* Safely encodes a string to be used as a path
*
* Note: This function DOES encode typical URL parts like ?, =, &, #, and +
* If you need to use search parameters or URL fragments, they should be
* added AFTER calling this function, not before.
*
* @param {String} potentiallyUnsafePath
* @returns {String}
*/
export function encodeSaferUrl(potentiallyUnsafePath) {
const unencode = ['%2F'];
const encode = ['#', '!', '~', '\\*', "'", '\\(', '\\)'];
let saferPath = encodeURIComponent(potentiallyUnsafePath);
unencode.forEach((code) => {
saferPath = saferPath.replace(new RegExp(code, 'g'), decodeURIComponent(code));
});
encode.forEach((code) => {
const encodedValue = code
.codePointAt(code.length - 1)
.toString(16)
.toUpperCase();
saferPath = saferPath.replace(new RegExp(code, 'g'), `%${encodedValue}`);
});
return saferPath;
}
export function cleanLeadingSeparator(path) {
return path.replace(PATH_SEPARATOR_LEADING_REGEX, '');
}
......
......@@ -880,4 +880,27 @@ describe('URL utility', () => {
expect(urlUtils.getURLOrigin(url)).toBe(expectation);
});
});
describe('encodeSaferUrl', () => {
it.each`
character | input | output
${' '} | ${'/url/hello 1.jpg'} | ${'/url/hello%201.jpg'}
${'#'} | ${'/url/hello#1.jpg'} | ${'/url/hello%231.jpg'}
${'!'} | ${'/url/hello!.jpg'} | ${'/url/hello%21.jpg'}
${'~'} | ${'/url/hello~.jpg'} | ${'/url/hello%7E.jpg'}
${'*'} | ${'/url/hello*.jpg'} | ${'/url/hello%2A.jpg'}
${"'"} | ${"/url/hello'.jpg"} | ${'/url/hello%27.jpg'}
${'('} | ${'/url/hello(.jpg'} | ${'/url/hello%28.jpg'}
${')'} | ${'/url/hello).jpg'} | ${'/url/hello%29.jpg'}
${'?'} | ${'/url/hello?.jpg'} | ${'/url/hello%3F.jpg'}
${'='} | ${'/url/hello=.jpg'} | ${'/url/hello%3D.jpg'}
${'+'} | ${'/url/hello+.jpg'} | ${'/url/hello%2B.jpg'}
${'&'} | ${'/url/hello&.jpg'} | ${'/url/hello%26.jpg'}
`(
'properly escapes `$character` characters while retaining the integrity of the URL',
({ input, output }) => {
expect(urlUtils.encodeSaferUrl(input)).toBe(output);
},
);
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment