diff --git a/.changeset/metal-moons-provide.md b/.changeset/metal-moons-provide.md
new file mode 100644
index 000000000000..1faeae6e6d3a
--- /dev/null
+++ b/.changeset/metal-moons-provide.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+refactor: use one escape function for json in html script body instead of two slightly different
diff --git a/packages/kit/src/runtime/server/page/load_node.js b/packages/kit/src/runtime/server/page/load_node.js
index 714a3e2ba462..582da5477210 100644
--- a/packages/kit/src/runtime/server/page/load_node.js
+++ b/packages/kit/src/runtime/server/page/load_node.js
@@ -1,7 +1,7 @@
import { normalize } from '../../load.js';
import { respond } from '../index.js';
import { s } from '../../../utils/misc.js';
-import { escape_json_value_in_html } from '../../../utils/escape.js';
+import { escape_json_in_html } from '../../../utils/escape.js';
import { is_root_relative, resolve } from '../../../utils/url.js';
import { create_prerendering_url_proxy } from './utils.js';
import { is_pojo } from '../utils.js';
@@ -253,11 +253,21 @@ export async function load_node({
}
if (!opts.body || typeof opts.body === 'string') {
+ // the json constructed below is later added to the dom in a script tag
+ // make sure the used values are safe
+ const status_number = Number(response.status);
+ if (isNaN(status_number)) {
+ throw new Error(
+ `response.status is not a number. value: "${
+ response.status
+ }" type: ${typeof response.status}`
+ );
+ }
// prettier-ignore
fetched.push({
url: requested,
body: /** @type {string} */ (opts.body),
- json: `{"status":${response.status},"statusText":${s(response.statusText)},"headers":${s(headers)},"body":"${escape_json_value_in_html(body)}"}`
+ json: `{"status":${status_number},"statusText":${s(response.statusText)},"headers":${s(headers)},"body":${escape_json_in_html(body)}}`
});
}
diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js
index 67891e389f6c..361510bafeb7 100644
--- a/packages/kit/src/runtime/server/page/render.js
+++ b/packages/kit/src/runtime/server/page/render.js
@@ -261,7 +261,7 @@ export async function render_response({
if (shadow_props) {
// prettier-ignore
- body += ``;
+ body += ``;
}
}
diff --git a/packages/kit/src/utils/escape.js b/packages/kit/src/utils/escape.js
index 895c45570d26..c15a798d6e73 100644
--- a/packages/kit/src/utils/escape.js
+++ b/packages/kit/src/utils/escape.js
@@ -1,49 +1,26 @@
+// dict from https://github.com/yahoo/serialize-javascript/blob/183c18a776e4635a379fdc620f81771f219832bb/index.js#L25
/** @type {Record} */
const escape_json_in_html_dict = {
- '&': '\\u0026',
- '>': '\\u003e',
- '<': '\\u003c',
- '\u2028': '\\u2028',
- '\u2029': '\\u2029'
-};
-
-/** @type {Record} */
-const escape_json_value_in_html_dict = {
- '"': '\\"',
'<': '\\u003C',
'>': '\\u003E',
'/': '\\u002F',
- '\\': '\\\\',
- '\b': '\\b',
- '\f': '\\f',
- '\n': '\\n',
- '\r': '\\r',
- '\t': '\\t',
- '\0': '\\0',
'\u2028': '\\u2028',
'\u2029': '\\u2029'
};
-/**
- * Escape a stringified JSON object that's going to be embedded in a `