@lwrjs/shared-utils 0.23.4 → 0.23.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,6 +28,7 @@ __export(exports, {
28
28
  addToHead: () => addToHead,
29
29
  createHeadMarkup: () => createHeadMarkup,
30
30
  replaceStringFromLocation: () => replaceStringFromLocation,
31
+ serializeForScript: () => serializeForScript,
31
32
  serializeModuleToJson: () => serializeModuleToJson,
32
33
  shortestTtl: () => shortestTtl
33
34
  });
@@ -67,6 +68,16 @@ async function serializeModuleToJson(code = "", {
67
68
  code
68
69
  };
69
70
  }
71
+ var SCRIPT_UNSAFE_ESCAPES = {
72
+ 60: "\\u003c",
73
+ 62: "\\u003e",
74
+ 8232: "\\u2028",
75
+ 8233: "\\u2029"
76
+ };
77
+ var SCRIPT_UNSAFE_CHARS_RE = /[<>\u2028\u2029]/g;
78
+ function serializeForScript(value) {
79
+ return JSON.stringify(value).replace(SCRIPT_UNSAFE_CHARS_RE, (char) => SCRIPT_UNSAFE_ESCAPES[char.charCodeAt(0)]);
80
+ }
70
81
  function replaceStringFromLocation(src, {startOffset, endOffset}, replaceValue) {
71
82
  return src.substr(0, startOffset) + replaceValue + src.substr(endOffset, src.length);
72
83
  }
@@ -8,6 +8,22 @@ import type { HeadMarkup, LinkedModuleDefinition, LwrStringBuilder, ModuleJsonDe
8
8
  * @returns - Promise to the JSON serialization of the module
9
9
  */
10
10
  export declare function serializeModuleToJson(code: string | undefined, { specifier, version, ownHash, runtimeEnvironment, linkedConfig: { minified }, moduleRecord: { imports }, }: LinkedModuleDefinition, moduleRegistry: ModuleRegistry, runtimeParams: RuntimeParams): Promise<ModuleJsonDefinition>;
11
+ /**
12
+ * JSON-serialize a value for safe embedding inside an inline HTML `<script>`
13
+ * element. For data purposes this is equivalent to `JSON.stringify(value)` — the
14
+ * output parses back to the identical value — but a string value can never break
15
+ * out of the surrounding `<script>` block.
16
+ *
17
+ * `<`, `>`, U+2028 and U+2029 never appear as JSON structural syntax (only inside
18
+ * string values), so escaping them on the serialized output cannot corrupt the
19
+ * JSON structure. The JS parser decodes each `\uXXXX` escape back to the original
20
+ * character, so a client that `JSON.parse`s (or evaluates) the result receives a
21
+ * byte-for-byte identical value.
22
+ *
23
+ * @param value - the value to serialize
24
+ * @returns a JSON string safe to inline in a `<script>` element
25
+ */
26
+ export declare function serializeForScript(value: unknown): string;
11
27
  /**
12
28
  * Replace a part of a source string at the indices with a different value
13
29
  *
@@ -34,6 +34,46 @@ export async function serializeModuleToJson(code = '', { specifier, version, own
34
34
  code,
35
35
  };
36
36
  }
37
+ /**
38
+ * Character codes that are legal inside a JSON string literal but unsafe when
39
+ * that JSON is embedded verbatim in an inline HTML `<script>` element. Each maps
40
+ * to its equivalent JS `\uXXXX` escape.
41
+ *
42
+ * - U+003C `<` lets a value forge a `</script>` or `<!--` sequence and terminate
43
+ * the script element early, injecting arbitrary HTML (CWE-79).
44
+ * - U+003E `>` neutralizes `]]>` and HTML-comment close sequences (defense in depth).
45
+ * - U+2028 / U+2029 are treated as line terminators by the JS parser and break
46
+ * an inline script that contains them unescaped.
47
+ *
48
+ * Keyed by char code (and matched via `charCodeAt` below) so that no literal
49
+ * U+2028/U+2029 — invisible line terminators that would themselves break this
50
+ * source file — ever appears here.
51
+ */
52
+ const SCRIPT_UNSAFE_ESCAPES = {
53
+ 0x3c: '\\u003c',
54
+ 0x3e: '\\u003e',
55
+ 0x2028: '\\u2028',
56
+ 0x2029: '\\u2029',
57
+ };
58
+ const SCRIPT_UNSAFE_CHARS_RE = /[<>\u2028\u2029]/g;
59
+ /**
60
+ * JSON-serialize a value for safe embedding inside an inline HTML `<script>`
61
+ * element. For data purposes this is equivalent to `JSON.stringify(value)` — the
62
+ * output parses back to the identical value — but a string value can never break
63
+ * out of the surrounding `<script>` block.
64
+ *
65
+ * `<`, `>`, U+2028 and U+2029 never appear as JSON structural syntax (only inside
66
+ * string values), so escaping them on the serialized output cannot corrupt the
67
+ * JSON structure. The JS parser decodes each `\uXXXX` escape back to the original
68
+ * character, so a client that `JSON.parse`s (or evaluates) the result receives a
69
+ * byte-for-byte identical value.
70
+ *
71
+ * @param value - the value to serialize
72
+ * @returns a JSON string safe to inline in a `<script>` element
73
+ */
74
+ export function serializeForScript(value) {
75
+ return JSON.stringify(value).replace(SCRIPT_UNSAFE_CHARS_RE, (char) => SCRIPT_UNSAFE_ESCAPES[char.charCodeAt(0)]);
76
+ }
37
77
  /**
38
78
  * Replace a part of a source string at the indices with a different value
39
79
  *
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.23.4",
7
+ "version": "0.23.6",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -37,7 +37,7 @@
37
37
  "build/**/*.d.ts"
38
38
  ],
39
39
  "dependencies": {
40
- "@lwrjs/diagnostics": "0.23.4",
40
+ "@lwrjs/diagnostics": "0.23.6",
41
41
  "es-module-lexer": "^1.5.4",
42
42
  "fast-json-stable-stringify": "^2.1.0",
43
43
  "magic-string": "^0.30.9",
@@ -50,7 +50,7 @@
50
50
  "slugify": "^1.4.5"
51
51
  },
52
52
  "devDependencies": {
53
- "@lwrjs/types": "0.23.4",
53
+ "@lwrjs/types": "0.23.6",
54
54
  "@types/mime-types": "2.1.4",
55
55
  "@types/path-to-regexp": "^1.7.0",
56
56
  "memfs": "^4.13.0"
@@ -58,5 +58,5 @@
58
58
  "engines": {
59
59
  "node": ">=22.0.0"
60
60
  },
61
- "gitHead": "dedca0fa75a00da4cb52d49e4ed507b242fe0d63"
61
+ "gitHead": "39e89890152606679168b0e6beb972e0b1aa47ba"
62
62
  }