-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14351 from Expensify/yuwen-sanitizeStringForJSONP…
…arse
- Loading branch information
Showing
5 changed files
with
164 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const replacer = str => ({ | ||
'\\': '\\\\', | ||
'\t': '\\t', | ||
'\n': '\\n', | ||
'\r': '\\r', | ||
'\f': '\\f', | ||
'"': '\\"', | ||
}[str]); | ||
|
||
/** | ||
* Replace any characters in the string that will break JSON.parse for our Git Log output | ||
* | ||
* Solution partly taken from SO user Gabriel Rodríguez Flores 🙇 | ||
* https://stackoverflow.com/questions/52789718/how-to-remove-special-characters-before-json-parse-while-file-reading | ||
* | ||
* @param {String} inputString | ||
* @returns {String} | ||
*/ | ||
module.exports = function (inputString) { | ||
if (typeof inputString !== 'string') { | ||
throw new TypeError('Input must me of type String'); | ||
} | ||
|
||
// Replace any newlines and escape backslashes | ||
return inputString.replace(/\\|\t|\n|\r|\f|"/g, replacer); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import sanitizeStringForJSONParse from '../../.github/libs/sanitizeStringForJSONParse'; | ||
|
||
// Bad inputs should cause an error to be thrown | ||
const badInputs = [ | ||
null, | ||
undefined, | ||
42, | ||
true, | ||
]; | ||
|
||
// Invalid JSON Data should be able to get parsed and the parsed result should match the input text. | ||
const invalidJSONData = [ | ||
['Hello \t world!', 'Hello \t world!'], | ||
['Hello \n world!', 'Hello \n world!'], | ||
['Hello \n\tworld!', 'Hello \n\tworld!'], | ||
['"Hello world!"', '"Hello world!"'], | ||
['Test "', 'Test "'], | ||
['something `\\ something', 'something `\\ something'], | ||
|
||
// Real-life examples from git commits that broke getMergeLogsAsJSON | ||
// From https://github.com/Expensify/App/commit/e472470893867648cfbd85a5c2c5d24da1efece6 | ||
['Add \\', 'Add \\'], | ||
|
||
// From https://github.com/Expensify/App/pull/13500/commits/b730d5c43643f32baa3b189f0238f4de61aae0b7 | ||
['Prevent commit messages that end in `\\` from breaking `getMergeLogsAsJSON()`', 'Prevent commit messages that end in `\\` from breaking `getMergeLogsAsJSON()`'], | ||
]; | ||
|
||
// Valid JSON Data should be able to get parsed and the input text should be unmodified. | ||
const validJSONData = [ | ||
['', ''], | ||
['Hello world!', 'Hello world!'], | ||
['Hello\\\\world!', 'Hello\\\\world!'], | ||
]; | ||
|
||
describe('santizeStringForJSONParse', () => { | ||
describe.each(badInputs)('willDetectBadInputs', (input) => { | ||
test('sanitizeStringForJSONParse', () => { | ||
expect(() => sanitizeStringForJSONParse(input)).toThrow(); | ||
}); | ||
}); | ||
|
||
describe.each(invalidJSONData)('canHandleInvalidJSON', (input, expectedOutput) => { | ||
test('sanitizeStringForJSONParse', () => { | ||
const badJSON = `{"key": "${input}"}`; | ||
expect(() => JSON.parse(badJSON)).toThrow(); | ||
const goodJSON = JSON.parse(`{"key": "${sanitizeStringForJSONParse(input)}"}`); | ||
expect(goodJSON.key).toStrictEqual(expectedOutput); | ||
}); | ||
}); | ||
|
||
describe.each(validJSONData)('canHandleValidJSON', (input, expectedOutput) => { | ||
test('sanitizeStringForJSONParse', () => { | ||
const goodJSON = JSON.parse(`{"key": "${sanitizeStringForJSONParse(input)}"}`); | ||
expect(goodJSON.key).toStrictEqual(expectedOutput); | ||
}); | ||
}); | ||
}); |