@rsvelte/vite-plugin-svelte-native 0.2.5 → 0.2.7

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.
package/envelope.js CHANGED
@@ -12,6 +12,8 @@
12
12
 
13
13
  'use strict';
14
14
 
15
+ const { isWindowOutOfBounds, windowOutOfBoundsMessage } = require('./lib/bounds-check.js');
16
+
15
17
  const MAGIC = 0x31565352; // "RSV1" little-endian
16
18
  const VERSION = 1;
17
19
  const HEADER_LEN = 60;
@@ -27,10 +29,8 @@ const WARN_HAS_FRAME = 1 << 3;
27
29
 
28
30
  /**
29
31
  * Validate that the byte window `[off, off + len)` lies fully inside a
30
- * buffer of `bufLen` bytes. The encoder writes offsets/lengths as u32s
31
- * the decoder otherwise trusts blindly — `buf.toString` / `subarray`
32
- * silently *clamp* an out-of-range window, so a malformed envelope would
33
- * decode to truncated data instead of failing loudly. Throw instead (M-012).
32
+ * buffer of `bufLen` bytes (see `./lib/bounds-check.js` for why this must
33
+ * throw rather than let `toString`/`subarray` clamp silently — M-012).
34
34
  *
35
35
  * @param {number} bufLen
36
36
  * @param {number} off
@@ -38,11 +38,8 @@ const WARN_HAS_FRAME = 1 << 3;
38
38
  * @param {string} label
39
39
  */
40
40
  function assertWindow(bufLen, off, len, label) {
41
- if (off < 0 || len < 0 || off + len > bufLen) {
42
- throw new Error(
43
- `[rsvelte] envelope ${label} out of bounds ` +
44
- `(offset ${off} + length ${len} exceeds buffer of ${bufLen} bytes)`,
45
- );
41
+ if (isWindowOutOfBounds(off, len, bufLen)) {
42
+ throw new Error(`[rsvelte] envelope ${windowOutOfBoundsMessage(label, off, len, bufLen)}`);
46
43
  }
47
44
  }
48
45
 
package/index.cjs CHANGED
@@ -137,6 +137,8 @@ module.exports.parseEnvelope = binding.parseEnvelope;
137
137
  module.exports.decodeParseEnvelope = decodeParseEnvelope;
138
138
  // Upstream Svelte version this binding emits code for — used by
139
139
  // downstream consumers (the `@rsvelte/vite-plugin-svelte` fork, etc.)
140
- // for `gte(VERSION, '5.36.0')`-style feature detection. Synced
141
- // manually against `submodules/svelte/packages/svelte/package.json`.
142
- module.exports.VERSION = '5.51.3';
140
+ // for `gte(VERSION, '5.36.0')`-style feature detection. Kept in sync
141
+ // with `submodules/svelte/packages/svelte/package.json` by hand; run
142
+ // `node scripts/dev/check-vps-version.mjs` (also wired into CI) to
143
+ // catch drift.
144
+ module.exports.VERSION = '5.56.4';
@@ -0,0 +1,38 @@
1
+ // Shared bounds-check primitive for the two raw-transfer envelope decoders
2
+ // (`../envelope.js` for `compileEnvelope`/`compileModuleEnvelope`, and
3
+ // `../parse-envelope.js` for `parseEnvelope`). Both wire formats encode
4
+ // offsets/lengths as u32s that the decoder otherwise trusts blindly —
5
+ // `Buffer.toString` / `Uint8Array.subarray` silently *clamp* an
6
+ // out-of-range window instead of throwing, so a malformed envelope would
7
+ // decode to truncated/misaligned data rather than failing loudly (M-012).
8
+ //
9
+ // Each decoder wraps this in its own `assertWindow` helper so it can throw
10
+ // its own Error subtype with its own message prefix (`[rsvelte] envelope …`
11
+ // vs `parse envelope: …`) while sharing the actual bounds arithmetic and
12
+ // message body.
13
+
14
+ 'use strict';
15
+
16
+ /**
17
+ * @param {number} off
18
+ * @param {number} len
19
+ * @param {number} bufLen
20
+ * @returns {boolean} true when the byte window `[off, off + len)` does NOT
21
+ * lie fully inside a buffer of `bufLen` bytes.
22
+ */
23
+ function isWindowOutOfBounds(off, len, bufLen) {
24
+ return off < 0 || len < 0 || off + len > bufLen;
25
+ }
26
+
27
+ /**
28
+ * @param {string} label
29
+ * @param {number} off
30
+ * @param {number} len
31
+ * @param {number} bufLen
32
+ * @returns {string}
33
+ */
34
+ function windowOutOfBoundsMessage(label, off, len, bufLen) {
35
+ return `${label} out of bounds (offset ${off} + length ${len} exceeds buffer of ${bufLen} bytes)`;
36
+ }
37
+
38
+ module.exports = { isWindowOutOfBounds, windowOutOfBoundsMessage };
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@rsvelte/vite-plugin-svelte-native",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "NAPI bindings to the rsvelte compiler — used by the @rsvelte vite-plugin-svelte shim",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/baseballyama/rsvelte.git",
9
- "directory": "apps/apps/npm/vite-plugin-svelte-native"
9
+ "directory": "apps/npm/vite-plugin-svelte-native"
10
10
  },
