sandboxedjs 0.1.53 → 0.1.55
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/agent.d.cts +2 -2
- package/dist/agent.d.ts +2 -2
- package/dist/{container-B--ykWn3.d.cts → container-BAgb9I06.d.ts} +1 -1
- package/dist/{container-BSW6jjlq.d.ts → container-CY_hS650.d.cts} +1 -1
- package/dist/{vfs-DzEcPbMY.d.cts → contracts-CVgctitO.d.cts} +196 -136
- package/dist/{vfs-DzEcPbMY.d.ts → contracts-CVgctitO.d.ts} +196 -136
- package/dist/index.cjs +553 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -6
- package/dist/index.d.ts +11 -6
- package/dist/index.js +553 -9
- package/dist/index.js.map +1 -1
- package/dist/{memory-volume-CTOXNJ6n.d.ts → memory-volume-CWuWScIs.d.ts} +1 -1
- package/dist/{memory-volume-DCzGZFJb.d.cts → memory-volume-DlMSAh-K.d.cts} +1 -1
- package/dist/python-abi.cjs +299 -2
- package/dist/python-abi.cjs.map +1 -1
- package/dist/python-abi.d.cts +265 -226
- package/dist/python-abi.d.ts +265 -226
- package/dist/python-abi.js +299 -2
- package/dist/python-abi.js.map +1 -1
- package/dist/python-worker.js +57 -1
- package/dist/python-worker.js.map +1 -1
- package/dist/worker-entry.js +5 -1
- package/dist/worker-entry.js.map +1 -1
- package/package.json +1 -1
package/dist/python-abi.js
CHANGED
|
@@ -33,7 +33,20 @@ var Op = {
|
|
|
33
33
|
getcwd: 1281,
|
|
34
34
|
chdir: 1282,
|
|
35
35
|
environ: 1283,
|
|
36
|
-
getrandom: 1536
|
|
36
|
+
getrandom: 1536,
|
|
37
|
+
socket: 1792,
|
|
38
|
+
bind: 1793,
|
|
39
|
+
listen: 1794,
|
|
40
|
+
accept: 1795,
|
|
41
|
+
connect: 1796,
|
|
42
|
+
send: 1797,
|
|
43
|
+
recv: 1798,
|
|
44
|
+
shutdown: 1799,
|
|
45
|
+
getsockname: 1800,
|
|
46
|
+
getpeername: 1801,
|
|
47
|
+
setsockopt: 1802,
|
|
48
|
+
getsockopt: 1803,
|
|
49
|
+
socket_close: 1804
|
|
37
50
|
};
|
|
38
51
|
var Errno = {
|
|
39
52
|
EPERM: 1,
|
|
@@ -70,6 +83,15 @@ var Errno = {
|
|
|
70
83
|
ENOTEMPTY: 39,
|
|
71
84
|
ELOOP: 40,
|
|
72
85
|
ENODATA: 61,
|
|
86
|
+
ENOTSOCK: 88,
|
|
87
|
+
EAFNOSUPPORT: 97,
|
|
88
|
+
EADDRINUSE: 98,
|
|
89
|
+
EADDRNOTAVAIL: 99,
|
|
90
|
+
ENETUNREACH: 101,
|
|
91
|
+
ECONNRESET: 104,
|
|
92
|
+
EISCONN: 106,
|
|
93
|
+
ENOTCONN: 107,
|
|
94
|
+
ECONNREFUSED: 111,
|
|
73
95
|
EPROTO: 71,
|
|
74
96
|
EOVERFLOW: 75,
|
|
75
97
|
ETIMEDOUT: 110,
|
|
@@ -1079,6 +1101,170 @@ var FileService = class {
|
|
|
1079
1101
|
}
|
|
1080
1102
|
};
|
|
1081
1103
|
|
|
1104
|
+
// src/net/virtual-socket.ts
|
|
1105
|
+
var VirtualTcpSocket = class _VirtualTcpSocket {
|
|
1106
|
+
constructor(network) {
|
|
1107
|
+
this.network = network;
|
|
1108
|
+
}
|
|
1109
|
+
network;
|
|
1110
|
+
listenerValue = null;
|
|
1111
|
+
connectionValue = null;
|
|
1112
|
+
boundPort = 0;
|
|
1113
|
+
boundAddress = "0.0.0.0";
|
|
1114
|
+
bind(address, port) {
|
|
1115
|
+
if (this.listenerValue || this.connectionValue || this.boundPort !== 0) {
|
|
1116
|
+
throw new PosixError(Errno.EINVAL, "socket is already bound");
|
|
1117
|
+
}
|
|
1118
|
+
this.boundAddress = address;
|
|
1119
|
+
this.boundPort = port;
|
|
1120
|
+
}
|
|
1121
|
+
listen(backlog) {
|
|
1122
|
+
if (this.listenerValue) return;
|
|
1123
|
+
if (this.boundPort === 0) {
|
|
1124
|
+
const port = this.findEphemeralPort();
|
|
1125
|
+
this.boundPort = port;
|
|
1126
|
+
}
|
|
1127
|
+
this.listenerValue = this.network.listen(this.boundPort, this.boundAddress, backlog);
|
|
1128
|
+
}
|
|
1129
|
+
connect(port, address = "127.0.0.1") {
|
|
1130
|
+
if (this.listenerValue || this.connectionValue) throw new PosixError(Errno.EISCONN);
|
|
1131
|
+
this.connectionValue = this.network.connect(port, this.boundPort, this.boundAddress);
|
|
1132
|
+
this.boundPort = this.connectionValue.local.port;
|
|
1133
|
+
this.boundAddress = this.connectionValue.local.address;
|
|
1134
|
+
}
|
|
1135
|
+
accept() {
|
|
1136
|
+
if (!this.listenerValue) throw new PosixError(Errno.EINVAL, "socket is not listening");
|
|
1137
|
+
const accepted = this.listenerValue.accept().connection;
|
|
1138
|
+
const socket = new _VirtualTcpSocket(this.network);
|
|
1139
|
+
socket.connectionValue = accepted;
|
|
1140
|
+
socket.boundPort = accepted.local.port;
|
|
1141
|
+
socket.boundAddress = accepted.local.address;
|
|
1142
|
+
return socket;
|
|
1143
|
+
}
|
|
1144
|
+
get listener() {
|
|
1145
|
+
return this.listenerValue;
|
|
1146
|
+
}
|
|
1147
|
+
get connection() {
|
|
1148
|
+
return this.connectionValue;
|
|
1149
|
+
}
|
|
1150
|
+
get local() {
|
|
1151
|
+
return { address: this.boundAddress, port: this.boundPort };
|
|
1152
|
+
}
|
|
1153
|
+
get remote() {
|
|
1154
|
+
return this.connectionValue?.remote ?? null;
|
|
1155
|
+
}
|
|
1156
|
+
get readable() {
|
|
1157
|
+
return this.listenerValue?.readable ?? this.connectionValue?.readable ?? false;
|
|
1158
|
+
}
|
|
1159
|
+
get writable() {
|
|
1160
|
+
return this.connectionValue?.writable ?? false;
|
|
1161
|
+
}
|
|
1162
|
+
waitForChange() {
|
|
1163
|
+
return (this.listenerValue ?? this.connectionValue)?.waitForChange() ?? Promise.resolve();
|
|
1164
|
+
}
|
|
1165
|
+
read(length) {
|
|
1166
|
+
if (!this.connectionValue) throw new PosixError(Errno.EINVAL);
|
|
1167
|
+
return this.connectionValue.read(length);
|
|
1168
|
+
}
|
|
1169
|
+
write(data) {
|
|
1170
|
+
if (!this.connectionValue) throw new PosixError(Errno.EINVAL);
|
|
1171
|
+
return this.connectionValue.write(data);
|
|
1172
|
+
}
|
|
1173
|
+
shutdown(read, write) {
|
|
1174
|
+
if (!this.connectionValue) throw new PosixError(Errno.ENOTCONN);
|
|
1175
|
+
this.connectionValue.shutdown(read, write);
|
|
1176
|
+
}
|
|
1177
|
+
close() {
|
|
1178
|
+
if (this.listenerValue) this.network.close(this.listenerValue);
|
|
1179
|
+
this.connectionValue?.close();
|
|
1180
|
+
this.listenerValue = null;
|
|
1181
|
+
this.connectionValue = null;
|
|
1182
|
+
}
|
|
1183
|
+
findEphemeralPort() {
|
|
1184
|
+
for (let port = 49152; port <= 65535; port += 1) if (!this.network.hasListener(port)) return port;
|
|
1185
|
+
throw new PosixError(Errno.EADDRINUSE, "no ephemeral ports available");
|
|
1186
|
+
}
|
|
1187
|
+
};
|
|
1188
|
+
var SocketDescription = class _SocketDescription {
|
|
1189
|
+
kind = "socket";
|
|
1190
|
+
flags;
|
|
1191
|
+
resource;
|
|
1192
|
+
closed = false;
|
|
1193
|
+
options = /* @__PURE__ */ new Map();
|
|
1194
|
+
constructor(resource, flags = 0) {
|
|
1195
|
+
this.resource = resource;
|
|
1196
|
+
this.flags = flags;
|
|
1197
|
+
}
|
|
1198
|
+
get listener() {
|
|
1199
|
+
return this.resource.listener;
|
|
1200
|
+
}
|
|
1201
|
+
get connection() {
|
|
1202
|
+
return this.resource.connection;
|
|
1203
|
+
}
|
|
1204
|
+
read(length) {
|
|
1205
|
+
return this.resource.read(length);
|
|
1206
|
+
}
|
|
1207
|
+
write(data) {
|
|
1208
|
+
return this.resource.write(data);
|
|
1209
|
+
}
|
|
1210
|
+
readable() {
|
|
1211
|
+
return this.resource.readable;
|
|
1212
|
+
}
|
|
1213
|
+
writable() {
|
|
1214
|
+
return this.resource.writable;
|
|
1215
|
+
}
|
|
1216
|
+
whenReady() {
|
|
1217
|
+
return this.resource.waitForChange();
|
|
1218
|
+
}
|
|
1219
|
+
stat() {
|
|
1220
|
+
return {
|
|
1221
|
+
ino: 0,
|
|
1222
|
+
mode: 49663,
|
|
1223
|
+
size: 0,
|
|
1224
|
+
uid: 0,
|
|
1225
|
+
gid: 0,
|
|
1226
|
+
nlink: 1,
|
|
1227
|
+
atimeMs: Date.now(),
|
|
1228
|
+
mtimeMs: Date.now(),
|
|
1229
|
+
ctimeMs: Date.now()
|
|
1230
|
+
};
|
|
1231
|
+
}
|
|
1232
|
+
close() {
|
|
1233
|
+
if (this.closed) return;
|
|
1234
|
+
this.closed = true;
|
|
1235
|
+
this.resource.close();
|
|
1236
|
+
}
|
|
1237
|
+
bind(address, port) {
|
|
1238
|
+
this.resource.bind(address, port);
|
|
1239
|
+
}
|
|
1240
|
+
listen(backlog) {
|
|
1241
|
+
this.resource.listen(backlog);
|
|
1242
|
+
}
|
|
1243
|
+
connect(address, port) {
|
|
1244
|
+
this.resource.connect(port, address);
|
|
1245
|
+
}
|
|
1246
|
+
accept() {
|
|
1247
|
+
return new _SocketDescription(this.resource.accept(), this.flags);
|
|
1248
|
+
}
|
|
1249
|
+
shutdown(read, write) {
|
|
1250
|
+
this.resource.shutdown(read, write);
|
|
1251
|
+
}
|
|
1252
|
+
setOption(level, option, value) {
|
|
1253
|
+
this.options.set(`${level}:${option}`, value.slice());
|
|
1254
|
+
}
|
|
1255
|
+
getOption(level, option) {
|
|
1256
|
+
return this.options.get(`${level}:${option}`)?.slice() ?? new Uint8Array(4);
|
|
1257
|
+
}
|
|
1258
|
+
localAddress() {
|
|
1259
|
+
return this.resource.local;
|
|
1260
|
+
}
|
|
1261
|
+
peerAddress() {
|
|
1262
|
+
const peer = this.resource.remote;
|
|
1263
|
+
if (!peer) throw new PosixError(Errno.ENOTCONN);
|
|
1264
|
+
return peer;
|
|
1265
|
+
}
|
|
1266
|
+
};
|
|
1267
|
+
|
|
1082
1268
|
// src/runtime/python/syscall-server.ts
|
|
1083
1269
|
var MAX_TRANSFER = 8 * 1024 * 1024;
|
|
1084
1270
|
function createHostAbiServer(proc) {
|
|
@@ -1325,12 +1511,76 @@ function createHostAbiServer(proc) {
|
|
|
1325
1511
|
crypto.getRandomValues(bytes);
|
|
1326
1512
|
return { status: length, payload: bytes };
|
|
1327
1513
|
}
|
|
1514
|
+
/* ----------------------------------------------------------- sockets */
|
|
1515
|
+
case Op.socket: {
|
|
1516
|
+
const family = r.u32();
|
|
1517
|
+
const type = r.u32();
|
|
1518
|
+
const protocol = r.i32();
|
|
1519
|
+
if (family !== 2 || (type & 15) !== 1 || protocol !== 0) throw new PosixError(Errno.EAFNOSUPPORT);
|
|
1520
|
+
if (!proc.sockets) throw new PosixError(Errno.ENOSYS);
|
|
1521
|
+
return { status: proc.table.add(new SocketDescription(new VirtualTcpSocket(proc.sockets))) };
|
|
1522
|
+
}
|
|
1523
|
+
case Op.bind: {
|
|
1524
|
+
const description = socketDescription(proc.table.get(r.i32()));
|
|
1525
|
+
description.bind(r.string(), r.u32());
|
|
1526
|
+
return { status: 0 };
|
|
1527
|
+
}
|
|
1528
|
+
case Op.listen: {
|
|
1529
|
+
const description = socketDescription(proc.table.get(r.i32()));
|
|
1530
|
+
description.listen(Math.max(1, Math.min(1024, r.u32())));
|
|
1531
|
+
return { status: 0 };
|
|
1532
|
+
}
|
|
1533
|
+
case Op.accept: {
|
|
1534
|
+
const description = socketDescription(proc.table.get(r.i32()));
|
|
1535
|
+
const accepted = await acceptBlocking(description);
|
|
1536
|
+
const fd = proc.table.add(accepted);
|
|
1537
|
+
const peer = accepted.peerAddress();
|
|
1538
|
+
return { status: fd, payload: new Writer().string(peer.address).u32(peer.port).finish() };
|
|
1539
|
+
}
|
|
1540
|
+
case Op.connect: {
|
|
1541
|
+
const description = socketDescription(proc.table.get(r.i32()));
|
|
1542
|
+
description.connect(r.string(), r.u32());
|
|
1543
|
+
return { status: 0 };
|
|
1544
|
+
}
|
|
1545
|
+
case Op.send: {
|
|
1546
|
+
const description = socketDescription(proc.table.get(r.i32()));
|
|
1547
|
+
return { status: await writeBlocking(description, r.bytes32()) };
|
|
1548
|
+
}
|
|
1549
|
+
case Op.recv: {
|
|
1550
|
+
const description = socketDescription(proc.table.get(r.i32()));
|
|
1551
|
+
const data = await readBlocking(description, clamp(r.u32()));
|
|
1552
|
+
return { status: data.length, payload: data };
|
|
1553
|
+
}
|
|
1554
|
+
case Op.shutdown: {
|
|
1555
|
+
const description = socketDescription(proc.table.get(r.i32()));
|
|
1556
|
+
const how = r.u32();
|
|
1557
|
+
if (how > 2) throw new PosixError(Errno.EINVAL);
|
|
1558
|
+
description.shutdown(how === 0 || how === 2, how === 1 || how === 2);
|
|
1559
|
+
return { status: 0 };
|
|
1560
|
+
}
|
|
1561
|
+
case Op.getsockname: {
|
|
1562
|
+
const address = socketDescription(proc.table.get(r.i32())).localAddress();
|
|
1563
|
+
return { status: 0, payload: new Writer().string(address.address).u32(address.port).finish() };
|
|
1564
|
+
}
|
|
1565
|
+
case Op.getpeername: {
|
|
1566
|
+
const address = socketDescription(proc.table.get(r.i32())).peerAddress();
|
|
1567
|
+
return { status: 0, payload: new Writer().string(address.address).u32(address.port).finish() };
|
|
1568
|
+
}
|
|
1569
|
+
case Op.setsockopt: {
|
|
1570
|
+
const description = socketDescription(proc.table.get(r.i32()));
|
|
1571
|
+
description.setOption(r.u32(), r.u32(), r.bytes32());
|
|
1572
|
+
return { status: 0 };
|
|
1573
|
+
}
|
|
1574
|
+
case Op.getsockopt: {
|
|
1575
|
+
const description = socketDescription(proc.table.get(r.i32()));
|
|
1576
|
+
return { status: 0, payload: new Writer().bytes32(description.getOption(r.u32(), r.u32())).finish() };
|
|
1577
|
+
}
|
|
1328
1578
|
default:
|
|
1329
1579
|
return { status: failure(Errno.ENOSYS) };
|
|
1330
1580
|
}
|
|
1331
1581
|
}
|
|
1332
1582
|
function implemented(capability) {
|
|
1333
|
-
return ["files", "descriptors", "pipes", "readiness", "time", "identity", "entropy"].includes(capability);
|
|
1583
|
+
return ["files", "descriptors", "pipes", "readiness", "time", "identity", "entropy"].includes(capability) || capability === "sockets" && proc.sockets !== void 0;
|
|
1334
1584
|
}
|
|
1335
1585
|
function resolve2(path) {
|
|
1336
1586
|
if (path.startsWith("/")) return proc.vfs.resolvePath(path);
|
|
@@ -1339,6 +1589,22 @@ function createHostAbiServer(proc) {
|
|
|
1339
1589
|
function clamp(length) {
|
|
1340
1590
|
return Math.min(length, MAX_TRANSFER);
|
|
1341
1591
|
}
|
|
1592
|
+
function socketDescription(description) {
|
|
1593
|
+
if (!(description instanceof SocketDescription)) throw new PosixError(Errno.ENOTSOCK, "descriptor is not a socket");
|
|
1594
|
+
return description;
|
|
1595
|
+
}
|
|
1596
|
+
async function acceptBlocking(description) {
|
|
1597
|
+
for (; ; ) {
|
|
1598
|
+
try {
|
|
1599
|
+
return description.accept();
|
|
1600
|
+
} catch (error) {
|
|
1601
|
+
const posix = toPosixError(error);
|
|
1602
|
+
if (posix.errno !== Errno.EAGAIN || description.flags & O_NONBLOCK) throw posix;
|
|
1603
|
+
}
|
|
1604
|
+
await Promise.race([description.whenReady(), aborted()]);
|
|
1605
|
+
if (proc.signal.aborted) throw new PosixError(Errno.EINTR);
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1342
1608
|
async function readBlocking(description, length) {
|
|
1343
1609
|
for (; ; ) {
|
|
1344
1610
|
try {
|
|
@@ -1559,6 +1825,37 @@ var HostAbiClient = class {
|
|
|
1559
1825
|
getrandom(length) {
|
|
1560
1826
|
return this.call(Op.getrandom, new Writer().u32(length).finish()).payload;
|
|
1561
1827
|
}
|
|
1828
|
+
socket(family, type, protocol = 0) {
|
|
1829
|
+
return this.call(Op.socket, new Writer().u32(family).u32(type).i32(protocol).finish()).status;
|
|
1830
|
+
}
|
|
1831
|
+
bind(fd, address, port) {
|
|
1832
|
+
this.call(Op.bind, new Writer().i32(fd).string(address).u32(port).finish());
|
|
1833
|
+
}
|
|
1834
|
+
listen(fd, backlog = 128) {
|
|
1835
|
+
this.call(Op.listen, new Writer().i32(fd).u32(backlog).finish());
|
|
1836
|
+
}
|
|
1837
|
+
accept(fd) {
|
|
1838
|
+
const result = this.call(Op.accept, new Writer().i32(fd).finish());
|
|
1839
|
+
const r = new Reader(result.payload);
|
|
1840
|
+
return { fd: result.status, address: r.string(), port: r.u32() };
|
|
1841
|
+
}
|
|
1842
|
+
connect(fd, address, port) {
|
|
1843
|
+
this.call(Op.connect, new Writer().i32(fd).string(address).u32(port).finish());
|
|
1844
|
+
}
|
|
1845
|
+
send(fd, data) {
|
|
1846
|
+
return this.call(Op.send, new Writer().i32(fd).bytes32(data).finish()).status;
|
|
1847
|
+
}
|
|
1848
|
+
recv(fd, length) {
|
|
1849
|
+
return this.call(Op.recv, new Writer().i32(fd).u32(length).finish()).payload;
|
|
1850
|
+
}
|
|
1851
|
+
shutdown(fd, how) {
|
|
1852
|
+
this.call(Op.shutdown, new Writer().i32(fd).u32(how).finish());
|
|
1853
|
+
}
|
|
1854
|
+
socketName(fd, peer = false) {
|
|
1855
|
+
const payload = this.call(peer ? Op.getpeername : Op.getsockname, new Writer().i32(fd).finish()).payload;
|
|
1856
|
+
const r = new Reader(payload);
|
|
1857
|
+
return { address: r.string(), port: r.u32() };
|
|
1858
|
+
}
|
|
1562
1859
|
};
|
|
1563
1860
|
function decodeStat(payload) {
|
|
1564
1861
|
const r = new Reader(payload);
|