@secure-exec/core 0.1.1-rc.2 → 0.1.1-rc.3
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/dist/bridge/child-process.js +22 -8
- package/dist/bridge/fs.js +29 -25
- package/dist/bridge/module.js +12 -3
- package/dist/bridge/network.d.ts +101 -1
- package/dist/bridge/network.js +629 -12
- package/dist/bridge/process.js +46 -25
- package/dist/bridge.js +795 -65
- package/dist/generated/isolate-runtime.d.ts +5 -5
- package/dist/generated/isolate-runtime.js +5 -5
- package/dist/index.d.ts +1 -1
- package/dist/isolate-runtime/apply-timing-mitigation-freeze.js +8 -6
- package/dist/isolate-runtime/bridge-initial-globals.js +4 -143
- package/dist/isolate-runtime/require-setup.js +960 -5
- package/dist/isolate-runtime/setup-dynamic-import.js +5 -1
- package/dist/isolate-runtime/setup-fs-facade.js +21 -60
- package/dist/shared/bridge-contract.d.ts +220 -94
- package/dist/shared/bridge-contract.js +31 -3
- package/dist/shared/console-formatter.js +4 -4
- package/dist/shared/global-exposure.js +95 -0
- package/dist/shared/permissions.js +16 -0
- package/dist/types.d.ts +42 -1
- package/package.json +1 -1
package/dist/bridge/process.js
CHANGED
|
@@ -40,8 +40,8 @@ function getNowMs() {
|
|
|
40
40
|
? performance.now()
|
|
41
41
|
: Date.now();
|
|
42
42
|
}
|
|
43
|
-
// Start time for uptime calculation
|
|
44
|
-
|
|
43
|
+
// Start time for uptime calculation
|
|
44
|
+
const _processStartTime = getNowMs();
|
|
45
45
|
const BUFFER_MAX_LENGTH = typeof BufferPolyfill.kMaxLength ===
|
|
46
46
|
"number"
|
|
47
47
|
? BufferPolyfill.kMaxLength
|
|
@@ -71,18 +71,6 @@ if (typeof bufferPolyfillMutable.constants !== "object" ||
|
|
|
71
71
|
// Exit code tracking
|
|
72
72
|
let _exitCode = 0;
|
|
73
73
|
let _exited = false;
|
|
74
|
-
// Expose reset function for snapshot restore — resets mutable state
|
|
75
|
-
// captured in this closure so each restored context starts fresh.
|
|
76
|
-
globalThis.__runtimeResetProcessState =
|
|
77
|
-
function () {
|
|
78
|
-
_processStartTime =
|
|
79
|
-
typeof performance !== "undefined" && performance.now
|
|
80
|
-
? performance.now()
|
|
81
|
-
: Date.now();
|
|
82
|
-
_exitCode = 0;
|
|
83
|
-
_exited = false;
|
|
84
|
-
delete globalThis.__runtimeResetProcessState;
|
|
85
|
-
};
|
|
86
74
|
/**
|
|
87
75
|
* Thrown by `process.exit()` to unwind the sandbox call stack. The host
|
|
88
76
|
* catches this to extract the exit code without killing the isolate.
|
|
@@ -134,7 +122,7 @@ function _addListener(event, listener, once = false) {
|
|
|
134
122
|
const warning = `MaxListenersExceededWarning: Possible EventEmitter memory leak detected. ${total} ${event} listeners added to [process]. MaxListeners is ${_processMaxListeners}. Use emitter.setMaxListeners() to increase limit`;
|
|
135
123
|
// Use console.error to emit warning without recursion risk
|
|
136
124
|
if (typeof _error !== "undefined") {
|
|
137
|
-
_error(warning);
|
|
125
|
+
_error.applySync(undefined, [warning]);
|
|
138
126
|
}
|
|
139
127
|
}
|
|
140
128
|
}
|
|
@@ -181,7 +169,7 @@ const _stderrIsTTY = (typeof _processConfig !== "undefined" && _processConfig.st
|
|
|
181
169
|
const _stdout = {
|
|
182
170
|
write(data) {
|
|
183
171
|
if (typeof _log !== "undefined") {
|
|
184
|
-
_log(String(data).replace(/\n$/, ""));
|
|
172
|
+
_log.applySync(undefined, [String(data).replace(/\n$/, "")]);
|
|
185
173
|
}
|
|
186
174
|
return true;
|
|
187
175
|
},
|
|
@@ -206,7 +194,7 @@ const _stdout = {
|
|
|
206
194
|
const _stderr = {
|
|
207
195
|
write(data) {
|
|
208
196
|
if (typeof _error !== "undefined") {
|
|
209
|
-
_error(String(data).replace(/\n$/, ""));
|
|
197
|
+
_error.applySync(undefined, [String(data).replace(/\n$/, "")]);
|
|
210
198
|
}
|
|
211
199
|
return true;
|
|
212
200
|
},
|
|
@@ -340,7 +328,7 @@ const _stdin = {
|
|
|
340
328
|
throw new Error("setRawMode is not supported when stdin is not a TTY");
|
|
341
329
|
}
|
|
342
330
|
if (typeof _ptySetRawMode !== "undefined") {
|
|
343
|
-
_ptySetRawMode(mode);
|
|
331
|
+
_ptySetRawMode.applySync(undefined, [mode]);
|
|
344
332
|
}
|
|
345
333
|
return this;
|
|
346
334
|
},
|
|
@@ -444,9 +432,9 @@ const process = {
|
|
|
444
432
|
},
|
|
445
433
|
chdir(dir) {
|
|
446
434
|
// Validate directory exists in VFS before setting cwd
|
|
447
|
-
let
|
|
435
|
+
let statJson;
|
|
448
436
|
try {
|
|
449
|
-
|
|
437
|
+
statJson = _fs.stat.applySyncPromise(undefined, [dir]);
|
|
450
438
|
}
|
|
451
439
|
catch {
|
|
452
440
|
const err = new Error(`ENOENT: no such file or directory, chdir '${dir}'`);
|
|
@@ -456,7 +444,8 @@ const process = {
|
|
|
456
444
|
err.path = dir;
|
|
457
445
|
throw err;
|
|
458
446
|
}
|
|
459
|
-
|
|
447
|
+
const parsed = JSON.parse(statJson);
|
|
448
|
+
if (!parsed.isDirectory) {
|
|
460
449
|
const err = new Error(`ENOTDIR: not a directory, chdir '${dir}'`);
|
|
461
450
|
err.code = "ENOTDIR";
|
|
462
451
|
err.errno = -20;
|
|
@@ -714,6 +703,13 @@ process.memoryUsage.rss =
|
|
|
714
703
|
function () {
|
|
715
704
|
return 50 * 1024 * 1024;
|
|
716
705
|
};
|
|
706
|
+
// Match Node.js Object.prototype.toString.call(process) === '[object process]'
|
|
707
|
+
Object.defineProperty(process, Symbol.toStringTag, {
|
|
708
|
+
value: "process",
|
|
709
|
+
writable: false,
|
|
710
|
+
configurable: true,
|
|
711
|
+
enumerable: false,
|
|
712
|
+
});
|
|
717
713
|
export default process;
|
|
718
714
|
// ============================================================================
|
|
719
715
|
// Global polyfills
|
|
@@ -770,7 +766,11 @@ export function setTimeout(callback, delay, ...args) {
|
|
|
770
766
|
const actualDelay = delay ?? 0;
|
|
771
767
|
// Use host timer for actual delays if available and delay > 0
|
|
772
768
|
if (typeof _scheduleTimer !== "undefined" && actualDelay > 0) {
|
|
773
|
-
_scheduleTimer(
|
|
769
|
+
// _scheduleTimer.apply() returns a Promise that resolves after the delay
|
|
770
|
+
// Using { result: { promise: true } } tells isolated-vm to wait for the
|
|
771
|
+
// host Promise to resolve before resolving the apply() Promise
|
|
772
|
+
_scheduleTimer
|
|
773
|
+
.apply(undefined, [actualDelay], { result: { promise: true } })
|
|
774
774
|
.then(() => {
|
|
775
775
|
if (_timers.has(id)) {
|
|
776
776
|
_timers.delete(id);
|
|
@@ -818,7 +818,8 @@ export function setInterval(callback, delay, ...args) {
|
|
|
818
818
|
return; // Interval was cleared
|
|
819
819
|
if (typeof _scheduleTimer !== "undefined" && actualDelay > 0) {
|
|
820
820
|
// Use host timer for actual delays
|
|
821
|
-
_scheduleTimer
|
|
821
|
+
_scheduleTimer
|
|
822
|
+
.apply(undefined, [actualDelay], { result: { promise: true } })
|
|
822
823
|
.then(() => {
|
|
823
824
|
if (_intervals.has(id)) {
|
|
824
825
|
try {
|
|
@@ -871,6 +872,25 @@ export const URLSearchParams = WhatwgURLSearchParams;
|
|
|
871
872
|
export { TextEncoder, TextDecoder };
|
|
872
873
|
// Buffer - use buffer package polyfill
|
|
873
874
|
export const Buffer = BufferPolyfill;
|
|
875
|
+
// Patch internal V8 Buffer slice/write methods used by native-protocol libraries
|
|
876
|
+
// (ssh2, msgpack, protobuf, etc.). The polyfill supports these encodings through
|
|
877
|
+
// toString()/write() but doesn't expose the fast-path internal methods.
|
|
878
|
+
const bp = BufferPolyfill.prototype;
|
|
879
|
+
const sliceEncodings = ["utf8", "ascii", "latin1", "binary", "hex", "base64", "ucs2", "utf16le"];
|
|
880
|
+
for (const enc of sliceEncodings) {
|
|
881
|
+
const sliceKey = `${enc}Slice`;
|
|
882
|
+
if (typeof bp[sliceKey] !== "function") {
|
|
883
|
+
bp[sliceKey] = function (start, end) {
|
|
884
|
+
return this.toString(enc, start, end);
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
const writeKey = `${enc}Write`;
|
|
888
|
+
if (typeof bp[writeKey] !== "function") {
|
|
889
|
+
bp[writeKey] = function (str, offset, length) {
|
|
890
|
+
return this.write(str, offset, length, enc);
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
}
|
|
874
894
|
function throwUnsupportedCryptoApi(api) {
|
|
875
895
|
throw new Error(`crypto.${api} is not supported in sandbox`);
|
|
876
896
|
}
|
|
@@ -890,7 +910,8 @@ export const cryptoPolyfill = {
|
|
|
890
910
|
}
|
|
891
911
|
const bytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
|
|
892
912
|
try {
|
|
893
|
-
const
|
|
913
|
+
const base64 = _cryptoRandomFill.applySync(undefined, [bytes.byteLength]);
|
|
914
|
+
const hostBytes = BufferPolyfill.from(base64, "base64");
|
|
894
915
|
if (hostBytes.byteLength !== bytes.byteLength) {
|
|
895
916
|
throw new Error("invalid host entropy size");
|
|
896
917
|
}
|
|
@@ -906,7 +927,7 @@ export const cryptoPolyfill = {
|
|
|
906
927
|
throwUnsupportedCryptoApi("randomUUID");
|
|
907
928
|
}
|
|
908
929
|
try {
|
|
909
|
-
const uuid = _cryptoRandomUUID();
|
|
930
|
+
const uuid = _cryptoRandomUUID.applySync(undefined, []);
|
|
910
931
|
if (typeof uuid !== "string") {
|
|
911
932
|
throw new Error("invalid host uuid");
|
|
912
933
|
}
|