@rsvelte/vite-plugin-svelte-native 0.1.3 → 0.1.4
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 +71 -2
- package/package.json +6 -6
package/envelope.js
CHANGED
|
@@ -25,6 +25,27 @@ const WARN_HAS_START = 1 << 1;
|
|
|
25
25
|
const WARN_HAS_END = 1 << 2;
|
|
26
26
|
const WARN_HAS_FRAME = 1 << 3;
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* 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).
|
|
34
|
+
*
|
|
35
|
+
* @param {number} bufLen
|
|
36
|
+
* @param {number} off
|
|
37
|
+
* @param {number} len
|
|
38
|
+
* @param {string} label
|
|
39
|
+
*/
|
|
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
|
+
);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
28
49
|
/**
|
|
29
50
|
* Decode an envelope produced by `compileEnvelope` / `compileModuleEnvelope`.
|
|
30
51
|
*
|
|
@@ -71,10 +92,24 @@ function decodeEnvelope(buf) {
|
|
|
71
92
|
const cssMapLen = view.getUint32(44, true);
|
|
72
93
|
const warningsOff = view.getUint32(48, true);
|
|
73
94
|
const warningsCount = view.getUint32(52, true);
|
|
95
|
+
const warningsLen = view.getUint32(56, true);
|
|
74
96
|
|
|
75
97
|
const hasCss = (flags & FLAG_HAS_CSS) !== 0;
|
|
76
98
|
const runes = (flags & FLAG_RUNES) !== 0;
|
|
77
99
|
|
|
100
|
+
// Validate every field window up front so a malformed envelope throws
|
|
101
|
+
// at decode time rather than silently truncating on first lazy read.
|
|
102
|
+
// A zero offset marks an absent optional field (the header alone fills
|
|
103
|
+
// the first HEADER_LEN bytes, so real data never starts at offset 0).
|
|
104
|
+
const len = buf.byteLength;
|
|
105
|
+
assertWindow(len, jsCodeOff, jsCodeLen, 'js.code');
|
|
106
|
+
if (jsMapOff !== 0) assertWindow(len, jsMapOff, jsMapLen, 'js.map');
|
|
107
|
+
if (hasCss) {
|
|
108
|
+
assertWindow(len, cssCodeOff, cssCodeLen, 'css.code');
|
|
109
|
+
if (cssMapOff !== 0) assertWindow(len, cssMapOff, cssMapLen, 'css.map');
|
|
110
|
+
}
|
|
111
|
+
if (warningsCount > 0) assertWindow(len, warningsOff, warningsLen, 'warnings');
|
|
112
|
+
|
|
78
113
|
// `buf.toString('utf8', start, end)` is the V8 fast path for
|
|
79
114
|
// Buffer→string and is consistently faster than wrapping in a
|
|
80
115
|
// TextDecoder; fall back to TextDecoder for plain Uint8Array.
|
|
@@ -109,7 +144,7 @@ function decodeEnvelope(buf) {
|
|
|
109
144
|
configurable: true,
|
|
110
145
|
get() {
|
|
111
146
|
if (warningsCache === null) {
|
|
112
|
-
warningsCache = decodeWarnings(buf, view, warningsOff, warningsCount, slice);
|
|
147
|
+
warningsCache = decodeWarnings(buf, view, warningsOff, warningsLen, warningsCount, slice);
|
|
113
148
|
}
|
|
114
149
|
return warningsCache;
|
|
115
150
|
},
|
|
@@ -186,29 +221,50 @@ function makeCodeMapObject(buf, slice, codeOff, codeLen, mapOff, mapLen) {
|
|
|
186
221
|
return obj;
|
|
187
222
|
}
|
|
188
223
|
|
|
189
|
-
function decodeWarnings(buf, view, off, count, slice) {
|
|
224
|
+
function decodeWarnings(buf, view, off, regionLen, count, slice) {
|
|
225
|
+
// Every record field is bounds-checked against the warnings region
|
|
226
|
+
// (already validated to lie inside the buffer by the caller) so a
|
|
227
|
+
// corrupt internal length throws rather than reading adjacent bytes
|
|
228
|
+
// or overrunning the buffer.
|
|
229
|
+
const end = off + regionLen;
|
|
230
|
+
const need = (p, n, what) => {
|
|
231
|
+
if (p < off || p + n > end) {
|
|
232
|
+
throw new Error(
|
|
233
|
+
`[rsvelte] truncated warning ${what} at offset ${p} ` +
|
|
234
|
+
`(needs ${n} bytes, region ends at ${end})`,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
190
238
|
const out = new Array(count);
|
|
191
239
|
let p = off;
|
|
192
240
|
for (let i = 0; i < count; i++) {
|
|
241
|
+
need(p, 4, 'code length');
|
|
193
242
|
const codeLen = view.getUint32(p, true);
|
|
194
243
|
p += 4;
|
|
244
|
+
need(p, codeLen, 'code');
|
|
195
245
|
const code = slice(p, codeLen);
|
|
196
246
|
p += codeLen;
|
|
247
|
+
need(p, 4, 'message length');
|
|
197
248
|
const msgLen = view.getUint32(p, true);
|
|
198
249
|
p += 4;
|
|
250
|
+
need(p, msgLen, 'message');
|
|
199
251
|
const message = slice(p, msgLen);
|
|
200
252
|
p += msgLen;
|
|
253
|
+
need(p, 1, 'flags');
|
|
201
254
|
const flags = view.getUint8(p);
|
|
202
255
|
p += 1;
|
|
203
256
|
|
|
204
257
|
const w = { code, message };
|
|
205
258
|
if (flags & WARN_HAS_FILENAME) {
|
|
259
|
+
need(p, 4, 'filename length');
|
|
206
260
|
const len = view.getUint32(p, true);
|
|
207
261
|
p += 4;
|
|
262
|
+
need(p, len, 'filename');
|
|
208
263
|
w.filename = slice(p, len);
|
|
209
264
|
p += len;
|
|
210
265
|
}
|
|
211
266
|
if (flags & WARN_HAS_START) {
|
|
267
|
+
need(p, 12, 'start position');
|
|
212
268
|
w.start = {
|
|
213
269
|
line: view.getUint32(p, true),
|
|
214
270
|
column: view.getUint32(p + 4, true),
|
|
@@ -217,6 +273,7 @@ function decodeWarnings(buf, view, off, count, slice) {
|
|
|
217
273
|
p += 12;
|
|
218
274
|
}
|
|
219
275
|
if (flags & WARN_HAS_END) {
|
|
276
|
+
need(p, 12, 'end position');
|
|
220
277
|
w.end = {
|
|
221
278
|
line: view.getUint32(p, true),
|
|
222
279
|
column: view.getUint32(p + 4, true),
|
|
@@ -228,8 +285,10 @@ function decodeWarnings(buf, view, off, count, slice) {
|
|
|
228
285
|
w.position = [w.start.character, w.end.character];
|
|
229
286
|
}
|
|
230
287
|
if (flags & WARN_HAS_FRAME) {
|
|
288
|
+
need(p, 4, 'frame length');
|
|
231
289
|
const len = view.getUint32(p, true);
|
|
232
290
|
p += 4;
|
|
291
|
+
need(p, len, 'frame');
|
|
233
292
|
w.frame = slice(p, len);
|
|
234
293
|
p += len;
|
|
235
294
|
}
|
|
@@ -298,12 +357,22 @@ function decodeBatch(buf) {
|
|
|
298
357
|
}
|
|
299
358
|
const count = view.getUint32(12, true);
|
|
300
359
|
|
|
360
|
+
// The entry table must fit inside the buffer before we index into it.
|
|
361
|
+
const tableEnd = BATCH_HEADER_LEN + count * BATCH_ENTRY_LEN;
|
|
362
|
+
if (tableEnd > buf.byteLength) {
|
|
363
|
+
throw new Error(
|
|
364
|
+
`[rsvelte] batch entry table (${count} entries) exceeds buffer ` +
|
|
365
|
+
`(needs ${tableEnd} bytes, buffer is ${buf.byteLength})`,
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
|
|
301
369
|
const out = new Array(count);
|
|
302
370
|
for (let i = 0; i < count; i++) {
|
|
303
371
|
const entryOff = BATCH_HEADER_LEN + i * BATCH_ENTRY_LEN;
|
|
304
372
|
const status = view.getUint32(entryOff, true);
|
|
305
373
|
const payloadOff = view.getUint32(entryOff + 4, true);
|
|
306
374
|
const payloadLen = view.getUint32(entryOff + 8, true);
|
|
375
|
+
assertWindow(buf.byteLength, payloadOff, payloadLen, `batch entry ${i}`);
|
|
307
376
|
// Subarray gives a zero-copy view into the same underlying
|
|
308
377
|
// ArrayBuffer; `decodeEnvelope` walks it without further allocation.
|
|
309
378
|
const slice = buf.subarray
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rsvelte/vite-plugin-svelte-native",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "NAPI bindings to the rsvelte compiler — used by the @rsvelte vite-plugin-svelte shim",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
"index.d.ts"
|
|
28
28
|
],
|
|
29
29
|
"optionalDependencies": {
|
|
30
|
-
"@rsvelte/vite-plugin-svelte-native-darwin-arm64": "^0.1.
|
|
31
|
-
"@rsvelte/vite-plugin-svelte-native-darwin-x64": "^0.1.
|
|
32
|
-
"@rsvelte/vite-plugin-svelte-native-linux-arm64-gnu": "^0.1.
|
|
33
|
-
"@rsvelte/vite-plugin-svelte-native-linux-x64-gnu": "^0.1.
|
|
34
|
-
"@rsvelte/vite-plugin-svelte-native-win32-x64-msvc": "^0.1.
|
|
30
|
+
"@rsvelte/vite-plugin-svelte-native-darwin-arm64": "^0.1.4",
|
|
31
|
+
"@rsvelte/vite-plugin-svelte-native-darwin-x64": "^0.1.4",
|
|
32
|
+
"@rsvelte/vite-plugin-svelte-native-linux-arm64-gnu": "^0.1.4",
|
|
33
|
+
"@rsvelte/vite-plugin-svelte-native-linux-x64-gnu": "^0.1.4",
|
|
34
|
+
"@rsvelte/vite-plugin-svelte-native-win32-x64-msvc": "^0.1.4"
|
|
35
35
|
},
|
|
36
36
|
"publishConfig": {
|
|
37
37
|
"access": "public"
|