sandboxedjs 0.1.67 → 0.1.69
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/index.cjs +189 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +189 -6
- package/dist/index.js.map +1 -1
- package/dist/python/python.data +270 -273
- package/dist/python/python.js +1 -1
- package/dist/python/python.wasm +0 -0
- package/dist/python/runtime.json +3 -3
- package/dist/python-abi.cjs +45 -1
- package/dist/python-abi.cjs.map +1 -1
- package/dist/python-abi.d.cts +34 -0
- package/dist/python-abi.d.ts +34 -0
- package/dist/python-abi.js +45 -1
- package/dist/python-abi.js.map +1 -1
- package/dist/python-worker.js +13 -1
- package/dist/python-worker.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -506,6 +506,9 @@ function normalizeSignal(spec) {
|
|
|
506
506
|
const withPrefix = upper.startsWith("SIG") ? upper : "SIG" + upper;
|
|
507
507
|
return withPrefix in exports.SIGNALS ? withPrefix : null;
|
|
508
508
|
}
|
|
509
|
+
function signalNumber(name) {
|
|
510
|
+
return exports.SIGNALS[name] ?? 0;
|
|
511
|
+
}
|
|
509
512
|
function exitCodeForSignal(sig) {
|
|
510
513
|
return 128 + (exports.SIGNALS[sig] ?? 0);
|
|
511
514
|
}
|
|
@@ -17817,7 +17820,10 @@ var Op = {
|
|
|
17817
17820
|
getpeername: 1801,
|
|
17818
17821
|
setsockopt: 1802,
|
|
17819
17822
|
getsockopt: 1803,
|
|
17820
|
-
socket_close: 1804
|
|
17823
|
+
socket_close: 1804,
|
|
17824
|
+
spawn: 2048,
|
|
17825
|
+
waitpid: 2049,
|
|
17826
|
+
kill: 2050
|
|
17821
17827
|
};
|
|
17822
17828
|
var Errno = {
|
|
17823
17829
|
EPERM: 1,
|
|
@@ -17828,6 +17834,7 @@ var Errno = {
|
|
|
17828
17834
|
ENXIO: 6,
|
|
17829
17835
|
E2BIG: 7,
|
|
17830
17836
|
EBADF: 9,
|
|
17837
|
+
ECHILD: 10,
|
|
17831
17838
|
EAGAIN: 11,
|
|
17832
17839
|
ENOMEM: 12,
|
|
17833
17840
|
EACCES: 13,
|
|
@@ -17963,7 +17970,7 @@ var wheels_default = {
|
|
|
17963
17970
|
|
|
17964
17971
|
// package.json
|
|
17965
17972
|
var package_default = {
|
|
17966
|
-
version: "0.1.
|
|
17973
|
+
version: "0.1.69"};
|
|
17967
17974
|
|
|
17968
17975
|
// src/runtime/python/config.ts
|
|
17969
17976
|
var bundledManifest = {
|
|
@@ -18508,6 +18515,9 @@ function toPosixError(error) {
|
|
|
18508
18515
|
};
|
|
18509
18516
|
return new PosixError(code && mapped[code] ? mapped[code] : Errno.EIO, message);
|
|
18510
18517
|
}
|
|
18518
|
+
|
|
18519
|
+
// src/runtime/python/backend.ts
|
|
18520
|
+
init_signals();
|
|
18511
18521
|
var DescriptorTable = class _DescriptorTable {
|
|
18512
18522
|
slots = /* @__PURE__ */ new Map();
|
|
18513
18523
|
/** Descriptions this table shares with others, so close counts correctly. */
|
|
@@ -19401,6 +19411,46 @@ function createHostAbiServer(proc) {
|
|
|
19401
19411
|
const joined = Object.entries(proc.env).map(([key, value]) => `${key}=${value}`).join("\0");
|
|
19402
19412
|
return { status: 0, payload: new Writer().string(joined).finish() };
|
|
19403
19413
|
}
|
|
19414
|
+
/* --------------------------------------------------------- processes */
|
|
19415
|
+
case Op.spawn: {
|
|
19416
|
+
const argv = [];
|
|
19417
|
+
for (let i = 0, n = r.u32(); i < n; i++) argv.push(r.string());
|
|
19418
|
+
const env2 = {};
|
|
19419
|
+
for (let i = 0, n = r.u32(); i < n; i++) {
|
|
19420
|
+
const entry = r.string();
|
|
19421
|
+
const split2 = entry.indexOf("=");
|
|
19422
|
+
if (split2 > 0) env2[entry.slice(0, split2)] = entry.slice(split2 + 1);
|
|
19423
|
+
}
|
|
19424
|
+
const cwd = r.string() || proc.cwd;
|
|
19425
|
+
const files2 = /* @__PURE__ */ new Map();
|
|
19426
|
+
for (let i = 0, n = r.u32(); i < n; i++) {
|
|
19427
|
+
const childFd = r.u32() | 0;
|
|
19428
|
+
const parentFd = r.u32() | 0;
|
|
19429
|
+
files2.set(childFd, proc.table.get(parentFd));
|
|
19430
|
+
}
|
|
19431
|
+
if (!proc.processes) throw new PosixError(Errno.ENOSYS);
|
|
19432
|
+
if (argv.length === 0) throw new PosixError(Errno.EINVAL);
|
|
19433
|
+
return { status: await proc.processes.spawn({ argv, env: env2, cwd: resolve3(cwd), files: files2 }) };
|
|
19434
|
+
}
|
|
19435
|
+
case Op.waitpid: {
|
|
19436
|
+
const pid = r.u32() | 0;
|
|
19437
|
+
const options = r.u32() | 0;
|
|
19438
|
+
if (!proc.processes) throw new PosixError(Errno.ENOSYS);
|
|
19439
|
+
const result = await Promise.race([
|
|
19440
|
+
proc.processes.wait(pid, options),
|
|
19441
|
+
aborted().then(() => {
|
|
19442
|
+
throw new PosixError(Errno.EINTR);
|
|
19443
|
+
})
|
|
19444
|
+
]);
|
|
19445
|
+
return { status: 0, payload: new Writer().i32(result.pid).i32(result.status).finish() };
|
|
19446
|
+
}
|
|
19447
|
+
case Op.kill: {
|
|
19448
|
+
const pid = r.u32() | 0;
|
|
19449
|
+
const signal = r.u32() | 0;
|
|
19450
|
+
if (!proc.processes) throw new PosixError(Errno.ENOSYS);
|
|
19451
|
+
proc.processes.kill(pid, signal);
|
|
19452
|
+
return { status: 0 };
|
|
19453
|
+
}
|
|
19404
19454
|
/* ---------------------------------------------------------- entropy */
|
|
19405
19455
|
case Op.getrandom: {
|
|
19406
19456
|
const length = Math.min(r.u32(), 65536);
|
|
@@ -19754,6 +19804,7 @@ async function startPythonProcess(options) {
|
|
|
19754
19804
|
table.set(0, stdin);
|
|
19755
19805
|
table.set(1, stdout);
|
|
19756
19806
|
table.set(2, stderr);
|
|
19807
|
+
for (const [fd, description] of options.inherit ?? []) table.set(fd, description);
|
|
19757
19808
|
const controller = new AbortController();
|
|
19758
19809
|
const abort = () => controller.abort();
|
|
19759
19810
|
options.signal.addEventListener("abort", abort, { once: true });
|
|
@@ -19767,7 +19818,8 @@ async function startPythonProcess(options) {
|
|
|
19767
19818
|
env: options.env,
|
|
19768
19819
|
cwd: options.cwd,
|
|
19769
19820
|
signal: controller.signal,
|
|
19770
|
-
sockets: options.sockets
|
|
19821
|
+
sockets: options.sockets,
|
|
19822
|
+
processes: options.processes
|
|
19771
19823
|
});
|
|
19772
19824
|
const buffers = createHostTransportBuffers();
|
|
19773
19825
|
let fault = null;
|
|
@@ -19832,7 +19884,11 @@ async function startPythonProcess(options) {
|
|
|
19832
19884
|
pid: options.pid,
|
|
19833
19885
|
ppid: options.ppid,
|
|
19834
19886
|
mounts: options.mounts,
|
|
19835
|
-
isTty: options.isTty
|
|
19887
|
+
isTty: options.isTty,
|
|
19888
|
+
/* Only beyond the standard three: 0, 1 and 2 are bound as the process's
|
|
19889
|
+
* terminal-or-pipe streams by the worker itself, and installing a second
|
|
19890
|
+
* stream over one of them would leave two objects claiming the number. */
|
|
19891
|
+
inheritFds: [...options.inherit?.keys() ?? []].filter((fd) => fd > 2)
|
|
19836
19892
|
});
|
|
19837
19893
|
return {
|
|
19838
19894
|
write: (data) => stdin.push(data),
|
|
@@ -20320,6 +20376,129 @@ raise SystemExit(entry())
|
|
|
20320
20376
|
}
|
|
20321
20377
|
|
|
20322
20378
|
// src/runtime/python/backend.ts
|
|
20379
|
+
var PENDING_INHERITANCE = /* @__PURE__ */ new Map();
|
|
20380
|
+
var INHERIT_TOKEN = "SBX_PYTHON_INHERIT";
|
|
20381
|
+
var WNOHANG = 1;
|
|
20382
|
+
function claimInheritance(env2) {
|
|
20383
|
+
const token = env2[INHERIT_TOKEN];
|
|
20384
|
+
if (!token) return void 0;
|
|
20385
|
+
const files = PENDING_INHERITANCE.get(token);
|
|
20386
|
+
PENDING_INHERITANCE.delete(token);
|
|
20387
|
+
delete env2[INHERIT_TOKEN];
|
|
20388
|
+
return files;
|
|
20389
|
+
}
|
|
20390
|
+
function waitStatus(proc) {
|
|
20391
|
+
if (proc.termSignal) return signalNumber(proc.termSignal) & 127;
|
|
20392
|
+
return ((proc.exitCode ?? 0) & 255) << 8;
|
|
20393
|
+
}
|
|
20394
|
+
function outputFor(description, fallback) {
|
|
20395
|
+
if (!description) return fallback;
|
|
20396
|
+
return {
|
|
20397
|
+
write(data) {
|
|
20398
|
+
description.write(typeof data === "string" ? new TextEncoder().encode(data) : data);
|
|
20399
|
+
},
|
|
20400
|
+
end() {
|
|
20401
|
+
},
|
|
20402
|
+
get closed() {
|
|
20403
|
+
return false;
|
|
20404
|
+
},
|
|
20405
|
+
isTTY: fallback.isTTY
|
|
20406
|
+
};
|
|
20407
|
+
}
|
|
20408
|
+
function createProcessService(ctx) {
|
|
20409
|
+
const children = /* @__PURE__ */ new Map();
|
|
20410
|
+
const exited = (proc) => proc.exitCode !== null || proc.termSignal !== null;
|
|
20411
|
+
return {
|
|
20412
|
+
async spawn(request) {
|
|
20413
|
+
const token = `${ctx.proc.pid}:${Math.random().toString(36).slice(2)}`;
|
|
20414
|
+
const env2 = { ...request.env };
|
|
20415
|
+
if (request.files.size > 0) {
|
|
20416
|
+
PENDING_INHERITANCE.set(token, new Map(request.files));
|
|
20417
|
+
env2[INHERIT_TOKEN] = token;
|
|
20418
|
+
}
|
|
20419
|
+
const stdin = request.files.get(0);
|
|
20420
|
+
const argv = [containerProgram(ctx, request.argv[0] ?? ""), ...request.argv.slice(1)];
|
|
20421
|
+
const proc = ctx.kernel.spawn(argv, {
|
|
20422
|
+
cwd: request.cwd,
|
|
20423
|
+
env: env2,
|
|
20424
|
+
cred: ctx.cred,
|
|
20425
|
+
ppid: ctx.proc.pid,
|
|
20426
|
+
stdin: stdin ? descriptionInput(stdin) : void 0,
|
|
20427
|
+
stdout: outputFor(request.files.get(1), ctx.stdout),
|
|
20428
|
+
stderr: outputFor(request.files.get(2), ctx.stderr)
|
|
20429
|
+
});
|
|
20430
|
+
children.set(proc.pid, proc);
|
|
20431
|
+
void proc.wait().finally(() => PENDING_INHERITANCE.delete(token));
|
|
20432
|
+
return proc.pid;
|
|
20433
|
+
},
|
|
20434
|
+
async wait(pid, options) {
|
|
20435
|
+
const candidates = pid > 0 ? [children.get(pid)].filter((p) => p !== void 0) : [...children.values()];
|
|
20436
|
+
if (candidates.length === 0) throw new PosixError(Errno.ECHILD);
|
|
20437
|
+
const reap = (proc) => {
|
|
20438
|
+
children.delete(proc.pid);
|
|
20439
|
+
return { pid: proc.pid, status: waitStatus(proc) };
|
|
20440
|
+
};
|
|
20441
|
+
const done = candidates.find(exited);
|
|
20442
|
+
if (done) return reap(done);
|
|
20443
|
+
if (options & WNOHANG) return { pid: 0, status: 0 };
|
|
20444
|
+
await Promise.race(candidates.map((proc) => proc.wait()));
|
|
20445
|
+
const finished = candidates.find(exited);
|
|
20446
|
+
if (!finished) throw new PosixError(Errno.ECHILD);
|
|
20447
|
+
return reap(finished);
|
|
20448
|
+
},
|
|
20449
|
+
kill(pid, signal) {
|
|
20450
|
+
const proc = children.get(pid) ?? ctx.kernel.procs.get(pid);
|
|
20451
|
+
if (!proc) throw new PosixError(Errno.ESRCH);
|
|
20452
|
+
if (signal === 0) return;
|
|
20453
|
+
const name = exports.SIGNAL_NAMES[signal];
|
|
20454
|
+
if (!name) throw new PosixError(Errno.EINVAL);
|
|
20455
|
+
proc.deliver(name);
|
|
20456
|
+
}
|
|
20457
|
+
};
|
|
20458
|
+
}
|
|
20459
|
+
function containerProgram(ctx, program) {
|
|
20460
|
+
const resolvable = (name) => name !== "" && ctx.kernel.resolveExecutable(name, ctx.cwd, ctx.env, ctx.cred) !== null;
|
|
20461
|
+
if (resolvable(program)) return program;
|
|
20462
|
+
const base2 = program.slice(program.lastIndexOf("/") + 1);
|
|
20463
|
+
if (resolvable(base2)) return base2;
|
|
20464
|
+
if (base2.startsWith("python")) return "python3";
|
|
20465
|
+
return program;
|
|
20466
|
+
}
|
|
20467
|
+
function descriptionInput(description) {
|
|
20468
|
+
const read = async (size) => {
|
|
20469
|
+
for (; ; ) {
|
|
20470
|
+
try {
|
|
20471
|
+
const chunk = description.read(size);
|
|
20472
|
+
if (chunk.length === 0) return null;
|
|
20473
|
+
return chunk;
|
|
20474
|
+
} catch {
|
|
20475
|
+
await description.whenReady();
|
|
20476
|
+
}
|
|
20477
|
+
}
|
|
20478
|
+
};
|
|
20479
|
+
return {
|
|
20480
|
+
isTTY: false,
|
|
20481
|
+
interactive: false,
|
|
20482
|
+
read,
|
|
20483
|
+
async readAll() {
|
|
20484
|
+
const parts = [];
|
|
20485
|
+
for (; ; ) {
|
|
20486
|
+
const chunk = await read(65536);
|
|
20487
|
+
if (chunk === null) break;
|
|
20488
|
+
parts.push(chunk);
|
|
20489
|
+
}
|
|
20490
|
+
let total = 0;
|
|
20491
|
+
for (const part of parts) total += part.length;
|
|
20492
|
+
const out = new Uint8Array(total);
|
|
20493
|
+
let at = 0;
|
|
20494
|
+
for (const part of parts) {
|
|
20495
|
+
out.set(part, at);
|
|
20496
|
+
at += part.length;
|
|
20497
|
+
}
|
|
20498
|
+
return out;
|
|
20499
|
+
}
|
|
20500
|
+
};
|
|
20501
|
+
}
|
|
20323
20502
|
function withSitePackages(env2) {
|
|
20324
20503
|
const existing = env2.PYTHONPATH;
|
|
20325
20504
|
return {
|
|
@@ -20360,6 +20539,8 @@ async function runOwnedPython(ctx, argv) {
|
|
|
20360
20539
|
const { manifest, workerUrl } = pythonBackend();
|
|
20361
20540
|
if (!manifest) throw new Error("no Python runtime manifest is configured");
|
|
20362
20541
|
const mounts = containerMounts(ctx);
|
|
20542
|
+
const env2 = withSitePackages(ctx.env);
|
|
20543
|
+
const inherit = claimInheritance(env2);
|
|
20363
20544
|
const process2 = await startPythonProcess({
|
|
20364
20545
|
manifest,
|
|
20365
20546
|
workerUrl: await resolveWorkerUrl(workerUrl),
|
|
@@ -20368,14 +20549,16 @@ async function runOwnedPython(ctx, argv) {
|
|
|
20368
20549
|
pid: ctx.proc.pid,
|
|
20369
20550
|
ppid: ctx.proc.ppid ?? 1,
|
|
20370
20551
|
argv,
|
|
20371
|
-
env:
|
|
20552
|
+
env: env2,
|
|
20372
20553
|
cwd: ctx.cwd,
|
|
20373
20554
|
isTty: isTerminal(ctx),
|
|
20374
20555
|
mounts,
|
|
20375
20556
|
onStdout: (data) => ctx.stdout.write(data),
|
|
20376
20557
|
onStderr: (data) => ctx.stderr.write(data),
|
|
20377
20558
|
signal: ctx.signal,
|
|
20378
|
-
sockets: ctx.kernel.pod.sockets
|
|
20559
|
+
sockets: ctx.kernel.pod.sockets,
|
|
20560
|
+
processes: createProcessService(ctx),
|
|
20561
|
+
inherit
|
|
20379
20562
|
});
|
|
20380
20563
|
void pumpStdin(ctx, process2);
|
|
20381
20564
|
return process2.wait();
|