@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/kernel-worker.js
CHANGED
|
@@ -544,14 +544,14 @@ var Integrity = class {
|
|
|
544
544
|
if (!this.root.version) return void 0;
|
|
545
545
|
return `${real}\0${await this.root.version(real)}`;
|
|
546
546
|
}
|
|
547
|
-
async read(path, caller,
|
|
548
|
-
return (await this.readKeyed(path, caller,
|
|
547
|
+
async read(path, caller, plain3, asked) {
|
|
548
|
+
return (await this.readKeyed(path, caller, plain3, asked)).bytes;
|
|
549
549
|
}
|
|
550
|
-
async readKeyed(path, caller,
|
|
550
|
+
async readKeyed(path, caller, plain3, asked) {
|
|
551
551
|
const found = await this.real(path, asked);
|
|
552
|
-
if (found === void 0) return { bytes: await
|
|
552
|
+
if (found === void 0) return { bytes: await plain3() };
|
|
553
553
|
const { real, name: name2 } = found;
|
|
554
|
-
const read = name2 !== real ? { bytes: await
|
|
554
|
+
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 };
|
|
555
555
|
const { bytes } = read;
|
|
556
556
|
const keyed = read.version === void 0 ? { bytes } : { bytes, key: `${real}\0${read.version}` };
|
|
557
557
|
await this.verify(name2, bytes, caller, EXEC_OPS);
|
|
@@ -560,9 +560,9 @@ var Integrity = class {
|
|
|
560
560
|
get readsChecked() {
|
|
561
561
|
return this.sources.length > 0;
|
|
562
562
|
}
|
|
563
|
-
async readSource(path, caller,
|
|
563
|
+
async readSource(path, caller, plain3) {
|
|
564
564
|
const found = await this.source(path);
|
|
565
|
-
return found === void 0 ?
|
|
565
|
+
return found === void 0 ? plain3() : this.checked(found, caller, plain3);
|
|
566
566
|
}
|
|
567
567
|
async openSource(path, caller, real) {
|
|
568
568
|
const found = await this.source(path, real);
|
|
@@ -572,10 +572,10 @@ var Integrity = class {
|
|
|
572
572
|
}
|
|
573
573
|
await this.checked(found, caller, () => this.root.readFileBuffer(found.real));
|
|
574
574
|
}
|
|
575
|
-
async checked(found, caller,
|
|
575
|
+
async checked(found, caller, plain3) {
|
|
576
576
|
const { real, name: name2 } = found;
|
|
577
577
|
if (name2 !== real || !this.root.readVersioned) {
|
|
578
|
-
const bytes2 = await
|
|
578
|
+
const bytes2 = await plain3();
|
|
579
579
|
await this.verify(name2, bytes2, caller, READ_OPS);
|
|
580
580
|
return bytes2;
|
|
581
581
|
}
|
|
@@ -3232,11 +3232,11 @@ function frame(opcode, payload) {
|
|
|
3232
3232
|
return out;
|
|
3233
3233
|
}
|
|
3234
3234
|
function clientFrame(opcode, payload) {
|
|
3235
|
-
const
|
|
3236
|
-
const head =
|
|
3235
|
+
const plain3 = frame(opcode, payload);
|
|
3236
|
+
const head = plain3.length - payload.length;
|
|
3237
3237
|
const mask = crypto.getRandomValues(new Uint8Array(4));
|
|
3238
|
-
const out = new Uint8Array(
|
|
3239
|
-
out.set(
|
|
3238
|
+
const out = new Uint8Array(plain3.length + 4);
|
|
3239
|
+
out.set(plain3.subarray(0, head));
|
|
3240
3240
|
out[1] = out[1] | 128;
|
|
3241
3241
|
out.set(mask, head);
|
|
3242
3242
|
for (let i = 0; i < payload.length; i++) {
|
|
@@ -7020,7 +7020,7 @@ function satisfies(version, range2) {
|
|
|
7020
7020
|
}
|
|
7021
7021
|
|
|
7022
7022
|
// src/version.ts
|
|
7023
|
-
var KERNEL_VERSION = true ? "1.
|
|
7023
|
+
var KERNEL_VERSION = true ? "1.129.0" : "0.0.0-dev";
|
|
7024
7024
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7025
7025
|
function procVersion() {
|
|
7026
7026
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -9772,8 +9772,9 @@ var FreshModules = class {
|
|
|
9772
9772
|
if (ranged2) {
|
|
9773
9773
|
overrides.pwrite = async (path, at, bytes, transfer) => {
|
|
9774
9774
|
const touches2 = at < MAGIC.length && this.fresh.has(normalizePath(path));
|
|
9775
|
+
const first = at === 0 && bytes.length >= MAGIC.length ? bytes.slice(0, MAGIC.length) : void 0;
|
|
9775
9776
|
await ranged2.pwrite(path, at, bytes, transfer);
|
|
9776
|
-
if (touches2) await decide(path);
|
|
9777
|
+
if (touches2) await decide(path, first);
|
|
9777
9778
|
};
|
|
9778
9779
|
overrides.truncate = async (path, size) => {
|
|
9779
9780
|
await ranged2.truncate(path, size);
|
|
@@ -12377,13 +12378,13 @@ async function chown(entry, path, req) {
|
|
|
12377
12378
|
}
|
|
12378
12379
|
async function runMkdir(entry, path, req) {
|
|
12379
12380
|
const { fs } = entry;
|
|
12380
|
-
const
|
|
12381
|
+
const plain3 = plainDirMode(entry, req.mode);
|
|
12381
12382
|
const parentsMode = !req.exclusive ? plainParentsMode(entry) : void 0;
|
|
12382
12383
|
const fixParents = parentsMode !== void 0 ? await missingParents(fs, path, parentsMode) : void 0;
|
|
12383
|
-
const fresh2 =
|
|
12384
|
+
const fresh2 = plain3 !== void 0 && !await fs.exists(path);
|
|
12384
12385
|
await (req.exclusive ? mkdirExclusive(entry, path, req.mode) : fs.mkdir(path, mkdirOptions(entry, req.mode)));
|
|
12385
12386
|
await fixParents?.();
|
|
12386
|
-
if (fresh2) await fs.chmod(path,
|
|
12387
|
+
if (fresh2) await fs.chmod(path, plain3);
|
|
12387
12388
|
return done2;
|
|
12388
12389
|
}
|
|
12389
12390
|
async function shownAs(entry, path, st) {
|
|
@@ -12391,8 +12392,8 @@ async function shownAs(entry, path, st) {
|
|
|
12391
12392
|
return callerStat(guardOf(entry), await real?.catch(() => path) ?? path, st);
|
|
12392
12393
|
}
|
|
12393
12394
|
function readSource(entry, path) {
|
|
12394
|
-
const
|
|
12395
|
-
return entry.source ? entry.source.read(path,
|
|
12395
|
+
const plain3 = () => entry.fs.readFileBuffer(path);
|
|
12396
|
+
return entry.source ? entry.source.read(path, plain3) : plain3();
|
|
12396
12397
|
}
|
|
12397
12398
|
async function run(entry, path, req) {
|
|
12398
12399
|
const { fs, cwd } = entry;
|
|
@@ -18489,6 +18490,95 @@ async function substituteHead(head, ask) {
|
|
|
18489
18490
|
`, values };
|
|
18490
18491
|
}
|
|
18491
18492
|
|
|
18493
|
+
// src/kernel/net/sealed-smtp.ts
|
|
18494
|
+
var SMTP_LINE_MAX = 4096;
|
|
18495
|
+
var GREETING = ["EHLO ", "HELO "];
|
|
18496
|
+
function sniffSmtp(start2) {
|
|
18497
|
+
const upper = start2.toUpperCase();
|
|
18498
|
+
for (const word of GREETING) {
|
|
18499
|
+
if (upper.startsWith(word)) return "yes";
|
|
18500
|
+
if (word.startsWith(upper)) return "more";
|
|
18501
|
+
}
|
|
18502
|
+
return "no";
|
|
18503
|
+
}
|
|
18504
|
+
function decoded(b64) {
|
|
18505
|
+
if (!/^[A-Za-z0-9+/]+={0,2}$/.test(b64)) return void 0;
|
|
18506
|
+
try {
|
|
18507
|
+
return atob(b64);
|
|
18508
|
+
} catch {
|
|
18509
|
+
return void 0;
|
|
18510
|
+
}
|
|
18511
|
+
}
|
|
18512
|
+
async function swapped2(text, position, ask) {
|
|
18513
|
+
const placeholders = placeholdersIn(text);
|
|
18514
|
+
if (placeholders.length === 0 || placeholders.length > SESSION_PLACEHOLDERS) return void 0;
|
|
18515
|
+
const values = usable(await ask(position, placeholders));
|
|
18516
|
+
if (Object.keys(values).length === 0) return void 0;
|
|
18517
|
+
return { text: replaced(text, values), values };
|
|
18518
|
+
}
|
|
18519
|
+
async function plain2(b64, ask) {
|
|
18520
|
+
const text = decoded(b64);
|
|
18521
|
+
const fields = text?.split("\0");
|
|
18522
|
+
if (fields?.length !== 3) return { line: b64 };
|
|
18523
|
+
const [authz, user, pass2] = fields;
|
|
18524
|
+
if (placeholdersIn(authz + user).length > 0) return { line: b64 };
|
|
18525
|
+
const done5 = await swapped2(pass2, "auth-plain", ask);
|
|
18526
|
+
if (!done5) return { line: b64 };
|
|
18527
|
+
return { line: btoa(`${authz}\0${user}\0${done5.text}`), values: done5.values };
|
|
18528
|
+
}
|
|
18529
|
+
async function login(b64, ask) {
|
|
18530
|
+
const text = decoded(b64);
|
|
18531
|
+
const done5 = text === void 0 ? void 0 : await swapped2(text, "auth-login", ask);
|
|
18532
|
+
return done5 ? { line: btoa(done5.text), values: done5.values } : { line: b64 };
|
|
18533
|
+
}
|
|
18534
|
+
var SmtpClient = class {
|
|
18535
|
+
state = "command";
|
|
18536
|
+
ask;
|
|
18537
|
+
constructor(ask) {
|
|
18538
|
+
this.ask = ask;
|
|
18539
|
+
}
|
|
18540
|
+
get done() {
|
|
18541
|
+
return this.state === "done";
|
|
18542
|
+
}
|
|
18543
|
+
async line(text) {
|
|
18544
|
+
const state = this.state;
|
|
18545
|
+
if (state === "done") return { line: text };
|
|
18546
|
+
if (state === "plain" || state === "password") {
|
|
18547
|
+
this.state = "done";
|
|
18548
|
+
if (text === "*") return { line: text };
|
|
18549
|
+
return state === "plain" ? plain2(text, this.ask) : login(text, this.ask);
|
|
18550
|
+
}
|
|
18551
|
+
if (state === "user") {
|
|
18552
|
+
this.state = text === "*" ? "done" : "password";
|
|
18553
|
+
return { line: text };
|
|
18554
|
+
}
|
|
18555
|
+
return this.command(text);
|
|
18556
|
+
}
|
|
18557
|
+
async command(text) {
|
|
18558
|
+
const m = /^AUTH[ \t]+(PLAIN|LOGIN)(?:[ \t]+(\S+))?$/i.exec(text);
|
|
18559
|
+
if (!m) {
|
|
18560
|
+
if (/^(MAIL|RCPT|DATA|BDAT|AUTH)\b/i.test(text)) this.state = "done";
|
|
18561
|
+
return { line: text };
|
|
18562
|
+
}
|
|
18563
|
+
const mech = m[1].toUpperCase();
|
|
18564
|
+
const arg = m[2];
|
|
18565
|
+
if (mech === "LOGIN") {
|
|
18566
|
+
this.state = arg === void 0 ? "user" : "password";
|
|
18567
|
+
return { line: text };
|
|
18568
|
+
}
|
|
18569
|
+
if (arg === void 0) {
|
|
18570
|
+
this.state = "plain";
|
|
18571
|
+
return { line: text };
|
|
18572
|
+
}
|
|
18573
|
+
this.state = "done";
|
|
18574
|
+
const out = await plain2(arg, this.ask);
|
|
18575
|
+
return {
|
|
18576
|
+
line: `${text.slice(0, text.length - arg.length)}${out.line}`,
|
|
18577
|
+
...out.values ? { values: out.values } : {}
|
|
18578
|
+
};
|
|
18579
|
+
}
|
|
18580
|
+
};
|
|
18581
|
+
|
|
18492
18582
|
// src/kernel/net/sealed-conn.ts
|
|
18493
18583
|
var HEAD_IDLE_MS = 2e3;
|
|
18494
18584
|
function substitutes(s) {
|
|
@@ -18520,12 +18610,25 @@ function headEnd2(bytes) {
|
|
|
18520
18610
|
}
|
|
18521
18611
|
return -1;
|
|
18522
18612
|
}
|
|
18523
|
-
|
|
18613
|
+
function modeOf(start2) {
|
|
18614
|
+
const http = sniffHttp1(start2);
|
|
18615
|
+
const smtp = sniffSmtp(start2);
|
|
18616
|
+
if (http === "yes") return "http1";
|
|
18617
|
+
if (smtp === "yes") return "smtp";
|
|
18618
|
+
return http === "no" && smtp === "no" ? "pass" : void 0;
|
|
18619
|
+
}
|
|
18620
|
+
function crlf(bytes) {
|
|
18621
|
+
for (let i = 0; i + 1 < bytes.length; i++) if (bytes[i] === 13 && bytes[i + 1] === 10) return i;
|
|
18622
|
+
return -1;
|
|
18623
|
+
}
|
|
18624
|
+
var SessionWriter = class {
|
|
18524
18625
|
buffer = new Uint8Array(0);
|
|
18525
|
-
|
|
18626
|
+
mode = "sniff";
|
|
18526
18627
|
timer;
|
|
18527
18628
|
chain = Promise.resolve();
|
|
18528
18629
|
failed;
|
|
18630
|
+
session = sessionId();
|
|
18631
|
+
smtp;
|
|
18529
18632
|
conn;
|
|
18530
18633
|
s;
|
|
18531
18634
|
scope;
|
|
@@ -18533,6 +18636,9 @@ var Http1Writer = class {
|
|
|
18533
18636
|
this.conn = conn;
|
|
18534
18637
|
this.s = s;
|
|
18535
18638
|
this.scope = scope;
|
|
18639
|
+
this.smtp = new SmtpClient(
|
|
18640
|
+
(position, placeholders) => this.ask("smtp", position, placeholders)
|
|
18641
|
+
);
|
|
18536
18642
|
}
|
|
18537
18643
|
write(bytes) {
|
|
18538
18644
|
const run2 = this.chain.then(() => this.take(bytes));
|
|
@@ -18542,30 +18648,78 @@ var Http1Writer = class {
|
|
|
18542
18648
|
);
|
|
18543
18649
|
return run2;
|
|
18544
18650
|
}
|
|
18651
|
+
async ask(protocol, position, placeholders, head) {
|
|
18652
|
+
const s = this.s;
|
|
18653
|
+
const values = await s.broker.sessionMaterialize({
|
|
18654
|
+
stamp: await s.stamp(),
|
|
18655
|
+
session: this.session,
|
|
18656
|
+
host: s.host,
|
|
18657
|
+
port: s.port,
|
|
18658
|
+
protocol,
|
|
18659
|
+
position,
|
|
18660
|
+
verified: s.verified,
|
|
18661
|
+
handshakeAt: s.handshakeAt,
|
|
18662
|
+
exit: s.exit,
|
|
18663
|
+
placeholders,
|
|
18664
|
+
...head ? { head } : {}
|
|
18665
|
+
});
|
|
18666
|
+
return values;
|
|
18667
|
+
}
|
|
18668
|
+
remember(values) {
|
|
18669
|
+
this.scope.add(
|
|
18670
|
+
Object.entries(values).map(([placeholder, value2]) => ({ name: "sealed", value: value2, placeholder }))
|
|
18671
|
+
);
|
|
18672
|
+
}
|
|
18545
18673
|
async take(bytes) {
|
|
18546
18674
|
if (this.failed !== void 0) throw this.failed;
|
|
18547
|
-
if (this.
|
|
18675
|
+
if (this.mode === "pass") return this.conn.write(bytes);
|
|
18548
18676
|
clearTimeout(this.timer);
|
|
18549
18677
|
const joined4 = new Uint8Array(this.buffer.length + bytes.length);
|
|
18550
18678
|
joined4.set(this.buffer);
|
|
18551
18679
|
joined4.set(bytes, this.buffer.length);
|
|
18552
18680
|
this.buffer.fill(0);
|
|
18553
18681
|
this.buffer = joined4;
|
|
18554
|
-
|
|
18555
|
-
|
|
18556
|
-
if (
|
|
18557
|
-
|
|
18558
|
-
|
|
18559
|
-
|
|
18682
|
+
if (this.mode === "sniff") this.mode = modeOf(latin12(joined4.subarray(0, 8))) ?? "sniff";
|
|
18683
|
+
if (this.mode === "pass") await this.release();
|
|
18684
|
+
else if (this.mode === "http1") await this.http1();
|
|
18685
|
+
else if (this.mode === "smtp") await this.lines();
|
|
18686
|
+
if (this.mode !== "pass" && this.buffer.length > 0)
|
|
18687
|
+
this.timer = setTimeout(() => this.idle(), HEAD_IDLE_MS);
|
|
18560
18688
|
return bytes.length;
|
|
18561
18689
|
}
|
|
18690
|
+
async http1() {
|
|
18691
|
+
const end = headEnd2(this.buffer);
|
|
18692
|
+
if (end > HEAD_MAX || end < 0 && this.buffer.length > HEAD_MAX) await this.release();
|
|
18693
|
+
else if (end >= 0) await this.substitute(end);
|
|
18694
|
+
}
|
|
18695
|
+
async lines() {
|
|
18696
|
+
for (; ; ) {
|
|
18697
|
+
const at = crlf(this.buffer);
|
|
18698
|
+
if (at < 0) break;
|
|
18699
|
+
if (at > SMTP_LINE_MAX) return this.release();
|
|
18700
|
+
const all = this.buffer;
|
|
18701
|
+
this.buffer = all.slice(at + 2);
|
|
18702
|
+
const out = await this.smtp.line(latin12(all.subarray(0, at))).catch(() => ({ line: latin12(all.subarray(0, at)) }));
|
|
18703
|
+
all.fill(0);
|
|
18704
|
+
if ("values" in out && out.values) this.remember(out.values);
|
|
18705
|
+
const line = bytesOf(`${out.line}\r
|
|
18706
|
+
`);
|
|
18707
|
+
try {
|
|
18708
|
+
await writeAll4(this.conn, line);
|
|
18709
|
+
} finally {
|
|
18710
|
+
line.fill(0);
|
|
18711
|
+
}
|
|
18712
|
+
if (this.smtp.done) return this.release();
|
|
18713
|
+
}
|
|
18714
|
+
if (this.buffer.length > SMTP_LINE_MAX) await this.release();
|
|
18715
|
+
}
|
|
18562
18716
|
idle() {
|
|
18563
18717
|
this.chain = this.chain.then(() => this.release()).catch((err) => {
|
|
18564
18718
|
this.failed ??= err;
|
|
18565
18719
|
});
|
|
18566
18720
|
}
|
|
18567
18721
|
async release() {
|
|
18568
|
-
this.
|
|
18722
|
+
this.mode = "pass";
|
|
18569
18723
|
const out = this.buffer;
|
|
18570
18724
|
this.buffer = new Uint8Array(0);
|
|
18571
18725
|
try {
|
|
@@ -18575,37 +18729,15 @@ var Http1Writer = class {
|
|
|
18575
18729
|
}
|
|
18576
18730
|
}
|
|
18577
18731
|
async substitute(end) {
|
|
18578
|
-
this.
|
|
18732
|
+
this.mode = "pass";
|
|
18579
18733
|
const all = this.buffer;
|
|
18580
18734
|
this.buffer = new Uint8Array(0);
|
|
18581
|
-
const s = this.s;
|
|
18582
|
-
const session = sessionId();
|
|
18583
18735
|
const done5 = await substituteHead(
|
|
18584
18736
|
latin12(all.subarray(0, end)),
|
|
18585
|
-
|
|
18586
|
-
stamp: await s.stamp(),
|
|
18587
|
-
session,
|
|
18588
|
-
host: s.host,
|
|
18589
|
-
port: s.port,
|
|
18590
|
-
protocol: "http1",
|
|
18591
|
-
position,
|
|
18592
|
-
verified: s.verified,
|
|
18593
|
-
handshakeAt: s.handshakeAt,
|
|
18594
|
-
exit: s.exit,
|
|
18595
|
-
placeholders,
|
|
18596
|
-
head: head2
|
|
18597
|
-
})
|
|
18737
|
+
(position, placeholders, head2) => this.ask("http1", position, placeholders, head2)
|
|
18598
18738
|
).catch(() => void 0);
|
|
18599
18739
|
const head = done5 ? bytesOf(done5.head) : all.subarray(0, end);
|
|
18600
|
-
if (done5)
|
|
18601
|
-
this.scope.add(
|
|
18602
|
-
Object.entries(done5.values).map(([placeholder, value2]) => ({
|
|
18603
|
-
name: "sealed",
|
|
18604
|
-
value: value2,
|
|
18605
|
-
placeholder
|
|
18606
|
-
}))
|
|
18607
|
-
);
|
|
18608
|
-
}
|
|
18740
|
+
if (done5) this.remember(done5.values);
|
|
18609
18741
|
try {
|
|
18610
18742
|
await writeAll4(this.conn, head);
|
|
18611
18743
|
await writeAll4(this.conn, all.subarray(end));
|
|
@@ -18616,14 +18748,14 @@ var Http1Writer = class {
|
|
|
18616
18748
|
}
|
|
18617
18749
|
flushed() {
|
|
18618
18750
|
clearTimeout(this.timer);
|
|
18619
|
-
this.chain = this.chain.then(() => this.
|
|
18751
|
+
this.chain = this.chain.then(() => this.mode === "pass" ? void 0 : this.release());
|
|
18620
18752
|
return this.chain;
|
|
18621
18753
|
}
|
|
18622
18754
|
drop() {
|
|
18623
18755
|
clearTimeout(this.timer);
|
|
18624
18756
|
this.buffer.fill(0);
|
|
18625
18757
|
this.buffer = new Uint8Array(0);
|
|
18626
|
-
this.
|
|
18758
|
+
this.mode = "pass";
|
|
18627
18759
|
}
|
|
18628
18760
|
};
|
|
18629
18761
|
var IDLE2 = /* @__PURE__ */ Symbol("idle");
|
|
@@ -18634,11 +18766,9 @@ var ScrubReader = class {
|
|
|
18634
18766
|
held = false;
|
|
18635
18767
|
ended = false;
|
|
18636
18768
|
conn;
|
|
18637
|
-
s;
|
|
18638
18769
|
scope;
|
|
18639
|
-
constructor(conn,
|
|
18770
|
+
constructor(conn, scope) {
|
|
18640
18771
|
this.conn = conn;
|
|
18641
|
-
this.s = s;
|
|
18642
18772
|
this.scope = scope;
|
|
18643
18773
|
}
|
|
18644
18774
|
current() {
|
|
@@ -18697,8 +18827,8 @@ function idle() {
|
|
|
18697
18827
|
}
|
|
18698
18828
|
function sealedConn(conn, s) {
|
|
18699
18829
|
const scope = s.broker.sessions.scope(s.pid, s.host);
|
|
18700
|
-
const writer = substitutes(s) ? new
|
|
18701
|
-
const reader = new ScrubReader(conn,
|
|
18830
|
+
const writer = substitutes(s) ? new SessionWriter(conn, s, scope) : void 0;
|
|
18831
|
+
const reader = new ScrubReader(conn, scope);
|
|
18702
18832
|
return {
|
|
18703
18833
|
localAddr: conn.localAddr,
|
|
18704
18834
|
remoteAddr: conn.remoteAddr,
|
|
@@ -19824,6 +19954,12 @@ function tlsOverTransport(req, proc) {
|
|
|
19824
19954
|
return { fd: proc.fds.install(new OpenFile(mine), 3), alpnProtocol: "http/1.1", servername };
|
|
19825
19955
|
}
|
|
19826
19956
|
|
|
19957
|
+
// src/kernel/test-hooks.ts
|
|
19958
|
+
var SYSCALL_HOOK = /* @__PURE__ */ Symbol.for("slicc-kernel.test.syscall");
|
|
19959
|
+
function testSyscallHook() {
|
|
19960
|
+
return globalThis[SYSCALL_HOOK];
|
|
19961
|
+
}
|
|
19962
|
+
|
|
19827
19963
|
// src/kernel/vfs-file.ts
|
|
19828
19964
|
var O_ACCMODE = 3;
|
|
19829
19965
|
var O_WRONLY = 1;
|
|
@@ -21038,7 +21174,8 @@ var WasmProcess = class {
|
|
|
21038
21174
|
cwd,
|
|
21039
21175
|
...moved2,
|
|
21040
21176
|
...group,
|
|
21041
|
-
...exec ? { exec } : {}
|
|
21177
|
+
...exec ? { exec } : {},
|
|
21178
|
+
search: req.search
|
|
21042
21179
|
};
|
|
21043
21180
|
const pid = await this.children.spawn(spawned, stdio, inherit2);
|
|
21044
21181
|
if (deathSignal !== void 0) this.onDeath(pgid === 0 || session ? -pid : pid, deathSignal);
|
|
@@ -21124,6 +21261,8 @@ var WasmProcess = class {
|
|
|
21124
21261
|
return void 0;
|
|
21125
21262
|
}
|
|
21126
21263
|
async syscall(req, cancelled, block) {
|
|
21264
|
+
const hook = testSyscallHook();
|
|
21265
|
+
if (hook) await hook({ pid: this.pid, op: req.op });
|
|
21127
21266
|
this.options.onSyscall?.(req);
|
|
21128
21267
|
this.calls += 1;
|
|
21129
21268
|
const started = performance.now();
|
|
@@ -21421,18 +21560,18 @@ var WasmProcess = class {
|
|
|
21421
21560
|
}
|
|
21422
21561
|
if (this.writesAt(req) && this.options.readonlyAt?.(path)) throw new KernelError("EROFS");
|
|
21423
21562
|
const open2 = { ...req, path };
|
|
21424
|
-
const
|
|
21563
|
+
const plain3 = this.plainMode(req.mode);
|
|
21425
21564
|
if (req.exclusive) {
|
|
21426
21565
|
await nodes.createExclusive(path, this.newOwner(req.mode));
|
|
21427
|
-
if (
|
|
21566
|
+
if (plain3 !== void 0) await fs.chmod?.(path, plain3);
|
|
21428
21567
|
this.fds.installAt(fd, this.openVfsFile(open2, void 0, fs));
|
|
21429
21568
|
} else if (req.create) {
|
|
21430
21569
|
await nodes.onEntry(path, async () => {
|
|
21431
|
-
const marks = this.options.owners ||
|
|
21570
|
+
const marks = this.options.owners || plain3 !== void 0;
|
|
21432
21571
|
const fresh2 = marks && !await present3(fs, path, true);
|
|
21433
21572
|
this.fds.installAt(fd, this.openVfsFile(open2, await nodes.identify(path), fs));
|
|
21434
21573
|
await this.fds.get(fd).file.stat?.();
|
|
21435
|
-
if (fresh2 &&
|
|
21574
|
+
if (fresh2 && plain3 !== void 0) await fs.chmod?.(path, plain3);
|
|
21436
21575
|
else if (fresh2) {
|
|
21437
21576
|
await fs.chown?.(path, { ...this.newOwner(req.mode), kind: "new" });
|
|
21438
21577
|
}
|
|
@@ -23575,15 +23714,15 @@ function isRecord(value2) {
|
|
|
23575
23714
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
23576
23715
|
}
|
|
23577
23716
|
function serialized(reply) {
|
|
23578
|
-
let
|
|
23717
|
+
let plain3;
|
|
23579
23718
|
try {
|
|
23580
23719
|
const text = JSON.stringify(reply);
|
|
23581
|
-
|
|
23720
|
+
plain3 = text === void 0 ? void 0 : JSON.parse(text);
|
|
23582
23721
|
} catch (err) {
|
|
23583
23722
|
return JSON.stringify(errorReply("EIO", lineOf2(err)));
|
|
23584
23723
|
}
|
|
23585
|
-
if (!isRecord(
|
|
23586
|
-
const { v: _, ...rest2 } =
|
|
23724
|
+
if (!isRecord(plain3)) return JSON.stringify(errorReply("EIO", "the vault gave no reply"));
|
|
23725
|
+
const { v: _, ...rest2 } = plain3;
|
|
23587
23726
|
return JSON.stringify({ v: 1, ...rest2 });
|
|
23588
23727
|
}
|
|
23589
23728
|
function lineOf2(err) {
|
|
@@ -25545,13 +25684,13 @@ function splitWords(text) {
|
|
|
25545
25684
|
while (piece.lastIndex < text.length) {
|
|
25546
25685
|
const m = piece.exec(text);
|
|
25547
25686
|
if (!m) return void 0;
|
|
25548
|
-
const [, single, double, escaped,
|
|
25687
|
+
const [, single, double, escaped, plain3, space] = m;
|
|
25549
25688
|
if (space !== void 0) {
|
|
25550
25689
|
if (word !== void 0) words2.push(word);
|
|
25551
25690
|
word = void 0;
|
|
25552
25691
|
continue;
|
|
25553
25692
|
}
|
|
25554
|
-
word = (word ?? "") + (single ?? (double !== void 0 ? unescaped(double) : escaped ??
|
|
25693
|
+
word = (word ?? "") + (single ?? (double !== void 0 ? unescaped(double) : escaped ?? plain3));
|
|
25555
25694
|
}
|
|
25556
25695
|
if (word !== void 0) words2.push(word);
|
|
25557
25696
|
return words2;
|
|
@@ -26744,16 +26883,52 @@ var Launcher = class {
|
|
|
26744
26883
|
for (const bin of planned?.bins ?? []) await need(g, "exec", bin, R_OK | X_OK);
|
|
26745
26884
|
if (planned?.target.copy) await need(g, "exec", planned.target.copy, R_OK | X_OK);
|
|
26746
26885
|
}
|
|
26747
|
-
async checkedPlan(req,
|
|
26748
|
-
|
|
26886
|
+
async checkedPlan(req, ctx, fds) {
|
|
26887
|
+
try {
|
|
26888
|
+
return await this.planOrSearch(req, ctx);
|
|
26889
|
+
} catch (err) {
|
|
26749
26890
|
await fds.closeAll();
|
|
26750
|
-
throw err
|
|
26891
|
+
throw err;
|
|
26892
|
+
}
|
|
26893
|
+
}
|
|
26894
|
+
async planOrSearch(req, ctx) {
|
|
26895
|
+
const bare = !req.file.includes("/") && !COMMAND2.test(req.file);
|
|
26896
|
+
try {
|
|
26897
|
+
return await this.planOne(req, ctx);
|
|
26898
|
+
} catch (err) {
|
|
26899
|
+
const code = codeOf7(err);
|
|
26900
|
+
const searched = bare && req.search !== false && (code === "ENOENT" || code === "ENOEXEC");
|
|
26901
|
+
if (!searched || await this.commandAt(req.file, ctx.scope)) throw err;
|
|
26902
|
+
const found = await this.onPath(req, ctx);
|
|
26903
|
+
if (found) return found;
|
|
26904
|
+
throw err;
|
|
26905
|
+
}
|
|
26906
|
+
}
|
|
26907
|
+
async onPath(req, ctx) {
|
|
26908
|
+
const path = req.env.PATH;
|
|
26909
|
+
if (typeof path !== "string") return void 0;
|
|
26910
|
+
let denied2 = false;
|
|
26911
|
+
for (const dir of path.split(":")) {
|
|
26912
|
+
const file = dir === "" ? `./${req.file}` : `${dir.replace(/\/+$/, "")}/${req.file}`;
|
|
26913
|
+
try {
|
|
26914
|
+
return await this.planOne({ ...req, file }, ctx);
|
|
26915
|
+
} catch (err) {
|
|
26916
|
+
const code = codeOf7(err);
|
|
26917
|
+
if (code === "EACCES") denied2 = true;
|
|
26918
|
+
else if (code !== "ENOENT" && code !== "ENOTDIR") throw err;
|
|
26919
|
+
}
|
|
26920
|
+
}
|
|
26921
|
+
if (denied2) throw new SpawnError("EACCES");
|
|
26922
|
+
return void 0;
|
|
26923
|
+
}
|
|
26924
|
+
async planOne(req, { ppid, cred, scope }) {
|
|
26925
|
+
const refused3 = (err) => {
|
|
26926
|
+
throw codeOf7(err) === "EACCES" ? new SpawnError("EACCES") : err;
|
|
26751
26927
|
};
|
|
26752
26928
|
const file = await this.execFile(req.file, req.cwd, this.execGuard(cred, ppid)).catch(refused3);
|
|
26753
26929
|
const planned = await this.plan(file, req.argv, req.cwd, scope, req.argv0);
|
|
26754
26930
|
await this.mayExec(cred, { ...req, file, pid: ppid }, planned).catch(refused3);
|
|
26755
26931
|
if (planned) return planned;
|
|
26756
|
-
await fds.closeAll();
|
|
26757
26932
|
throw new SpawnError(await this.unrunnable(file, req.cwd, scope));
|
|
26758
26933
|
}
|
|
26759
26934
|
async enterable(g, cwd) {
|
|
@@ -26920,12 +27095,12 @@ var Launcher = class {
|
|
|
26920
27095
|
return `${path}:${st.size}:${st.mtime.getTime()}`;
|
|
26921
27096
|
}
|
|
26922
27097
|
verified(path, caller, fs = this.base) {
|
|
26923
|
-
const
|
|
26924
|
-
return this.integrity ? this.integrity.read(path, caller,
|
|
27098
|
+
const plain3 = () => fs.readFileBuffer(path);
|
|
27099
|
+
return this.integrity ? this.integrity.read(path, caller, plain3) : plain3();
|
|
26925
27100
|
}
|
|
26926
27101
|
keyed(path, caller, asked) {
|
|
26927
|
-
const
|
|
26928
|
-
return this.integrity ? this.integrity.readKeyed(path, caller,
|
|
27102
|
+
const plain3 = async () => this.base.readFileBuffer(path);
|
|
27103
|
+
return this.integrity ? this.integrity.readKeyed(path, caller, plain3, asked) : plain3().then((bytes) => ({ bytes }));
|
|
26929
27104
|
}
|
|
26930
27105
|
cached(cache, key, load) {
|
|
26931
27106
|
const hit = cache.get(key);
|
|
@@ -27122,7 +27297,7 @@ var Launcher = class {
|
|
|
27122
27297
|
});
|
|
27123
27298
|
return {
|
|
27124
27299
|
source: {
|
|
27125
|
-
read: (path,
|
|
27300
|
+
read: (path, plain3) => integrity.readSource(path, caller(), plain3),
|
|
27126
27301
|
open: (path, real) => integrity.openSource(path, caller(), real)
|
|
27127
27302
|
}
|
|
27128
27303
|
};
|
|
@@ -28029,9 +28204,9 @@ var Launcher = class {
|
|
|
28029
28204
|
}
|
|
28030
28205
|
);
|
|
28031
28206
|
}
|
|
28032
|
-
environment(cwd, extra, account,
|
|
28207
|
+
environment(cwd, extra, account, login2 = false) {
|
|
28033
28208
|
const env = {
|
|
28034
|
-
...
|
|
28209
|
+
...login2 ? networkEnv(this.hostname) : this.env,
|
|
28035
28210
|
...userEnv(account, this.pnpmHome),
|
|
28036
28211
|
PWD: cwd,
|
|
28037
28212
|
...extra
|
|
@@ -28258,6 +28433,9 @@ var Launcher = class {
|
|
|
28258
28433
|
function cronLocks() {
|
|
28259
28434
|
return globalThis.navigator?.locks;
|
|
28260
28435
|
}
|
|
28436
|
+
function codeOf7(err) {
|
|
28437
|
+
return err?.code;
|
|
28438
|
+
}
|
|
28261
28439
|
|
|
28262
28440
|
// src/pin.ts
|
|
28263
28441
|
function pinScript(url) {
|