Skip to content

Commit 2bf5eba

Browse files
authored
explain the rationale for the chosen escaping implemenation in a comment (#24389)
1 parent d40dc73 commit 2bf5eba

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

packages/react-dom/src/server/ReactDOMServerFormatConfig.js

+13-4
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,25 @@ const startScriptSrc = stringToPrecomputedChunk('<script src="');
8383
const startModuleSrc = stringToPrecomputedChunk('<script type="module" src="');
8484
const endAsyncScript = stringToPrecomputedChunk('" async=""></script>');
8585

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+
*/
9096
function escapeBootstrapScriptContent(scriptText) {
9197
if (__DEV__) {
9298
checkHtmlStringCoercion(scriptText);
9399
}
94100
return ('' + scriptText).replace(scriptRegex, scriptReplacer);
95101
}
102+
const scriptRegex = /(<\/|<)(s)(cript)/gi;
103+
const scriptReplacer = (match, prefix, s, suffix) =>
104+
`${prefix}${s === 's' ? '\\u0073' : '\\u0053'}${suffix}`;
96105

97106
// Allows us to keep track of what we've already written so we can refer back to it.
98107
export function createResponseState(

0 commit comments

Comments
 (0)