@ai-ecoverse/slicc-kernel 1.90.0 → 1.91.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.
@@ -255,6 +255,10 @@ var init_protocol = __esm({
255
255
  });
256
256
 
257
257
  // src/kernel/net/loopback-names.ts
258
+ function isKernelLoopbackHost(hostname) {
259
+ const host = hostname.replace(/^\[(.*)\]$/, "$1").replace(/\.$/, "").toLowerCase();
260
+ return host === "localhost" || host.endsWith(".localhost") || host === "0.0.0.0" || LOOPBACK_V4.test(host) || LOOPBACK_V6.has(host) || MAPPED_V4.test(host);
261
+ }
258
262
  function reserved(name2) {
259
263
  const lower = name2.toLowerCase();
260
264
  return lower === "localhost" || lower.endsWith(".localhost") || lower === HOST_LOOPBACK || lower === "wasmer.sh" || /^\d+(\.\d+){3}$/.test(lower);
@@ -278,7 +282,7 @@ function hostsFile(hostname = DEFAULT_HOSTNAME) {
278
282
  ""
279
283
  ].join("\n");
280
284
  }
281
- var HOST_LOOPBACK, HOST_LOOPBACK_ADDRESS, PAGE_LOOPBACK, PAGE_LOOPBACK_URL, DEFAULT_HOSTNAME, HOSTNAME_ADDRESS, LIBC_HOSTNAMES, LABEL;
285
+ var HOST_LOOPBACK, HOST_LOOPBACK_ADDRESS, PAGE_LOOPBACK, PAGE_LOOPBACK_URL, LOOPBACK_V4, LOOPBACK_V6, MAPPED_V4, DEFAULT_HOSTNAME, HOSTNAME_ADDRESS, LIBC_HOSTNAMES, LABEL;
282
286
  var init_loopback_names = __esm({
283
287
  "src/kernel/net/loopback-names.ts"() {
284
288
  "use strict";
@@ -286,6 +290,9 @@ var init_loopback_names = __esm({
286
290
  HOST_LOOPBACK_ADDRESS = [10, 0, 2, 2];
287
291
  PAGE_LOOPBACK = "kernel.localhost";
288
292
  PAGE_LOOPBACK_URL = `http://{port}.${PAGE_LOOPBACK}`;
293
+ LOOPBACK_V4 = /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
294
+ LOOPBACK_V6 = /* @__PURE__ */ new Set(["::1", "::", "0:0:0:0:0:0:0:1"]);
295
+ MAPPED_V4 = /^::ffff:7f[0-9a-f]{2}:[0-9a-f]{1,4}$/;
289
296
  DEFAULT_HOSTNAME = "slicc";
290
297
  HOSTNAME_ADDRESS = "127.0.1.1";
291
298
  LIBC_HOSTNAMES = ["emscripten", "wasmer.sh"];
@@ -3762,12 +3769,12 @@ function anySelect(Fs, transport, read2, write2, timeoutMs) {
3762
3769
  const kernelRead = read2.filter((fd) => !own(fd));
3763
3770
  const kernelWrite = write2.filter((fd) => !own(fd));
3764
3771
  for (; ; ) {
3765
- const local2 = ownReady(Fs, read2.filter(own), write2.filter(own));
3766
- const pending = local2.read.length > 0 || local2.write.length > 0;
3772
+ const local3 = ownReady(Fs, read2.filter(own), write2.filter(own));
3773
+ const pending = local3.read.length > 0 || local3.write.length > 0;
3767
3774
  const slice = pending ? 0 : Math.min(SELECT_SLICE_MS, Math.max(0, deadline - Date.now()));
3768
3775
  const got = kernelSelect(Fs, transport, kernelRead, kernelWrite, slice);
3769
3776
  if (typeof got === "number") return got;
3770
- const ready = { read: [...local2.read, ...got.read], write: [...local2.write, ...got.write] };
3777
+ const ready = { read: [...local3.read, ...got.read], write: [...local3.write, ...got.write] };
3771
3778
  if (ready.read.length > 0 || ready.write.length > 0 || Date.now() >= deadline) {
3772
3779
  return ready;
3773
3780
  }
@@ -4285,7 +4292,7 @@ var KERNEL_VERSION, OS_RELEASE;
4285
4292
  var init_version = __esm({
4286
4293
  "src/version.ts"() {
4287
4294
  "use strict";
4288
- KERNEL_VERSION = true ? "1.90.0" : "0.0.0-dev";
4295
+ KERNEL_VERSION = true ? "1.91.0" : "0.0.0-dev";
4289
4296
  OS_RELEASE = "6.0.0-slicc";
4290
4297
  }
4291
4298
  });
@@ -6821,34 +6828,40 @@ function readyEvents(subs, ready) {
6821
6828
  hangup: ready.hangup?.includes(s.fd) === true
6822
6829
  }));
6823
6830
  }
6831
+ function selectOnce(deps, read2, write2, timeoutMs) {
6832
+ try {
6833
+ const ready = deps.kernel.call({ op: "fd-select", read: read2, write: write2, timeoutMs });
6834
+ return { ready, interrupted: false };
6835
+ } catch (e) {
6836
+ if (!deps.interruptWakes || e.code !== "EINTR") throw e;
6837
+ return { ready: { read: [], write: [] }, interrupted: true };
6838
+ }
6839
+ }
6840
+ function waitEvents(deps, subs, { events, read: read2, write: write2 }, entered) {
6841
+ const earliest = subs.reduce((min, s) => Math.min(min, s.deadline), Infinity);
6842
+ const timeout = () => {
6843
+ if (events.length > 0 || entered) return 0;
6844
+ return earliest === Infinity ? -1 : Math.max(0, Math.ceil(earliest - performance.now()));
6845
+ };
6846
+ for (; ; ) {
6847
+ const { ready, interrupted } = selectOnce(deps, read2, write2, timeout());
6848
+ events.push(...readyEvents(subs, ready));
6849
+ if (interrupted) return true;
6850
+ if (events.length > 0 || entered || earliest === Infinity) return false;
6851
+ if (performance.now() >= earliest) return false;
6852
+ }
6853
+ }
6824
6854
  function pollOneoff(deps, inPtr, outPtr, nsubs, neventsPtr) {
6825
6855
  if (nsubs === 0) return E.INVAL;
6826
- const { mem, kernel } = deps;
6856
+ const { mem } = deps;
6827
6857
  const subs = readSubscriptions(mem, inPtr, nsubs, deps.now);
6828
- const { events, read: read2, write: write2 } = classify(deps.fds, subs);
6829
- let interrupted = false;
6830
- const earliest = subs.reduce((min, s) => Math.min(min, s.deadline), Infinity);
6831
- const expired = () => performance.now() >= earliest;
6832
- if (read2.length > 0 || write2.length > 0 || events.length === 0) {
6833
- do {
6834
- let timeoutMs = -1;
6835
- if (events.length > 0) timeoutMs = 0;
6836
- else if (earliest !== Infinity)
6837
- timeoutMs = Math.max(0, Math.ceil(earliest - performance.now()));
6838
- let ready;
6839
- try {
6840
- ready = kernel.call({ op: "fd-select", read: read2, write: write2, timeoutMs });
6841
- } catch (e) {
6842
- if (!deps.interruptWakes || e.code !== "EINTR") throw e;
6843
- interrupted = true;
6844
- ready = { read: [], write: [] };
6845
- }
6846
- events.push(
6847
- ...readyEvents(subs, ready)
6848
- );
6849
- } while (events.length === 0 && !interrupted && earliest !== Infinity && !expired());
6850
- }
6858
+ const found = classify(deps.fds, subs);
6859
+ const { events, read: read2, write: write2 } = found;
6860
+ const entered = deps.entered === true && deps.interruptWakes !== true;
6861
+ const waits = read2.length > 0 || write2.length > 0 || events.length === 0;
6862
+ const interrupted = waits && waitEvents(deps, subs, found, entered);
6851
6863
  const after = performance.now();
6864
+ if (entered && events.length === 0 && !subs.some((s) => s.deadline <= after)) return E.INTR;
6852
6865
  for (const s of subs) {
6853
6866
  if (s.type === EVENTTYPE.CLOCK && (interrupted || s.deadline <= after)) {
6854
6867
  events.push({ userdata: s.userdata, error: E.SUCCESS, type: s.type });
@@ -7054,6 +7067,7 @@ var init_wasi_host = __esm({
7054
7067
  cache;
7055
7068
  startCwd;
7056
7069
  interruptWakes = false;
7070
+ entered = false;
7057
7071
  onRaise;
7058
7072
  muted;
7059
7073
  signals;
@@ -7277,7 +7291,8 @@ var init_wasi_host = __esm({
7277
7291
  fds: this.fds,
7278
7292
  kernel: this.o.kernel,
7279
7293
  now: (id) => this.now(id),
7280
- interruptWakes: this.interruptWakes
7294
+ interruptWakes: this.interruptWakes,
7295
+ entered: this.entered
7281
7296
  },
7282
7297
  inPtr,
7283
7298
  outPtr,
@@ -7294,7 +7309,7 @@ var init_wasi_host = __esm({
7294
7309
  this.mem.view().setUint32(nevents, 0, true);
7295
7310
  if (mask.deliverUnblocked()) return E.INTR;
7296
7311
  if (n > 0) return this.poll(inPtr, outPtr, n, nevents);
7297
- return this.suspend();
7312
+ return this.entered ? E.INTR : this.suspend();
7298
7313
  } finally {
7299
7314
  mask.deliverUnblocked();
7300
7315
  mask.restore(old);
@@ -10601,10 +10616,8 @@ var init_wasix_host = __esm({
10601
10616
  const v = mem.view();
10602
10617
  const timed = timeoutPtr !== 0 && v.getUint8(timeoutPtr) === 1;
10603
10618
  const ms = timed ? Number(v.getBigUint64(timeoutPtr + 8, true)) / 1e6 : Number.POSITIVE_INFINITY;
10604
- v.setUint8(
10605
- wokenPtr,
10606
- futexWait(i32(), ptr >> 2, expected | 0, ms, host.interrupted) ? 1 : 0
10607
- );
10619
+ const woken = host.entered || futexWait(i32(), ptr >> 2, expected | 0, ms, host.interrupted);
10620
+ v.setUint8(wokenPtr, woken ? 1 : 0);
10608
10621
  },
10609
10622
  futex_wake: (ptr, wokenPtr) => {
10610
10623
  Atomics.notify(i32(), ptr >> 2, 1);
@@ -10772,9 +10785,10 @@ function delivering(ns, table, host, driver, before) {
10772
10785
  }
10773
10786
  const fn = value2;
10774
10787
  out[name2] = (...args) => {
10788
+ host.entered = false;
10775
10789
  if (driver.idle) {
10776
10790
  before?.();
10777
- host.interrupted?.();
10791
+ host.entered = host.interrupted?.() === true;
10778
10792
  }
10779
10793
  return fn(...args);
10780
10794
  };
@@ -12383,11 +12397,20 @@ function plain(status2, text) {
12383
12397
  headers: { "content-type": "text/plain; charset=utf-8" }
12384
12398
  });
12385
12399
  }
12400
+ function local2(url) {
12401
+ return isKernelLoopbackHost(new URL(url).hostname);
12402
+ }
12386
12403
  function rewrite(hop, status2, location) {
12387
12404
  const next2 = new URL(location, hop.url);
12388
12405
  if (next2.protocol !== "http:" && next2.protocol !== "https:") {
12389
12406
  throw failed3(new JsCallError("EPROTONOSUPPORT", next2.protocol));
12390
12407
  }
12408
+ if (local2(next2.href) && !local2(hop.url)) {
12409
+ const from = new URL(hop.url).origin;
12410
+ throw failed3(
12411
+ new JsCallError("EACCES", `a redirect from ${from} into the kernel's loopback: ${next2.href}`)
12412
+ );
12413
+ }
12391
12414
  const toGet = (status2 === 301 || status2 === 302) && hop.method === "POST" || status2 === 303 && hop.method !== "GET" && hop.method !== "HEAD";
12392
12415
  const crossOrigin = next2.origin !== new URL(hop.url).origin;
12393
12416
  const headers = hop.headers.filter(
@@ -12556,13 +12579,15 @@ async function bodyOf(request, cap, signal) {
12556
12579
  return out;
12557
12580
  }
12558
12581
  function fetchOp(kernel) {
12559
- let traits;
12560
- const traitsOf = () => {
12561
- traits ??= kernel.json({ op: "net-traits" });
12562
- traits.catch(() => {
12563
- traits = void 0;
12582
+ const traits = /* @__PURE__ */ new Map();
12583
+ const traitsOf = (url) => {
12584
+ const own = local2(url);
12585
+ const known = traits.get(own) ?? kernel.json({ op: "net-traits", url });
12586
+ traits.set(own, known);
12587
+ known.catch(() => {
12588
+ traits.delete(own);
12564
12589
  });
12565
- return traits;
12590
+ return known;
12566
12591
  };
12567
12592
  const close = (handle) => kernel.raw({ op: "net-close", handle });
12568
12593
  const send = async (hop, signal) => {
@@ -12649,6 +12674,13 @@ function fetchOp(kernel) {
12649
12674
  });
12650
12675
  return withMeta(response, head.url, redirected);
12651
12676
  };
12677
+ const traitsAt = (at) => traitsOf(at).catch((err) => {
12678
+ throw failed3(err);
12679
+ });
12680
+ const redirect = async (hop, status2, location, known) => {
12681
+ const next2 = rewrite(hop, status2, location);
12682
+ return [next2, local2(next2.url) === local2(hop.url) ? known : await traitsAt(next2.url)];
12683
+ };
12652
12684
  return async (input, init) => {
12653
12685
  const request = new Request(input, init);
12654
12686
  const { signal } = request;
@@ -12658,9 +12690,7 @@ function fetchOp(kernel) {
12658
12690
  if (protocol !== "http:" && protocol !== "https:") {
12659
12691
  throw failed3(new JsCallError("EPROTONOSUPPORT", protocol));
12660
12692
  }
12661
- const known = await traitsOf().catch((err) => {
12662
- throw failed3(err);
12663
- });
12693
+ let known = await traitsAt(request.url);
12664
12694
  if (!known.manualRedirects && request.redirect !== "follow") {
12665
12695
  throw failed3(new JsCallError("ENOTSUP", `redirect: ${request.redirect}`));
12666
12696
  }
@@ -12686,7 +12716,7 @@ function fetchOp(kernel) {
12686
12716
  await close(head.handle);
12687
12717
  if (request.redirect === "error") throw failed3(new JsCallError("EREDIRECT", hop.url));
12688
12718
  if (hops >= MAX_REDIRECTS) throw failed3(new JsCallError("ELOOP", hop.url));
12689
- hop = rewrite(hop, head.status, location);
12719
+ [hop, known] = await redirect(hop, head.status, location, known);
12690
12720
  }
12691
12721
  };
12692
12722
  }
@@ -12694,6 +12724,7 @@ var CHUNK2, MAX_REDIRECTS, NULL_BODY, REDIRECTS, BODY_HEADERS, DECODED, CREDENTI
12694
12724
  var init_js_fetch = __esm({
12695
12725
  "src/process/js/js-fetch.ts"() {
12696
12726
  "use strict";
12727
+ init_loopback_names();
12697
12728
  init_js_kernel();
12698
12729
  CHUNK2 = 64 * 1024;
12699
12730
  MAX_REDIRECTS = 20;
@@ -12733,7 +12764,7 @@ function port(n) {
12733
12764
  function netOps(kernel, io) {
12734
12765
  const name2 = async (fd, peer) => addressOf(await kernel.json({ op: "sock-name", fd, peer }));
12735
12766
  const connection = async (fd) => {
12736
- const [local2, remote] = [await name2(fd, false), await name2(fd, true)];
12767
+ const [local3, remote] = [await name2(fd, false), await name2(fd, true)];
12737
12768
  const stop = new AbortController();
12738
12769
  let closed;
12739
12770
  const close = () => {
@@ -12758,7 +12789,7 @@ function netOps(kernel, io) {
12758
12789
  close: async () => void await shut(SHUT_WR),
12759
12790
  abort: () => close()
12760
12791
  });
12761
- return { fd, local: local2, remote, readable: readable3, writable: writable2, close };
12792
+ return { fd, local: local3, remote, readable: readable3, writable: writable2, close };
12762
12793
  };
12763
12794
  const resolve = async (host, signal) => {
12764
12795
  if (IPV4.test(host)) return host;