11
11
  "homepage": "https://github.com/baseballyama/rsvelte/tree/main/apps/npm/vite-plugin-svelte-native#readme",
12
12
  "bugs": {
@@ -24,15 +24,16 @@
24
24
  "files": [
25
25
  "envelope.js",
26
26
  "parse-envelope.js",
27
+ "lib/bounds-check.js",
27
28
  "index.cjs",
28
29
  "index.d.ts"
29
30
  ],
30
31
  "optionalDependencies": {
31
- "@rsvelte/vite-plugin-svelte-native-darwin-arm64": "^0.2.5",
32
- "@rsvelte/vite-plugin-svelte-native-darwin-x64": "^0.2.5",
33
- "@rsvelte/vite-plugin-svelte-native-linux-arm64-gnu": "^0.2.5",
34
- "@rsvelte/vite-plugin-svelte-native-linux-x64-gnu": "^0.2.5",
35
- "@rsvelte/vite-plugin-svelte-native-win32-x64-msvc": "^0.2.5"
32
+ "@rsvelte/vite-plugin-svelte-native-darwin-arm64": "^0.2.7",
33
+ "@rsvelte/vite-plugin-svelte-native-darwin-x64": "^0.2.7",
34
+ "@rsvelte/vite-plugin-svelte-native-linux-arm64-gnu": "^0.2.7",
35
+ "@rsvelte/vite-plugin-svelte-native-linux-x64-gnu": "^0.2.7",
36
+ "@rsvelte/vite-plugin-svelte-native-win32-x64-msvc": "^0.2.7"
36
37
  },
37
38
  "publishConfig": {
38
39
  "access": "public"
package/parse-envelope.js CHANGED
@@ -12,6 +12,8 @@
12
12
 
13
13
  'use strict';
14
14
 
15
+ const { isWindowOutOfBounds, windowOutOfBoundsMessage } = require('./lib/bounds-check.js');
16
+
15
17
  const MAGIC = 0x3156_5052; // "RPV1" little-endian
16
18
  const VERSION = 1;
17
19
  const HEADER_LEN = 24;
@@ -74,7 +76,7 @@ const TAG_AWAIT_BLOCK = 0x72;
74
76
  const TAG_KEY_BLOCK = 0x73;
75
77
  const TAG_SNIPPET_BLOCK = 0x74;
76
78
 
77
- // JsNode (estree) tags — 0x80..0xCB. Mirrors `napi_raw_parse.rs`.
79
+ // JsNode (estree) tags — 0x80..0xCC. Mirrors `napi_raw_parse.rs`.
78
80
  const JS_IDENTIFIER = 0x80;
79
81
  const JS_PRIVATE_IDENTIFIER = 0x81;
80
82
  const JS_LITERAL = 0x82;
@@ -150,7 +152,9 @@ const JS_TS_ENUM_DECLARATION = 0xc7;
150
152
  const JS_TS_MODULE_DECLARATION = 0xc8;
151
153
  const JS_COMMENT = 0xc9;
152
154
  const JS_NULL = 0xca;
153
- const JS_RAW_JSON = 0xcb;
155
+ // 0xcb was the former whole-node JS_RAW_JSON escape (removed — TS type
156
+ // annotations now ride a per-node trailer; see readOptTypeAnnotation).
157
+ const JS_TS_PARAMETER_PROPERTY = 0xcc;
154
158
 
155
159
  // LiteralValue inner tag (within a JS_LITERAL payload).
156
160
  const LV_NULL = 0;
@@ -253,10 +257,31 @@ function readU32(ctx) {
253
257
  function readBool(ctx) {
254
258
  return readU8(ctx) !== 0;
255
259
  }
260
+
261
+ /**
262
+ * Validate that the byte window `[start, start + len)` lies fully inside
263
+ * `ctx.bytes` (see `./lib/bounds-check.js`, shared with `envelope.js`'s
264
+ * `assertWindow`, for why this must throw rather than let
265
+ * `Buffer.toString`/`Uint8Array.subarray` clamp silently — M-012).
266
+ *
267
+ * @param {object} ctx
268
+ * @param {number} start
269
+ * @param {number} len
270
+ * @param {string} label
271
+ */
272
+ function assertWindow(ctx, start, len, label) {
273
+ if (isWindowOutOfBounds(start, len, ctx.bytes.byteLength)) {
274
+ throw new EnvelopeError(
275
+ `parse envelope: ${windowOutOfBoundsMessage(label, start, len, ctx.bytes.byteLength)}`,
276
+ );
277
+ }
278
+ }
279
+
256
280
  function readStr(ctx) {
257
281
  const len = readU32(ctx);
258
282
  const start = ctx.pos;
259
283
  const end = start + len;
284
+ assertWindow(ctx, start, len, 'string');
260
285
  ctx.pos = end;
261
286
  // Branch is monomorphic per envelope: V8 specialises after warmup.
262
287
  return ctx.isBuffer
@@ -287,6 +312,7 @@ function readInlineJson(ctx) {
287
312
  const len = readU32(ctx);
288
313
  const start = ctx.pos;
289
314
  const end = start + len;
315
+ assertWindow(ctx, start, len, 'inline JSON');
290
316
  ctx.pos = end;
291
317
  if (len === 0) return null;
292
318
  return JSON.parse(
@@ -301,6 +327,16 @@ function readJsonNodePayload(ctx) {
301
327
  return readInlineJson(ctx);
302
328
  }
303
329
 
330
+ /**
331
+ * Read an optional TS `typeAnnotation` trailer: a flag byte, then (when set) a
332
+ * length-prefixed JSON blob. Mirrors `write_opt_type_annotation` in
333
+ * `napi_raw_parse.rs`. Returns `null` when absent.
334
+ */
335
+ function readOptTypeAnnotation(ctx) {
336
+ if (readU8(ctx) === 0) return null;
337
+ return readInlineJson(ctx);
338
+ }
339
+
304
340
  // ---------------------------------------------------------------------------
305
341
  // Dispatch on tag
306
342
  // ---------------------------------------------------------------------------
@@ -397,8 +433,6 @@ function readNodeBody(ctx, tag, start, end) {
397
433
  // ----- JsNode (estree) ----------------------------------------
398
434
  case JS_NULL:
399
435
  return null;
400
- case JS_RAW_JSON:
401
- return readJsonNodePayload(ctx);
402
436
  case JS_IDENTIFIER:
403
437
  return readJsIdentifier(ctx, start, end);
404
438
  case JS_PRIVATE_IDENTIFIER:
@@ -543,6 +577,8 @@ function readNodeBody(ctx, tag, start, end) {
543
577
  return readJsTSTypeAnnotation(ctx, start, end);
544
578
  case JS_TS_ENUM_DECLARATION:
545
579
  return readJsBareExpr(ctx, 'TSEnumDeclaration', start, end);
580
+ case JS_TS_PARAMETER_PROPERTY:
581
+ return readJsBareExpr(ctx, 'TSParameterProperty', start, end);
546
582
  case JS_TS_MODULE_DECLARATION:
547
583
  return readJsTSModuleDeclaration(ctx, start, end);
548
584
  case JS_COMMENT:
@@ -650,6 +686,8 @@ function readJsIdentifier(ctx, start, end) {
650
686
  const node = { type: 'Identifier', start, end };
651
687
  if (loc !== null) node.loc = loc;
652
688
  node.name = name;
689
+ const typeAnnotation = readOptTypeAnnotation(ctx);
690
+ if (typeAnnotation !== null) node.typeAnnotation = typeAnnotation;
653
691
  return node;
654
692
  }
655
693
 
@@ -963,6 +1001,8 @@ function readJsObjectPattern(ctx, start, end) {
963
1001
  const node = { type: 'ObjectPattern', start, end };
964
1002
  if (loc !== null) node.loc = loc;
965
1003
  node.properties = properties;
1004
+ const typeAnnotation = readOptTypeAnnotation(ctx);
1005
+ if (typeAnnotation !== null) node.typeAnnotation = typeAnnotation;
966
1006
  return node;
967
1007
  }
968
1008
 
@@ -972,6 +1012,8 @@ function readJsArrayPattern(ctx, start, end) {
972
1012
  const node = { type: 'ArrayPattern', start, end };
973
1013
  if (loc !== null) node.loc = loc;
974
1014
  node.elements = elements;
1015
+ const typeAnnotation = readOptTypeAnnotation(ctx);
1016
+ if (typeAnnotation !== null) node.typeAnnotation = typeAnnotation;
975
1017
  return node;
976
1018
  }
977
1019