From 0c6bc25f6f2ef3bad181ac116ed90143e4038ab6 Mon Sep 17 00:00:00 2001 From: Dominik G Date: Sun, 13 Feb 2022 18:21:49 +0100 Subject: [PATCH] refactor: simplify escape_json_in_html util (#3804) --- .changeset/metal-moons-provide.md | 5 +++ .../kit/src/runtime/server/page/load_node.js | 14 +++++- .../kit/src/runtime/server/page/render.js | 2 +- packages/kit/src/utils/escape.js | 45 +++++-------------- 4 files changed, 29 insertions(+), 37 deletions(-) create mode 100644 .changeset/metal-moons-provide.md 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 994dac98cdfa..b0067cf655e6 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, lowercase_keys } from '../utils.js'; @@ -251,11 +251,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 `