explain the rationale for the chosen escaping implemenation in a comment (#24389)
Josh Story committed
Apr 16, 2022 at 14:29 UTC
2bf5eba7247a58aeb7ba23b3b5630d8bf6c2c4da
1 file changed
+13
-4
packages/react-dom/src/server/ReactDOMServerFormatConfig.js
+13
-4
@@ -83,16 +83,25 @@ const startScriptSrc = stringToPrecomputedChunk('<script src="');
83
const startModuleSrc = stringToPrecomputedChunk('<script type="module" src="');
84
const endAsyncScript = stringToPrecomputedChunk('" async=""></script>');
85
86
-const scriptRegex = /(<\/|<)(s)(cript)/gi;
87
-const scriptReplacer = (match, prefix, s, suffix) =>
88
- `${prefix}${s === 's' ? '\\u0073' : '\\u0053'}${suffix}`;
89
-
86
+/**
87
+ * This escaping function is designed to work with bootstrapScriptContent only.
88
+ * because we know we are escaping the entire script. We can avoid for instance
89
+ * escaping html comment string sequences that are valid javascript as well because
90
+ * if there are no sebsequent <script sequences the html parser will never enter
91
+ * script data double escaped state (see: https://www.w3.org/TR/html53/syntax.html#script-data-double-escaped-state)
92
+ *
93
+ * While untrusted script content should be made safe before using this api it will
94
+ * ensure that the script cannot be early terminated or never terminated state
95
+ */
96
function escapeBootstrapScriptContent(scriptText) {
97
if (__DEV__) {
98
checkHtmlStringCoercion(scriptText);
99
}
100
return ('' + scriptText).replace(scriptRegex, scriptReplacer);
101
}
102
+const scriptRegex = /(<\/|<)(s)(cript)/gi;
103
+const scriptReplacer = (match, prefix, s, suffix) =>
104
+ `${prefix}${s === 's' ? '\\u0073' : '\\u0053'}${suffix}`;
105
106
// Allows us to keep track of what we've already written so we can refer back to it.
107
export function createResponseState(