@ai-ecoverse/slicc-kernel 1.52.0 → 1.53.0

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/README.md CHANGED
@@ -234,7 +234,7 @@ The module's default export (or its `main` export) is called with a context and
234
234
 
235
235
  A program that throws, or leaves an error or a rejected promise unhandled with no listener for it, ends with status 1 and the message on stderr; one whose module cannot be loaded, or exports no function, ends with 126. A write to a pipe whose reader is gone ends the program with 141, unless it ignores or catches `SIGPIPE` (an ignore inherited from its parent counts), in which case the write fails with `EPIPE`. Errors carry a POSIX `code`. Reads and writes of pipes, terminals and sockets go through the kernel's asynchronous operations, so a program blocked reading stdin can still write and handle signals; other calls of one process are made one at a time. A JS program cannot `fork`, and threads it starts itself are not the kernel's.
236
236
 
237
- The module has the trust of an Emscripten program's glue or a WASI program's imports module: it comes from a package that was installed, and it runs in the worker of its own process. The kernel withholds the worker's own ways out before it loads the module: `fetch`, `XMLHttpRequest`, `WebSocket`, `WebTransport`, `EventSource`, `importScripts`, `indexedDB`, `caches`, `cookieStore`, `Worker`, `SharedWorker`, `BroadcastChannel`, `postMessage`, `close`, and `navigator.storage`, `navigator.locks` and `navigator.serviceWorker` are `undefined`, and a worker where one of them cannot be removed refuses to run the program (126). A program's files are the kernel's, through the context; it reaches the kernel only through its own process's system calls, as the context makes them, and no other process's. This is a guard against programs going around the kernel, not a sandbox: `import()` of a URL is a request the kernel cannot withhold.
237
+ The module has the trust of an Emscripten program's glue or a WASI program's imports module: it comes from a package that was installed, and it runs in the worker of its own process. The kernel withholds the worker's own ways out before it loads the module: `XMLHttpRequest`, `WebSocketStream`, `WebTransport`, `EventSource`, `importScripts`, `indexedDB`, `caches`, `cookieStore`, `Worker`, `SharedWorker`, `BroadcastChannel`, `postMessage`, `close`, and `navigator.storage`, `navigator.locks` and `navigator.serviceWorker` are `undefined`, and a worker where one of them cannot be removed refuses to run the program (126). `fetch` and `WebSocket` are `undefined` too, but stay writable and configurable, so a program can install its own over `ctx.fetch` and `ctx.websocket` (as slicc-jsh does). A program's files are the kernel's, through the context; it reaches the kernel only through its own process's system calls, as the context makes them, and no other process's. This is a guard against programs going around the kernel, not a sandbox: `import()` of a URL is a request the kernel cannot withhold.
238
238
 
239
239
  Under the Node entry, the kernel also withholds the host's Node from the program before its module loads ([#297](https://github.com/ai-ecoverse/slicc-kernel/issues/297)). `require`, `module`, `exports`, `__filename`, `__dirname`, `localStorage` and `sessionStorage` are `undefined` for good. `process`, `global`, `setImmediate` and `clearImmediate` are `undefined` too, but stay writable, so a program can install its own (as slicc-jsh does). `Buffer` stays Node's own, since Node's `Response`, `Request`, `Blob` and stream bodies read it when they run; it reaches nothing outside the program, and a program can replace it. Imports of Node's builtin modules (`node:fs`, `fs`, `node:worker_threads`, …) and of anything but a `data:` URL, `file:` included, fail with `ERR_ACCESS_DENIED`, whether static, dynamic or through `import.meta.resolve`. A process worker that exits or crashes on its own ends its process with 70. This is the same guard, not a sandbox: a host that runs code it does not trust, such as an agent's, needs its own isolation around the Node process as well.
240
240
 
@@ -42,19 +42,35 @@ function hide(target, names) {
42
42
  }
43
43
  }
44
44
  }
45
+ function vacate(target, names) {
46
+ for (const name2 of names) {
47
+ for (let at = target; at && at !== Object.prototype; ) {
48
+ if (Object.getOwnPropertyDescriptor(at, name2)?.configurable) Reflect.deleteProperty(at, name2);
49
+ at = Object.getPrototypeOf(at);
50
+ }
51
+ Reflect.defineProperty(target, name2, {
52
+ value: void 0,
53
+ writable: true,
54
+ enumerable: false,
55
+ configurable: true
56
+ });
57
+ if (Reflect.get(target, name2) !== void 0) {
58
+ throw new Error(`slicc-kernel: cannot withhold ${name2} from a JS program`);
59
+ }
60
+ }
61
+ }
45
62
  function lockdown(scope2 = globalThis) {
46
63
  hide(scope2, BLOCKED_GLOBALS);
64
+ vacate(scope2, OPEN_SLOTS);
47
65
  const navigator = scope2.navigator;
48
66
  if (navigator && typeof navigator === "object") hide(navigator, BLOCKED_NAVIGATOR);
49
67
  }
50
- var BLOCKED_GLOBALS, BLOCKED_NAVIGATOR;
68
+ var BLOCKED_GLOBALS, BLOCKED_NAVIGATOR, OPEN_SLOTS;
51
69
  var init_lockdown = __esm({
52
70
  "src/process/js/lockdown.ts"() {
53
71
  "use strict";
54
72
  BLOCKED_GLOBALS = [
55
- "fetch",
56
73
  "XMLHttpRequest",
57
- "WebSocket",
58
74
  "WebSocketStream",
59
75
  "WebTransport",
60
76
  "EventSource",
@@ -69,6 +85,7 @@ var init_lockdown = __esm({
69
85
  "close"
70
86
  ];
71
87
  BLOCKED_NAVIGATOR = ["storage", "locks", "serviceWorker"];
88
+ OPEN_SLOTS = ["fetch", "WebSocket"];
72
89
  }
73
90
  });
74
91
 
@@ -11302,23 +11319,6 @@ var NODE_SLOTS = [
11302
11319
  "setImmediate",
11303
11320
  "clearImmediate"
11304
11321
  ];
11305
- function vacate(target, names) {
11306
- for (const name2 of names) {
11307
- for (let at = target; at && at !== Object.prototype; ) {
11308
- if (Object.getOwnPropertyDescriptor(at, name2)?.configurable) Reflect.deleteProperty(at, name2);
11309
- at = Object.getPrototypeOf(at);
11310
- }
11311
- Reflect.defineProperty(target, name2, {
11312
- value: void 0,
11313
- writable: true,
11314
- enumerable: false,
11315
- configurable: true
11316
- });
11317
- if (Reflect.get(target, name2) !== void 0) {
11318
- throw new Error(`slicc-kernel: cannot withhold ${name2} from a JS program`);
11319
- }
11320
- }
11321
- }
11322
11322
  function refused(specifier) {
11323
11323
  return Object.assign(new Error(`slicc-kernel: a JS program cannot import ${specifier}`), {
11324
11324
  code: "ERR_ACCESS_DENIED"