@ai-ecoverse/slicc-kernel 1.128.1 → 1.129.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 +8 -2
- package/dist/kernel-worker.js +262 -84
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +2 -1
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +274 -96
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +2 -1
- package/dist/process-worker.js.map +2 -2
- package/dist/testing.js +10 -1
- package/dist/testing.js.map +3 -3
- package/dist/types/kernel/children.d.ts +1 -0
- package/dist/types/kernel/net/sealed-http1.d.ts +4 -0
- package/dist/types/kernel/net/sealed-smtp.d.ts +15 -0
- package/dist/types/kernel/process.d.ts +1 -0
- package/dist/types/kernel/test-hooks.d.ts +7 -0
- package/dist/types/launcher.d.ts +3 -0
- package/dist/types/testing.d.ts +1 -0
- package/package.json +2 -2
package/dist/node.js
CHANGED
|
@@ -3821,14 +3821,14 @@ var Integrity = class {
|
|
|
3821
3821
|
if (!this.root.version) return void 0;
|
|
3822
3822
|
return `${real}\0${await this.root.version(real)}`;
|
|
3823
3823
|
}
|
|
3824
|
-
async read(path, caller,
|
|
3825
|
-
return (await this.readKeyed(path, caller,
|
|
3824
|
+
async read(path, caller, plain3, asked) {
|
|
3825
|
+
return (await this.readKeyed(path, caller, plain3, asked)).bytes;
|
|
3826
3826
|
}
|
|
3827
|
-
async readKeyed(path, caller,
|
|
3827
|
+
async readKeyed(path, caller, plain3, asked) {
|
|
3828
3828
|
const found = await this.real(path, asked);
|
|
3829
|
-
if (found === void 0) return { bytes: await
|
|
3829
|
+
if (found === void 0) return { bytes: await plain3() };
|
|
3830
3830
|
const { real, name: name2 } = found;
|
|
3831
|
-
const read = name2 !== real ? { bytes: await
|
|
3831
|
+
const read = name2 !== real ? { bytes: await plain3(), version: void 0 } : this.root.readVersioned ? await this.root.readVersioned(real) : { bytes: await this.root.readFileBuffer(real), version: void 0 };
|
|
3832
3832
|
const { bytes } = read;
|
|
3833
3833
|
const keyed = read.version === void 0 ? { bytes } : { bytes, key: `${real}\0${read.version}` };
|
|
3834
3834
|
await this.verify(name2, bytes, caller, EXEC_OPS);
|
|
@@ -3837,9 +3837,9 @@ var Integrity = class {
|
|
|
3837
3837
|
get readsChecked() {
|
|
3838
3838
|
return this.sources.length > 0;
|
|
3839
3839
|
}
|
|
3840
|
-
async readSource(path, caller,
|
|
3840
|
+
async readSource(path, caller, plain3) {
|
|
3841
3841
|
const found = await this.source(path);
|
|
3842
|
-
return found === void 0 ?
|
|
3842
|
+
return found === void 0 ? plain3() : this.checked(found, caller, plain3);
|
|
3843
3843
|
}
|
|
3844
3844
|
async openSource(path, caller, real) {
|
|
3845
3845
|
const found = await this.source(path, real);
|
|
@@ -3849,10 +3849,10 @@ var Integrity = class {
|
|
|
3849
3849
|
}
|
|
3850
3850
|
await this.checked(found, caller, () => this.root.readFileBuffer(found.real));
|
|
3851
3851
|
}
|
|
3852
|
-
async checked(found, caller,
|
|
3852
|
+
async checked(found, caller, plain3) {
|
|
3853
3853
|
const { real, name: name2 } = found;
|
|
3854
3854
|
if (name2 !== real || !this.root.readVersioned) {
|
|
3855
|
-
const bytes2 = await
|
|
3855
|
+
const bytes2 = await plain3();
|
|
3856
3856
|
await this.verify(name2, bytes2, caller, READ_OPS);
|
|
3857
3857
|
return bytes2;
|
|
3858
3858
|
}
|
|
@@ -6785,11 +6785,11 @@ function frame(opcode, payload) {
|
|
|
6785
6785
|
return out;
|
|
6786
6786
|
}
|
|
6787
6787
|
function clientFrame(opcode, payload) {
|
|
6788
|
-
const
|
|
6789
|
-
const head =
|
|
6788
|
+
const plain3 = frame(opcode, payload);
|
|
6789
|
+
const head = plain3.length - payload.length;
|
|
6790
6790
|
const mask = crypto.getRandomValues(new Uint8Array(4));
|
|
6791
|
-
const out = new Uint8Array(
|
|
6792
|
-
out.set(
|
|
6791
|
+
const out = new Uint8Array(plain3.length + 4);
|
|
6792
|
+
out.set(plain3.subarray(0, head));
|
|
6793
6793
|
out[1] = out[1] | 128;
|
|
6794
6794
|
out.set(mask, head);
|
|
6795
6795
|
for (let i = 0; i < payload.length; i++) {
|
|
@@ -7392,7 +7392,7 @@ function satisfies(version, range2) {
|
|
|
7392
7392
|
}
|
|
7393
7393
|
|
|
7394
7394
|
// src/version.ts
|
|
7395
|
-
var KERNEL_VERSION = true ? "1.
|
|
7395
|
+
var KERNEL_VERSION = true ? "1.129.0" : "0.0.0-dev";
|
|
7396
7396
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7397
7397
|
function procVersion() {
|
|
7398
7398
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -9785,8 +9785,9 @@ var FreshModules = class {
|
|
|
9785
9785
|
if (ranged2) {
|
|
9786
9786
|
overrides.pwrite = async (path, at, bytes, transfer) => {
|
|
9787
9787
|
const touches2 = at < MAGIC.length && this.fresh.has(normalizePath(path));
|
|
9788
|
+
const first = at === 0 && bytes.length >= MAGIC.length ? bytes.slice(0, MAGIC.length) : void 0;
|
|
9788
9789
|
await ranged2.pwrite(path, at, bytes, transfer);
|
|
9789
|
-
if (touches2) await decide(path);
|
|
9790
|
+
if (touches2) await decide(path, first);
|
|
9790
9791
|
};
|
|
9791
9792
|
overrides.truncate = async (path, size) => {
|
|
9792
9793
|
await ranged2.truncate(path, size);
|
|
@@ -12390,13 +12391,13 @@ async function chown(entry, path, req) {
|
|
|
12390
12391
|
}
|
|
12391
12392
|
async function runMkdir(entry, path, req) {
|
|
12392
12393
|
const { fs } = entry;
|
|
12393
|
-
const
|
|
12394
|
+
const plain3 = plainDirMode(entry, req.mode);
|
|
12394
12395
|
const parentsMode = !req.exclusive ? plainParentsMode(entry) : void 0;
|
|
12395
12396
|
const fixParents = parentsMode !== void 0 ? await missingParents(fs, path, parentsMode) : void 0;
|
|
12396
|
-
const fresh2 =
|
|
12397
|
+
const fresh2 = plain3 !== void 0 && !await fs.exists(path);
|
|
12397
12398
|
await (req.exclusive ? mkdirExclusive(entry, path, req.mode) : fs.mkdir(path, mkdirOptions(entry, req.mode)));
|
|
12398
12399
|
await fixParents?.();
|
|
12399
|
-
if (fresh2) await fs.chmod(path,
|
|
12400
|
+
if (fresh2) await fs.chmod(path, plain3);
|
|
12400
12401
|
return done;
|
|
12401
12402
|
}
|
|
12402
12403
|
async function shownAs(entry, path, st) {
|
|
@@ -12404,8 +12405,8 @@ async function shownAs(entry, path, st) {
|
|
|
12404
12405
|
return callerStat(guardOf(entry), await real?.catch(() => path) ?? path, st);
|
|
12405
12406
|
}
|
|
12406
12407
|
function readSource(entry, path) {
|
|
12407
|
-
const
|
|
12408
|
-
return entry.source ? entry.source.read(path,
|
|
12408
|
+
const plain3 = () => entry.fs.readFileBuffer(path);
|
|
12409
|
+
return entry.source ? entry.source.read(path, plain3) : plain3();
|
|
12409
12410
|
}
|
|
12410
12411
|
async function run(entry, path, req) {
|
|
12411
12412
|
const { fs, cwd } = entry;
|
|
@@ -18344,6 +18345,95 @@ async function substituteHead(head, ask) {
|
|
|
18344
18345
|
`, values };
|
|
18345
18346
|
}
|
|
18346
18347
|
|
|
18348
|
+
// src/kernel/net/sealed-smtp.ts
|
|
18349
|
+
var SMTP_LINE_MAX = 4096;
|
|
18350
|
+
var GREETING = ["EHLO ", "HELO "];
|
|
18351
|
+
function sniffSmtp(start2) {
|
|
18352
|
+
const upper = start2.toUpperCase();
|
|
18353
|
+
for (const word of GREETING) {
|
|
18354
|
+
if (upper.startsWith(word)) return "yes";
|
|
18355
|
+
if (word.startsWith(upper)) return "more";
|
|
18356
|
+
}
|
|
18357
|
+
return "no";
|
|
18358
|
+
}
|
|
18359
|
+
function decoded(b64) {
|
|
18360
|
+
if (!/^[A-Za-z0-9+/]+={0,2}$/.test(b64)) return void 0;
|
|
18361
|
+
try {
|
|
18362
|
+
return atob(b64);
|
|
18363
|
+
} catch {
|
|
18364
|
+
return void 0;
|
|
18365
|
+
}
|
|
18366
|
+
}
|
|
18367
|
+
async function swapped2(text, position, ask) {
|
|
18368
|
+
const placeholders = placeholdersIn(text);
|
|
18369
|
+
if (placeholders.length === 0 || placeholders.length > SESSION_PLACEHOLDERS) return void 0;
|
|
18370
|
+
const values = usable(await ask(position, placeholders));
|
|
18371
|
+
if (Object.keys(values).length === 0) return void 0;
|
|
18372
|
+
return { text: replaced(text, values), values };
|
|
18373
|
+
}
|
|
18374
|
+
async function plain2(b64, ask) {
|
|
18375
|
+
const text = decoded(b64);
|
|
18376
|
+
const fields = text?.split("\0");
|
|
18377
|
+
if (fields?.length !== 3) return { line: b64 };
|
|
18378
|
+
const [authz, user, pass2] = fields;
|
|
18379
|
+
if (placeholdersIn(authz + user).length > 0) return { line: b64 };
|
|
18380
|
+
const done4 = await swapped2(pass2, "auth-plain", ask);
|
|
18381
|
+
if (!done4) return { line: b64 };
|
|
18382
|
+
return { line: btoa(`${authz}\0${user}\0${done4.text}`), values: done4.values };
|
|
18383
|
+
}
|
|
18384
|
+
async function login(b64, ask) {
|
|
18385
|
+
const text = decoded(b64);
|
|
18386
|
+
const done4 = text === void 0 ? void 0 : await swapped2(text, "auth-login", ask);
|
|
18387
|
+
return done4 ? { line: btoa(done4.text), values: done4.values } : { line: b64 };
|
|
18388
|
+
}
|
|
18389
|
+
var SmtpClient = class {
|
|
18390
|
+
state = "command";
|
|
18391
|
+
ask;
|
|
18392
|
+
constructor(ask) {
|
|
18393
|
+
this.ask = ask;
|
|
18394
|
+
}
|
|
18395
|
+
get done() {
|
|
18396
|
+
return this.state === "done";
|
|
18397
|
+
}
|
|
18398
|
+
async line(text) {
|
|
18399
|
+
const state = this.state;
|
|
18400
|
+
if (state === "done") return { line: text };
|
|
18401
|
+
if (state === "plain" || state === "password") {
|
|
18402
|
+
this.state = "done";
|
|
18403
|
+
if (text === "*") return { line: text };
|
|
18404
|
+
return state === "plain" ? plain2(text, this.ask) : login(text, this.ask);
|
|
18405
|
+
}
|
|
18406
|
+
if (state === "user") {
|
|
18407
|
+
this.state = text === "*" ? "done" : "password";
|
|
18408
|
+
return { line: text };
|
|
18409
|
+
}
|
|
18410
|
+
return this.command(text);
|
|
18411
|
+
}
|
|
18412
|
+
async command(text) {
|
|
18413
|
+
const m = /^AUTH[ \t]+(PLAIN|LOGIN)(?:[ \t]+(\S+))?$/i.exec(text);
|
|
18414
|
+
if (!m) {
|
|
18415
|
+
if (/^(MAIL|RCPT|DATA|BDAT|AUTH)\b/i.test(text)) this.state = "done";
|
|
18416
|
+
return { line: text };
|
|
18417
|
+
}
|
|
18418
|
+
const mech = m[1].toUpperCase();
|
|
18419
|
+
const arg = m[2];
|
|
18420
|
+
if (mech === "LOGIN") {
|
|
18421
|
+
this.state = arg === void 0 ? "user" : "password";
|
|
18422
|
+
return { line: text };
|
|
18423
|
+
}
|
|
18424
|
+
if (arg === void 0) {
|
|
18425
|
+
this.state = "plain";
|
|
18426
|
+
return { line: text };
|
|
18427
|
+
}
|
|
18428
|
+
this.state = "done";
|
|
18429
|
+
const out = await plain2(arg, this.ask);
|
|
18430
|
+
return {
|
|
18431
|
+
line: `${text.slice(0, text.length - arg.length)}${out.line}`,
|
|
18432
|
+
...out.values ? { values: out.values } : {}
|
|
18433
|
+
};
|
|
18434
|
+
}
|
|
18435
|
+
};
|
|
18436
|
+
|
|
18347
18437
|
// src/kernel/net/sealed-conn.ts
|
|
18348
18438
|
var HEAD_IDLE_MS = 2e3;
|
|
18349
18439
|
function substitutes(s) {
|
|
@@ -18375,12 +18465,25 @@ function headEnd2(bytes) {
|
|
|
18375
18465
|
}
|
|
18376
18466
|
return -1;
|
|
18377
18467
|
}
|
|
18378
|
-
|
|
18468
|
+
function modeOf(start2) {
|
|
18469
|
+
const http = sniffHttp1(start2);
|
|
18470
|
+
const smtp = sniffSmtp(start2);
|
|
18471
|
+
if (http === "yes") return "http1";
|
|
18472
|
+
if (smtp === "yes") return "smtp";
|
|
18473
|
+
return http === "no" && smtp === "no" ? "pass" : void 0;
|
|
18474
|
+
}
|
|
18475
|
+
function crlf(bytes) {
|
|
18476
|
+
for (let i = 0; i + 1 < bytes.length; i++) if (bytes[i] === 13 && bytes[i + 1] === 10) return i;
|
|
18477
|
+
return -1;
|
|
18478
|
+
}
|
|
18479
|
+
var SessionWriter = class {
|
|
18379
18480
|
buffer = new Uint8Array(0);
|
|
18380
|
-
|
|
18481
|
+
mode = "sniff";
|
|
18381
18482
|
timer;
|
|
18382
18483
|
chain = Promise.resolve();
|
|
18383
18484
|
failed;
|
|
18485
|
+
session = sessionId();
|
|
18486
|
+
smtp;
|
|
18384
18487
|
conn;
|
|
18385
18488
|
s;
|
|
18386
18489
|
scope;
|
|
@@ -18388,6 +18491,9 @@ var Http1Writer = class {
|
|
|
18388
18491
|
this.conn = conn;
|
|
18389
18492
|
this.s = s;
|
|
18390
18493
|
this.scope = scope;
|
|
18494
|
+
this.smtp = new SmtpClient(
|
|
18495
|
+
(position, placeholders) => this.ask("smtp", position, placeholders)
|
|
18496
|
+
);
|
|
18391
18497
|
}
|
|
18392
18498
|
write(bytes) {
|
|
18393
18499
|
const run2 = this.chain.then(() => this.take(bytes));
|
|
@@ -18397,30 +18503,78 @@ var Http1Writer = class {
|
|
|
18397
18503
|
);
|
|
18398
18504
|
return run2;
|
|
18399
18505
|
}
|
|
18506
|
+
async ask(protocol, position, placeholders, head) {
|
|
18507
|
+
const s = this.s;
|
|
18508
|
+
const values = await s.broker.sessionMaterialize({
|
|
18509
|
+
stamp: await s.stamp(),
|
|
18510
|
+
session: this.session,
|
|
18511
|
+
host: s.host,
|
|
18512
|
+
port: s.port,
|
|
18513
|
+
protocol,
|
|
18514
|
+
position,
|
|
18515
|
+
verified: s.verified,
|
|
18516
|
+
handshakeAt: s.handshakeAt,
|
|
18517
|
+
exit: s.exit,
|
|
18518
|
+
placeholders,
|
|
18519
|
+
...head ? { head } : {}
|
|
18520
|
+
});
|
|
18521
|
+
return values;
|
|
18522
|
+
}
|
|
18523
|
+
remember(values) {
|
|
18524
|
+
this.scope.add(
|
|
18525
|
+
Object.entries(values).map(([placeholder, value2]) => ({ name: "sealed", value: value2, placeholder }))
|
|
18526
|
+
);
|
|
18527
|
+
}
|
|
18400
18528
|
async take(bytes) {
|
|
18401
18529
|
if (this.failed !== void 0) throw this.failed;
|
|
18402
|
-
if (this.
|
|
18530
|
+
if (this.mode === "pass") return this.conn.write(bytes);
|
|
18403
18531
|
clearTimeout(this.timer);
|
|
18404
18532
|
const joined4 = new Uint8Array(this.buffer.length + bytes.length);
|
|
18405
18533
|
joined4.set(this.buffer);
|
|
18406
18534
|
joined4.set(bytes, this.buffer.length);
|
|
18407
18535
|
this.buffer.fill(0);
|
|
18408
18536
|
this.buffer = joined4;
|
|
18409
|
-
|
|
18410
|
-
|
|
18411
|
-
if (
|
|
18412
|
-
|
|
18413
|
-
|
|
18414
|
-
|
|
18537
|
+
if (this.mode === "sniff") this.mode = modeOf(latin12(joined4.subarray(0, 8))) ?? "sniff";
|
|
18538
|
+
if (this.mode === "pass") await this.release();
|
|
18539
|
+
else if (this.mode === "http1") await this.http1();
|
|
18540
|
+
else if (this.mode === "smtp") await this.lines();
|
|
18541
|
+
if (this.mode !== "pass" && this.buffer.length > 0)
|
|
18542
|
+
this.timer = setTimeout(() => this.idle(), HEAD_IDLE_MS);
|
|
18415
18543
|
return bytes.length;
|
|
18416
18544
|
}
|
|
18545
|
+
async http1() {
|
|
18546
|
+
const end = headEnd2(this.buffer);
|
|
18547
|
+
if (end > HEAD_MAX || end < 0 && this.buffer.length > HEAD_MAX) await this.release();
|
|
18548
|
+
else if (end >= 0) await this.substitute(end);
|
|
18549
|
+
}
|
|
18550
|
+
async lines() {
|
|
18551
|
+
for (; ; ) {
|
|
18552
|
+
const at = crlf(this.buffer);
|
|
18553
|
+
if (at < 0) break;
|
|
18554
|
+
if (at > SMTP_LINE_MAX) return this.release();
|
|
18555
|
+
const all = this.buffer;
|
|
18556
|
+
this.buffer = all.slice(at + 2);
|
|
18557
|
+
const out = await this.smtp.line(latin12(all.subarray(0, at))).catch(() => ({ line: latin12(all.subarray(0, at)) }));
|
|
18558
|
+
all.fill(0);
|
|
18559
|
+
if ("values" in out && out.values) this.remember(out.values);
|
|
18560
|
+
const line = bytesOf(`${out.line}\r
|
|
18561
|
+
`);
|
|
18562
|
+
try {
|
|
18563
|
+
await writeAll4(this.conn, line);
|
|
18564
|
+
} finally {
|
|
18565
|
+
line.fill(0);
|
|
18566
|
+
}
|
|
18567
|
+
if (this.smtp.done) return this.release();
|
|
18568
|
+
}
|
|
18569
|
+
if (this.buffer.length > SMTP_LINE_MAX) await this.release();
|
|
18570
|
+
}
|
|
18417
18571
|
idle() {
|
|
18418
18572
|
this.chain = this.chain.then(() => this.release()).catch((err) => {
|
|
18419
18573
|
this.failed ??= err;
|
|
18420
18574
|
});
|
|
18421
18575
|
}
|
|
18422
18576
|
async release() {
|
|
18423
|
-
this.
|
|
18577
|
+
this.mode = "pass";
|
|
18424
18578
|
const out = this.buffer;
|
|
18425
18579
|
this.buffer = new Uint8Array(0);
|
|
18426
18580
|
try {
|
|
@@ -18430,37 +18584,15 @@ var Http1Writer = class {
|
|
|
18430
18584
|
}
|
|
18431
18585
|
}
|
|
18432
18586
|
async substitute(end) {
|
|
18433
|
-
this.
|
|
18587
|
+
this.mode = "pass";
|
|
18434
18588
|
const all = this.buffer;
|
|
18435
18589
|
this.buffer = new Uint8Array(0);
|
|
18436
|
-
const s = this.s;
|
|
18437
|
-
const session = sessionId();
|
|
18438
18590
|
const done4 = await substituteHead(
|
|
18439
18591
|
latin12(all.subarray(0, end)),
|
|
18440
|
-
|
|
18441
|
-
stamp: await s.stamp(),
|
|
18442
|
-
session,
|
|
18443
|
-
host: s.host,
|
|
18444
|
-
port: s.port,
|
|
18445
|
-
protocol: "http1",
|
|
18446
|
-
position,
|
|
18447
|
-
verified: s.verified,
|
|
18448
|
-
handshakeAt: s.handshakeAt,
|
|
18449
|
-
exit: s.exit,
|
|
18450
|
-
placeholders,
|
|
18451
|
-
head: head2
|
|
18452
|
-
})
|
|
18592
|
+
(position, placeholders, head2) => this.ask("http1", position, placeholders, head2)
|
|
18453
18593
|
).catch(() => void 0);
|
|
18454
18594
|
const head = done4 ? bytesOf(done4.head) : all.subarray(0, end);
|
|
18455
|
-
if (done4)
|
|
18456
|
-
this.scope.add(
|
|
18457
|
-
Object.entries(done4.values).map(([placeholder, value2]) => ({
|
|
18458
|
-
name: "sealed",
|
|
18459
|
-
value: value2,
|
|
18460
|
-
placeholder
|
|
18461
|
-
}))
|
|
18462
|
-
);
|
|
18463
|
-
}
|
|
18595
|
+
if (done4) this.remember(done4.values);
|
|
18464
18596
|
try {
|
|
18465
18597
|
await writeAll4(this.conn, head);
|
|
18466
18598
|
await writeAll4(this.conn, all.subarray(end));
|
|
@@ -18471,14 +18603,14 @@ var Http1Writer = class {
|
|
|
18471
18603
|
}
|
|
18472
18604
|
flushed() {
|
|
18473
18605
|
clearTimeout(this.timer);
|
|
18474
|
-
this.chain = this.chain.then(() => this.
|
|
18606
|
+
this.chain = this.chain.then(() => this.mode === "pass" ? void 0 : this.release());
|
|
18475
18607
|
return this.chain;
|
|
18476
18608
|
}
|
|
18477
18609
|
drop() {
|
|
18478
18610
|
clearTimeout(this.timer);
|
|
18479
18611
|
this.buffer.fill(0);
|
|
18480
18612
|
this.buffer = new Uint8Array(0);
|
|
18481
|
-
this.
|
|
18613
|
+
this.mode = "pass";
|
|
18482
18614
|
}
|
|
18483
18615
|
};
|
|
18484
18616
|
var IDLE2 = /* @__PURE__ */ Symbol("idle");
|
|
@@ -18489,11 +18621,9 @@ var ScrubReader = class {
|
|
|
18489
18621
|
held = false;
|
|
18490
18622
|
ended = false;
|
|
18491
18623
|
conn;
|
|
18492
|
-
s;
|
|
18493
18624
|
scope;
|
|
18494
|
-
constructor(conn,
|
|
18625
|
+
constructor(conn, scope) {
|
|
18495
18626
|
this.conn = conn;
|
|
18496
|
-
this.s = s;
|
|
18497
18627
|
this.scope = scope;
|
|
18498
18628
|
}
|
|
18499
18629
|
current() {
|
|
@@ -18552,8 +18682,8 @@ function idle() {
|
|
|
18552
18682
|
}
|
|
18553
18683
|
function sealedConn(conn, s) {
|
|
18554
18684
|
const scope = s.broker.sessions.scope(s.pid, s.host);
|
|
18555
|
-
const writer = substitutes(s) ? new
|
|
18556
|
-
const reader = new ScrubReader(conn,
|
|
18685
|
+
const writer = substitutes(s) ? new SessionWriter(conn, s, scope) : void 0;
|
|
18686
|
+
const reader = new ScrubReader(conn, scope);
|
|
18557
18687
|
return {
|
|
18558
18688
|
localAddr: conn.localAddr,
|
|
18559
18689
|
remoteAddr: conn.remoteAddr,
|
|
@@ -19679,6 +19809,12 @@ function tlsOverTransport(req, proc) {
|
|
|
19679
19809
|
return { fd: proc.fds.install(new OpenFile(mine), 3), alpnProtocol: "http/1.1", servername };
|
|
19680
19810
|
}
|
|
19681
19811
|
|
|
19812
|
+
// src/kernel/test-hooks.ts
|
|
19813
|
+
var SYSCALL_HOOK = /* @__PURE__ */ Symbol.for("slicc-kernel.test.syscall");
|
|
19814
|
+
function testSyscallHook() {
|
|
19815
|
+
return globalThis[SYSCALL_HOOK];
|
|
19816
|
+
}
|
|
19817
|
+
|
|
19682
19818
|
// src/kernel/vfs-file.ts
|
|
19683
19819
|
var O_ACCMODE = 3;
|
|
19684
19820
|
var O_WRONLY = 1;
|
|
@@ -20893,7 +21029,8 @@ var WasmProcess = class {
|
|
|
20893
21029
|
cwd,
|
|
20894
21030
|
...moved2,
|
|
20895
21031
|
...group,
|
|
20896
|
-
...exec ? { exec } : {}
|
|
21032
|
+
...exec ? { exec } : {},
|
|
21033
|
+
search: req.search
|
|
20897
21034
|
};
|
|
20898
21035
|
const pid = await this.children.spawn(spawned, stdio, inherit2);
|
|
20899
21036
|
if (deathSignal !== void 0) this.onDeath(pgid === 0 || session ? -pid : pid, deathSignal);
|
|
@@ -20979,6 +21116,8 @@ var WasmProcess = class {
|
|
|
20979
21116
|
return void 0;
|
|
20980
21117
|
}
|
|
20981
21118
|
async syscall(req, cancelled, block) {
|
|
21119
|
+
const hook = testSyscallHook();
|
|
21120
|
+
if (hook) await hook({ pid: this.pid, op: req.op });
|
|
20982
21121
|
this.options.onSyscall?.(req);
|
|
20983
21122
|
this.calls += 1;
|
|
20984
21123
|
const started = performance.now();
|
|
@@ -21276,18 +21415,18 @@ var WasmProcess = class {
|
|
|
21276
21415
|
}
|
|
21277
21416
|
if (this.writesAt(req) && this.options.readonlyAt?.(path)) throw new KernelError("EROFS");
|
|
21278
21417
|
const open = { ...req, path };
|
|
21279
|
-
const
|
|
21418
|
+
const plain3 = this.plainMode(req.mode);
|
|
21280
21419
|
if (req.exclusive) {
|
|
21281
21420
|
await nodes.createExclusive(path, this.newOwner(req.mode));
|
|
21282
|
-
if (
|
|
21421
|
+
if (plain3 !== void 0) await fs.chmod?.(path, plain3);
|
|
21283
21422
|
this.fds.installAt(fd, this.openVfsFile(open, void 0, fs));
|
|
21284
21423
|
} else if (req.create) {
|
|
21285
21424
|
await nodes.onEntry(path, async () => {
|
|
21286
|
-
const marks = this.options.owners ||
|
|
21425
|
+
const marks = this.options.owners || plain3 !== void 0;
|
|
21287
21426
|
const fresh2 = marks && !await present3(fs, path, true);
|
|
21288
21427
|
this.fds.installAt(fd, this.openVfsFile(open, await nodes.identify(path), fs));
|
|
21289
21428
|
await this.fds.get(fd).file.stat?.();
|
|
21290
|
-
if (fresh2 &&
|
|
21429
|
+
if (fresh2 && plain3 !== void 0) await fs.chmod?.(path, plain3);
|
|
21291
21430
|
else if (fresh2) {
|
|
21292
21431
|
await fs.chown?.(path, { ...this.newOwner(req.mode), kind: "new" });
|
|
21293
21432
|
}
|
|
@@ -23430,15 +23569,15 @@ function isRecord(value2) {
|
|
|
23430
23569
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
23431
23570
|
}
|
|
23432
23571
|
function serialized(reply) {
|
|
23433
|
-
let
|
|
23572
|
+
let plain3;
|
|
23434
23573
|
try {
|
|
23435
23574
|
const text = JSON.stringify(reply);
|
|
23436
|
-
|
|
23575
|
+
plain3 = text === void 0 ? void 0 : JSON.parse(text);
|
|
23437
23576
|
} catch (err) {
|
|
23438
23577
|
return JSON.stringify(errorReply("EIO", lineOf2(err)));
|
|
23439
23578
|
}
|
|
23440
|
-
if (!isRecord(
|
|
23441
|
-
const { v: _, ...rest2 } =
|
|
23579
|
+
if (!isRecord(plain3)) return JSON.stringify(errorReply("EIO", "the vault gave no reply"));
|
|
23580
|
+
const { v: _, ...rest2 } = plain3;
|
|
23442
23581
|
return JSON.stringify({ v: 1, ...rest2 });
|
|
23443
23582
|
}
|
|
23444
23583
|
function lineOf2(err) {
|
|
@@ -25472,13 +25611,13 @@ function splitWords(text) {
|
|
|
25472
25611
|
while (piece.lastIndex < text.length) {
|
|
25473
25612
|
const m = piece.exec(text);
|
|
25474
25613
|
if (!m) return void 0;
|
|
25475
|
-
const [, single, double, escaped,
|
|
25614
|
+
const [, single, double, escaped, plain3, space] = m;
|
|
25476
25615
|
if (space !== void 0) {
|
|
25477
25616
|
if (word !== void 0) words2.push(word);
|
|
25478
25617
|
word = void 0;
|
|
25479
25618
|
continue;
|
|
25480
25619
|
}
|
|
25481
|
-
word = (word ?? "") + (single ?? (double !== void 0 ? unescaped(double) : escaped ??
|
|
25620
|
+
word = (word ?? "") + (single ?? (double !== void 0 ? unescaped(double) : escaped ?? plain3));
|
|
25482
25621
|
}
|
|
25483
25622
|
if (word !== void 0) words2.push(word);
|
|
25484
25623
|
return words2;
|
|
@@ -26667,16 +26806,52 @@ var Launcher = class {
|
|
|
26667
26806
|
for (const bin of planned?.bins ?? []) await need(g, "exec", bin, R_OK | X_OK);
|
|
26668
26807
|
if (planned?.target.copy) await need(g, "exec", planned.target.copy, R_OK | X_OK);
|
|
26669
26808
|
}
|
|
26670
|
-
async checkedPlan(req,
|
|
26671
|
-
|
|
26809
|
+
async checkedPlan(req, ctx, fds) {
|
|
26810
|
+
try {
|
|
26811
|
+
return await this.planOrSearch(req, ctx);
|
|
26812
|
+
} catch (err) {
|
|
26672
26813
|
await fds.closeAll();
|
|
26673
|
-
throw err
|
|
26814
|
+
throw err;
|
|
26815
|
+
}
|
|
26816
|
+
}
|
|
26817
|
+
async planOrSearch(req, ctx) {
|
|
26818
|
+
const bare = !req.file.includes("/") && !COMMAND2.test(req.file);
|
|
26819
|
+
try {
|
|
26820
|
+
return await this.planOne(req, ctx);
|
|
26821
|
+
} catch (err) {
|
|
26822
|
+
const code = codeOf7(err);
|
|
26823
|
+
const searched = bare && req.search !== false && (code === "ENOENT" || code === "ENOEXEC");
|
|
26824
|
+
if (!searched || await this.commandAt(req.file, ctx.scope)) throw err;
|
|
26825
|
+
const found = await this.onPath(req, ctx);
|
|
26826
|
+
if (found) return found;
|
|
26827
|
+
throw err;
|
|
26828
|
+
}
|
|
26829
|
+
}
|
|
26830
|
+
async onPath(req, ctx) {
|
|
26831
|
+
const path = req.env.PATH;
|
|
26832
|
+
if (typeof path !== "string") return void 0;
|
|
26833
|
+
let denied2 = false;
|
|
26834
|
+
for (const dir of path.split(":")) {
|
|
26835
|
+
const file = dir === "" ? `./${req.file}` : `${dir.replace(/\/+$/, "")}/${req.file}`;
|
|
26836
|
+
try {
|
|
26837
|
+
return await this.planOne({ ...req, file }, ctx);
|
|
26838
|
+
} catch (err) {
|
|
26839
|
+
const code = codeOf7(err);
|
|
26840
|
+
if (code === "EACCES") denied2 = true;
|
|
26841
|
+
else if (code !== "ENOENT" && code !== "ENOTDIR") throw err;
|
|
26842
|
+
}
|
|
26843
|
+
}
|
|
26844
|
+
if (denied2) throw new SpawnError("EACCES");
|
|
26845
|
+
return void 0;
|
|
26846
|
+
}
|
|
26847
|
+
async planOne(req, { ppid, cred, scope }) {
|
|
26848
|
+
const refused3 = (err) => {
|
|
26849
|
+
throw codeOf7(err) === "EACCES" ? new SpawnError("EACCES") : err;
|
|
26674
26850
|
};
|
|
26675
26851
|
const file = await this.execFile(req.file, req.cwd, this.execGuard(cred, ppid)).catch(refused3);
|
|
26676
26852
|
const planned = await this.plan(file, req.argv, req.cwd, scope, req.argv0);
|
|
26677
26853
|
await this.mayExec(cred, { ...req, file, pid: ppid }, planned).catch(refused3);
|
|
26678
26854
|
if (planned) return planned;
|
|
26679
|
-
await fds.closeAll();
|
|
26680
26855
|
throw new SpawnError(await this.unrunnable(file, req.cwd, scope));
|
|
26681
26856
|
}
|
|
26682
26857
|
async enterable(g, cwd) {
|
|
@@ -26843,12 +27018,12 @@ var Launcher = class {
|
|
|
26843
27018
|
return `${path}:${st.size}:${st.mtime.getTime()}`;
|
|
26844
27019
|
}
|
|
26845
27020
|
verified(path, caller, fs = this.base) {
|
|
26846
|
-
const
|
|
26847
|
-
return this.integrity ? this.integrity.read(path, caller,
|
|
27021
|
+
const plain3 = () => fs.readFileBuffer(path);
|
|
27022
|
+
return this.integrity ? this.integrity.read(path, caller, plain3) : plain3();
|
|
26848
27023
|
}
|
|
26849
27024
|
keyed(path, caller, asked) {
|
|
26850
|
-
const
|
|
26851
|
-
return this.integrity ? this.integrity.readKeyed(path, caller,
|
|
27025
|
+
const plain3 = async () => this.base.readFileBuffer(path);
|
|
27026
|
+
return this.integrity ? this.integrity.readKeyed(path, caller, plain3, asked) : plain3().then((bytes) => ({ bytes }));
|
|
26852
27027
|
}
|
|
26853
27028
|
cached(cache, key, load) {
|
|
26854
27029
|
const hit = cache.get(key);
|
|
@@ -27045,7 +27220,7 @@ var Launcher = class {
|
|
|
27045
27220
|
});
|
|
27046
27221
|
return {
|
|
27047
27222
|
source: {
|
|
27048
|
-
read: (path,
|
|
27223
|
+
read: (path, plain3) => integrity.readSource(path, caller(), plain3),
|
|
27049
27224
|
open: (path, real) => integrity.openSource(path, caller(), real)
|
|
27050
27225
|
}
|
|
27051
27226
|
};
|
|
@@ -27952,9 +28127,9 @@ var Launcher = class {
|
|
|
27952
28127
|
}
|
|
27953
28128
|
);
|
|
27954
28129
|
}
|
|
27955
|
-
environment(cwd, extra, account,
|
|
28130
|
+
environment(cwd, extra, account, login2 = false) {
|
|
27956
28131
|
const env = {
|
|
27957
|
-
...
|
|
28132
|
+
...login2 ? networkEnv(this.hostname) : this.env,
|
|
27958
28133
|
...userEnv(account, this.pnpmHome),
|
|
27959
28134
|
PWD: cwd,
|
|
27960
28135
|
...extra
|
|
@@ -28181,6 +28356,9 @@ var Launcher = class {
|
|
|
28181
28356
|
function cronLocks() {
|
|
28182
28357
|
return globalThis.navigator?.locks;
|
|
28183
28358
|
}
|
|
28359
|
+
function codeOf7(err) {
|
|
28360
|
+
return err?.code;
|
|
28361
|
+
}
|
|
28184
28362
|
|
|
28185
28363
|
// src/node/loopback.ts
|
|
28186
28364
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -28197,11 +28375,11 @@ function ipv4Place(address) {
|
|
|
28197
28375
|
return void 0;
|
|
28198
28376
|
}
|
|
28199
28377
|
function placeOf(address) {
|
|
28200
|
-
const
|
|
28201
|
-
const kind = isIP3(
|
|
28202
|
-
if (kind === 4) return ipv4Place(
|
|
28378
|
+
const plain3 = address.replace(/^\[(.*)\]$/, "$1").toLowerCase();
|
|
28379
|
+
const kind = isIP3(plain3);
|
|
28380
|
+
if (kind === 4) return ipv4Place(plain3);
|
|
28203
28381
|
if (kind !== 6) return void 0;
|
|
28204
|
-
const words2 = hextets2(
|
|
28382
|
+
const words2 = hextets2(plain3);
|
|
28205
28383
|
const embedded2 = words2.slice(0, 5).every((w) => w === 0) && (words2[5] === 65535 || words2[5] === 0);
|
|
28206
28384
|
if (embedded2 && (words2[5] === 65535 || words2[6] !== 0)) return ipv4Place(ipv4Of(words2));
|
|
28207
28385
|
if (words2.slice(0, 7).every((w) => w === 0) && (words2[7] ?? 0) <= 1) return "loopback";
|
|
@@ -28250,10 +28428,10 @@ function connectRefusal(address, port, place) {
|
|
|
28250
28428
|
return Object.assign(new Error(why), { status: 403, code: "EACCES" });
|
|
28251
28429
|
}
|
|
28252
28430
|
async function addressesOf(host, resolve2) {
|
|
28253
|
-
const
|
|
28254
|
-
if (isIP3(
|
|
28255
|
-
if (loopbackName2(
|
|
28256
|
-
return resolve2(
|
|
28431
|
+
const plain3 = host.replace(/^\[(.*)\]$/, "$1");
|
|
28432
|
+
if (isIP3(plain3)) return [plain3];
|
|
28433
|
+
if (loopbackName2(plain3)) return ["127.0.0.1"];
|
|
28434
|
+
return resolve2(plain3).catch(() => []);
|
|
28257
28435
|
}
|
|
28258
28436
|
async function checkDestination(target, policy, resolve2 = resolveHost) {
|
|
28259
28437
|
const url = new URL(target);
|
|
@@ -28591,7 +28769,7 @@ import { connect as tls } from "node:tls";
|
|
|
28591
28769
|
var PROBE_MS = 3e3;
|
|
28592
28770
|
var PASSED = /* @__PURE__ */ new Set(["ECONNREFUSED", "EHOSTUNREACH", "ENETUNREACH", "ETIMEDOUT", "ECONNRESET"]);
|
|
28593
28771
|
var NO_NAME = /* @__PURE__ */ new Set(["ENOTFOUND", "EAI_AGAIN", "EAI_NONAME", "EAI_FAIL", "ENODATA"]);
|
|
28594
|
-
function
|
|
28772
|
+
function codeOf8(e) {
|
|
28595
28773
|
const code = e?.code;
|
|
28596
28774
|
return typeof code === "string" ? code : void 0;
|
|
28597
28775
|
}
|
|
@@ -28620,7 +28798,7 @@ function probe(secure2, host, port, ms, signal) {
|
|
|
28620
28798
|
signal?.addEventListener("abort", stop, { once: true });
|
|
28621
28799
|
socket.once(secure2 ? "secureConnect" : "connect", () => done4("EPROTO"));
|
|
28622
28800
|
socket.once("error", (e) => {
|
|
28623
|
-
const code =
|
|
28801
|
+
const code = codeOf8(e) ?? "";
|
|
28624
28802
|
done4(PASSED.has(code) ? code : "EPROTO");
|
|
28625
28803
|
});
|
|
28626
28804
|
});
|
|
@@ -28635,7 +28813,7 @@ async function diagnose(url, ms = PROBE_MS, signal) {
|
|
|
28635
28813
|
await abortable(lookup3(host), signal);
|
|
28636
28814
|
} catch (e) {
|
|
28637
28815
|
if (signal?.aborted) throw signal.reason;
|
|
28638
|
-
return NO_NAME.has(
|
|
28816
|
+
return NO_NAME.has(codeOf8(e) ?? "") ? "EAI_NONAME" : void 0;
|
|
28639
28817
|
}
|
|
28640
28818
|
const code = await probe(secure2, host, port, ms, signal);
|
|
28641
28819
|
signal?.throwIfAborted();
|
|
@@ -28654,7 +28832,7 @@ function diagnosing(transport, check = byDefault) {
|
|
|
28654
28832
|
try {
|
|
28655
28833
|
return await open(request);
|
|
28656
28834
|
} catch (e) {
|
|
28657
|
-
if (request.signal.aborted || !(e instanceof Error) ||
|
|
28835
|
+
if (request.signal.aborted || !(e instanceof Error) || codeOf8(e)) throw e;
|
|
28658
28836
|
const code = await abortable(
|
|
28659
28837
|
check(request.url, request.signal).catch(() => void 0),
|
|
28660
28838
|
request.signal
|