Last active
August 25, 2021 14:45
-
-
Save voxpelli/ff7a83406078ba2d68b738e63cad6498 to your computer and use it in GitHub Desktop.
HTML safe JSON escaping, see eg: https://github.com/ember-fastboot/fastboot/pull/85
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
// My own take | |
const JSON_ESCAPE = { | |
'&': '\\u0026', | |
'>': '\\u003e', | |
'<': '\\u003c', | |
'\u2028': '\\u2028', | |
'\u2029': '\\u2029' | |
}; | |
const JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/g; | |
const jsonStringifyForScriptTag = (obj) => | |
JSON.stringify(obj) | |
.replace(JSON_ESCAPE_REGEXP, match => JSON_ESCAPE[match]); |
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
// Extracted from https://github.com/ember-fastboot/ember-cli-fastboot/blob/909c1417ceeb8a5c92bb952b0d59be02bfdca546/packages/fastboot/src/ember-app.js#L406-L420 | |
// Discussion in https://github.com/ember-fastboot/fastboot/pull/85 | |
const JSON_ESCAPE = { | |
'&': '\\u0026', | |
'>': '\\u003e', | |
'<': '\\u003c', | |
'\u2028': '\\u2028', | |
'\u2029': '\\u2029' | |
}; | |
const JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/g; | |
function escapeJSONString(string) { | |
return string.replace(JSON_ESCAPE_REGEXP, function(match) { | |
return JSON_ESCAPE[match]; | |
}); | |
} |
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
const React = require('react'); | |
const { renderToStaticMarkup } = require('react-dom/server'); | |
const JSON_ESCAPE = { | |
'&': '\\u0026', | |
'>': '\\u003e', | |
'<': '\\u003c', | |
'\u2028': '\\u2028', | |
'\u2029': '\\u2029' | |
}; | |
const JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/g; | |
function escapeJSONString(value) { | |
return value.replace(JSON_ESCAPE_REGEXP, match => JSON_ESCAPE[match]); | |
} | |
function escapedJSONStringify(obj) { | |
return escapeJSONString(JSON.stringify(obj)); | |
} | |
const data = "</script><script>console.log('hejsan2')</script><script>"; | |
// outputs: <script type="application/ld+json">"</script><script>console.log('hejsan2')</script><script>"</script> | |
// which won't parse as expected + will log 'hejsan2' to the console | |
console.log(renderToStaticMarkup(React.createElement('script', { | |
type: 'application/ld+json', | |
dangerouslySetInnerHTML: { __html: `${JSON.stringify(data)}` } | |
}))); | |
// outputs: <script type="application/ld+json">"\u003c/script\u003e\u003cscript\u003econsole.log('hejsan2')\u003c/script\u003e\u003cscript\u003e"</script> | |
// which can be parsed as expected + won't log anything | |
// parsing it: JSON.parse(`"\u003c/script\u003e\u003cscript\u003econsole.log('hejsan2')\u003c/script\u003e\u003cscript\u003e"`) | |
// results in: "</script><script>console.log('hejsan2')</script><script>" | |
console.log(renderToStaticMarkup(React.createElement('script', { | |
type: 'application/ld+json', | |
dangerouslySetInnerHTML: { __html: `${escapedJSONStringify(data)}` } | |
}))); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment