@poe-platform/safe-bash 0.1.802 → 0.1.803
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 +4 -2
- package/dist/image-ast/index.browser.js +13 -4
- package/dist/image-ast/index.js +13 -4
- package/dist/safe-bash/chunks/{chunk-KDNSPLII.js → chunk-2LSAMQER.js} +1 -0
- package/dist/safe-bash/chunks/{chunk-NZQXYWA3.js → chunk-5OHX7C2V.js} +0 -1
- package/dist/safe-bash/chunks/{chunk-SHEMU2Z7.js → chunk-B7PIL77G.js} +82 -63
- package/dist/safe-bash/chunks/{chunk-WDLGKIHD.js → chunk-EEEWOYEG.js} +4 -4
- package/dist/safe-bash/chunks/{chunk-GETUOD5D.js → chunk-GDYNCWRV.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-RSTHLAF3.js → chunk-JMMEIDPF.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-44ALJ4QG.js → chunk-PNBBUWSM.js} +71 -55
- package/dist/safe-bash/chunks/{chunk-NQCM3TYR.js → chunk-RYFQ3LZG.js} +73 -44
- package/dist/safe-bash/chunks/chunk-VBTDHOWC.js +55 -0
- package/dist/safe-bash/command-chunks/{chunk-ORYGZYKW.js → chunk-4FEVBOL5.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-VXSLJH7G.js → chunk-6JSIFWYT.js} +26 -6
- package/dist/safe-bash/command-chunks/chunk-A7MU7762.js +200 -0
- package/dist/safe-bash/command-chunks/{chunk-KJIMDLBB.js → chunk-BXCXRYVU.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-F4TEEZTL.js → chunk-CQHP3I66.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-PEF7K3UQ.js → chunk-EARHPPPJ.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-QKFSRZGQ.js → chunk-GFC2NTDG.js} +2 -2
- package/dist/safe-bash/command-chunks/chunk-GIRNFXP3.js +466 -0
- package/dist/safe-bash/command-chunks/{chunk-FPVUD6TH.js → chunk-HDCNKOIX.js} +9 -7
- package/dist/safe-bash/command-chunks/{chunk-MQFIPHIQ.js → chunk-ILX2NOLF.js} +18 -15
- package/dist/safe-bash/command-chunks/{chunk-5E4WAO4O.js → chunk-JD5QNRNO.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-I237SNW5.js → chunk-LFJJQQND.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-W5DNF4JH.js → chunk-LOICUCHG.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-7U7EXOXX.js → chunk-NASVPT6F.js} +2 -1
- package/dist/safe-bash/command-chunks/{chunk-OQKC5ZU2.js → chunk-NKIELG7Y.js} +22 -1
- package/dist/safe-bash/command-chunks/{chunk-WPYIOKE3.js → chunk-PICVQ6B5.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-YOFC45RK.js → chunk-QVOS4YXL.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-VGG2DL5Q.js → chunk-TRR4MYWF.js} +4 -0
- package/dist/safe-bash/command-chunks/{chunk-2JRBIDAD.js → chunk-V4K2JDYU.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-6GWJUQAV.js → chunk-WWIBP2ET.js} +38 -111
- package/dist/safe-bash/command-chunks/chunk-ZDN7MJE6.js +168 -0
- package/dist/safe-bash/commands/bytes/compression/index.js +54 -51
- package/dist/safe-bash/commands/chmod/index.browser.js +14 -0
- package/dist/safe-bash/commands/chmod/index.d.ts +2 -0
- package/dist/safe-bash/commands/chmod/index.js +2 -0
- package/dist/safe-bash/commands/metadata/chmod.d.ts +1 -7
- package/dist/safe-bash/commands/metadata/chmod.js +1 -204
- package/dist/safe-bash/commands/metadata/index.browser.js +1 -5
- package/dist/safe-bash/commands/metadata/internal.d.ts +1 -30
- package/dist/safe-bash/commands/metadata/internal.js +1 -76
- package/dist/safe-bash/commands/metadata/mktemp.d.ts +1 -3
- package/dist/safe-bash/commands/metadata/mktemp.js +1 -202
- package/dist/safe-bash/commands/metadata/stat.d.ts +1 -7
- package/dist/safe-bash/commands/metadata/stat.js +1 -530
- package/dist/safe-bash/commands/mktemp/index.browser.js +13 -0
- package/dist/safe-bash/commands/mktemp/index.d.ts +2 -0
- package/dist/safe-bash/commands/mktemp/index.js +2 -0
- package/dist/safe-bash/commands/node/index.browser.js +2 -2
- package/dist/safe-bash/commands/portable-random.d.ts +1 -1
- package/dist/safe-bash/commands/portable-random.js +1 -12
- package/dist/safe-bash/commands/python/index.browser.js +3 -3
- package/dist/safe-bash/commands/stat/index.browser.js +13 -0
- package/dist/safe-bash/commands/stat/index.d.ts +2 -0
- package/dist/safe-bash/commands/stat/index.js +2 -0
- package/dist/safe-bash/commands/text.js +46 -10
- package/dist/safe-bash/full-core.browser.js +86 -86
- package/dist/safe-bash/jobs.browser.js +2 -2
- package/dist/safe-bash/opt-in/commands/yq/native-work.js +1 -0
- package/dist/safe-bash/optional-host.browser.js +10 -10
- package/dist/safe-bash/plugins/index.browser.js +13 -13
- package/dist/safe-bash/registry-entry.browser.js +16 -16
- package/dist/safe-bash/search.browser.js +14 -14
- package/dist/safe-bash/shell/runtime.d.ts +3 -0
- package/dist/safe-bash/shell/runtime.js +20 -3
- package/dist/safe-bash/shell/types.d.ts +2 -0
- package/dist/safe-bash/shell/worker-limits.js +1 -0
- package/dist/safe-bash/shell-entry.browser.js +12 -12
- package/dist/safe-bash/worker/host.js +1 -1
- package/dist/safe-bash-command-bc/index.js +12 -5
- package/dist/safe-bash-command-bzip2/index.js +4 -3
- package/dist/safe-bash-command-chmod/LICENSE +21 -0
- package/dist/safe-bash-command-chmod/command.d.ts +7 -0
- package/dist/safe-bash-command-chmod/command.js +11 -0
- package/dist/safe-bash-command-chmod/index.d.ts +6 -0
- package/dist/safe-bash-command-chmod/index.js +27 -0
- package/dist/safe-bash-command-exiftool/index.js +5 -5
- package/dist/safe-bash-command-find/find.js +1 -1
- package/dist/safe-bash-command-find/index.js +1 -1
- package/dist/safe-bash-command-fmt/index.js +9 -2
- package/dist/safe-bash-command-gzip/index.js +45 -42
- package/dist/safe-bash-command-imagemagick/index.js +3 -1
- package/dist/safe-bash-command-jq/index.js +1 -1
- package/dist/safe-bash-command-jq/jq.js +1 -1
- package/dist/safe-bash-command-less/index.js +12 -3
- package/dist/safe-bash-command-mktemp/LICENSE +21 -0
- package/dist/safe-bash-command-mktemp/command.d.ts +3 -0
- package/dist/safe-bash-command-mktemp/command.js +9 -0
- package/dist/safe-bash-command-mktemp/index.d.ts +6 -0
- package/dist/safe-bash-command-mktemp/index.js +25 -0
- package/dist/safe-bash-command-od/index.js +6 -2
- package/dist/safe-bash-command-op/index.js +25 -6
- package/dist/safe-bash-command-rg/index.js +1 -1
- package/dist/safe-bash-command-rg/rg-command.js +1 -1
- package/dist/safe-bash-command-sed/index.js +1 -1
- package/dist/safe-bash-command-sed/sed.js +1 -1
- package/dist/safe-bash-command-sips/index.js +13 -5
- package/dist/safe-bash-command-sponge/index.js +10 -3
- package/dist/safe-bash-command-stat/LICENSE +21 -0
- package/dist/safe-bash-command-stat/command.d.ts +7 -0
- package/dist/safe-bash-command-stat/command.js +9 -0
- package/dist/safe-bash-command-stat/index.d.ts +6 -0
- package/dist/safe-bash-command-stat/index.js +25 -0
- package/dist/safe-bash-command-unrtf/index.js +11 -1
- package/dist/safe-bash-command-xxd/index.js +6 -2
- package/dist/safe-bash-command-xz/command.d.ts +1 -1
- package/dist/safe-bash-command-xz/index.js +3 -2
- package/dist/safe-bash-command-yq/index.js +1 -0
- package/dist/safe-bash-command-yq/native-work.js +1 -0
- package/dist/safe-bash-command-yq/query.js +3 -0
- package/dist/safe-bash-compression-engine/bounded-codec.js +3 -3
- package/dist/safe-bash-compression-engine/codec-loader.js +2 -2
- package/dist/safe-bash-compression-engine/files.js +6 -6
- package/dist/safe-bash-compression-engine/index.js +5 -5
- package/dist/safe-bash-compression-engine/operand.js +6 -6
- package/dist/safe-bash-compression-engine/options.js +1 -1
- package/dist/safe-bash-compression-engine/stream.js +5 -5
- package/dist/safe-bash-compression-engine/zstd-decode.js +4 -4
- package/dist/safe-bash-contracts/escaping.js +2 -2
- package/dist/safe-bash-contracts/filesystem-output.js +2 -2
- package/dist/safe-bash-contracts/index.js +2 -2
- package/dist/safe-bash-contracts/io.d.ts +2 -0
- package/dist/safe-bash-contracts/io.js +1 -1
- package/dist/safe-bash-contracts/output.js +2 -2
- package/dist/safe-bash-io-engine/commands/search/requirements.js +1 -1
- package/dist/safe-bash-io-engine/commands/text-programs/shared.js +1 -1
- package/dist/safe-bash-mcp/index.browser.js +11 -1
- package/dist/safe-bash-mcp/index.js +35 -16
- package/dist/safe-bash-metadata-engine/LICENSE +21 -0
- package/dist/safe-bash-metadata-engine/index.d.ts +30 -0
- package/dist/safe-bash-metadata-engine/index.js +82 -0
- package/dist/safe-bash-metadata-engine/random.d.ts +1 -0
- package/dist/safe-bash-metadata-engine/random.js +21 -0
- package/dist/safe-bash-regex-engine/index.js +1 -1
- package/dist/safe-bash-regex-engine/text/regex.js +1 -1
- package/dist/safe-bash-search-engine/ergonomic-regex.js +2 -2
- package/dist/safe-bash-search-engine/glob.js +2 -2
- package/dist/safe-bash-search-engine/grep.js +2 -2
- package/dist/safe-bash-search-engine/matcher.js +2 -2
- package/dist/safe-bash-search-engine/options.d.ts +2 -0
- package/dist/safe-bash-search-engine/options.js +1 -1
- package/dist/safe-bash-search-engine/output.js +1 -1
- package/dist/safe-bash-search-engine/shared.js +2 -2
- package/dist/safe-bash-search-engine/walk.js +3 -3
- package/dist/safe-playwright-cloudflare/browser-snapshot-json.js +2 -2
- package/dist/safe-playwright-cloudflare/browser-snapshot-references.js +1 -1
- package/package.json +31 -5
- package/dist/safe-bash/chunks/chunk-VSAJ4OTM.js +0 -962
- package/dist/safe-bash/chunks/{chunk-BJA5XNP6.js → chunk-A7XEHALN.js} +3 -3
|
@@ -163,6 +163,7 @@ export const defaultLimits = {
|
|
|
163
163
|
maxPathnameComponents: Infinity,
|
|
164
164
|
maxRedirects: Infinity,
|
|
165
165
|
maxPipelineStages: Infinity,
|
|
166
|
+
maxPipelineBytes: Infinity,
|
|
166
167
|
maxLoopIterations: Infinity,
|
|
167
168
|
maxSubstitutionDepth: Infinity,
|
|
168
169
|
maxFunctionDepth: Infinity,
|
|
@@ -453,6 +454,7 @@ function tickSharedWallClockBudgets() {
|
|
|
453
454
|
}
|
|
454
455
|
}
|
|
455
456
|
export class Budget {
|
|
457
|
+
pipelineBytes = 0;
|
|
456
458
|
get fileSystemOperations() {
|
|
457
459
|
return this._fileSystemOperations;
|
|
458
460
|
}
|
|
@@ -494,7 +496,7 @@ export class Budget {
|
|
|
494
496
|
this.maxSourceBytesSmi = limits.maxSourceBytes | 0;
|
|
495
497
|
if (limits.maxPipelineStages < 0x3fffffff)
|
|
496
498
|
this.maxPipelineStagesSmi = limits.maxPipelineStages | 0;
|
|
497
|
-
if (limits.pipeHighWaterMark < 65536)
|
|
499
|
+
if (limits.pipeHighWaterMark < 65536 || limits.maxPipelineBytes !== Infinity)
|
|
498
500
|
this.canSyncPurePipe = false;
|
|
499
501
|
this.signal = signal ? combineManagedSignals(signal, this.controller.signal) : this.controller.signal;
|
|
500
502
|
if (signal)
|
|
@@ -643,6 +645,16 @@ export class Budget {
|
|
|
643
645
|
set fsOperations(value) {
|
|
644
646
|
this._fileSystemOperations = value;
|
|
645
647
|
}
|
|
648
|
+
pipelineInput = (bytes) => {
|
|
649
|
+
if (this.limits.maxPipelineBytes === Infinity)
|
|
650
|
+
return;
|
|
651
|
+
this.assertPipelineInput(bytes);
|
|
652
|
+
this.pipelineBytes += bytes;
|
|
653
|
+
};
|
|
654
|
+
assertPipelineInput(bytes) {
|
|
655
|
+
if (bytes > this.limits.maxPipelineBytes - this.pipelineBytes)
|
|
656
|
+
this.fail("maxPipelineBytes");
|
|
657
|
+
}
|
|
646
658
|
reservePipelineStages(count) {
|
|
647
659
|
this.signal.throwIfAborted();
|
|
648
660
|
if (count > this.limits.maxPipelineStages - this._pipelineStages)
|
|
@@ -1493,6 +1505,7 @@ class BudgetedPipeStageSink {
|
|
|
1493
1505
|
return Boolean(w.open && pipe && !pipe.failed && !pipe.signal?.aborted && pipe.readerReferences && (!pipe.writes || pipe.writes.size === 0) && (pipe.availableBytes ?? 0) < (pipe.highWaterMark ?? 0));
|
|
1494
1506
|
}
|
|
1495
1507
|
writeSync(chunk) {
|
|
1508
|
+
this.budget.assertPipelineInput(chunk.byteLength);
|
|
1496
1509
|
this.budget.bytes += chunk.byteLength;
|
|
1497
1510
|
this.writable.write(chunk);
|
|
1498
1511
|
if (chunk.byteLength && this.written)
|
|
@@ -8264,7 +8277,7 @@ export class Runtime {
|
|
|
8264
8277
|
const n = pipeline.commands.length;
|
|
8265
8278
|
this.budget.enterPipelineStages(n);
|
|
8266
8279
|
this.budget.commands += n;
|
|
8267
|
-
const pipeOptions = { highWaterMark: this.budget.limits.pipeHighWaterMark, signal: this.signal };
|
|
8280
|
+
const pipeOptions = { highWaterMark: this.budget.limits.pipeHighWaterMark, signal: this.signal, admitWrite: this.budget.pipelineInput };
|
|
8268
8281
|
const pipes = new Array(n - 1);
|
|
8269
8282
|
for (let i = 0; i < n - 1; i++) {
|
|
8270
8283
|
pipes[i] = createBytePipe(pipeOptions);
|
|
@@ -18326,7 +18339,7 @@ export class Runtime {
|
|
|
18326
18339
|
}
|
|
18327
18340
|
for (let index = 1; index < pipeline.commands.length; index++)
|
|
18328
18341
|
pipes.push(createBytePipe({
|
|
18329
|
-
highWaterMark: this.budget.limits.pipeHighWaterMark, signal: this.signal,
|
|
18342
|
+
highWaterMark: this.budget.limits.pipeHighWaterMark, signal: this.signal, admitWrite: this.budget.pipelineInput,
|
|
18330
18343
|
}));
|
|
18331
18344
|
for (let index = 0; index < pipeline.commands.length; index++) {
|
|
18332
18345
|
controllers.push(createManagedControlController());
|
|
@@ -35476,6 +35489,10 @@ export class Runtime {
|
|
|
35476
35489
|
return true;
|
|
35477
35490
|
}
|
|
35478
35491
|
tryFastPureSubstitution(part, state, rawState, io) {
|
|
35492
|
+
if (!cCollation(rawState.variables.LC_ALL || rawState.variables.LC_COLLATE || rawState.variables.LANG || "C"))
|
|
35493
|
+
return undefined;
|
|
35494
|
+
if (this.budget.limits.maxPipelineBytes !== Infinity)
|
|
35495
|
+
return undefined;
|
|
35479
35496
|
// Synchronous evaluators do not expose cumulative source-read accounting.
|
|
35480
35497
|
// Use the command context whenever the caller has set an input ceiling.
|
|
35481
35498
|
if (this.budget.limits.maxInputBytes !== Infinity)
|
|
@@ -55,6 +55,8 @@ export interface ShellLimits {
|
|
|
55
55
|
* Zero permits only redirect-free commands. Not a global byte or filesystem-call budget. */
|
|
56
56
|
readonly maxRedirects?: number;
|
|
57
57
|
readonly maxPipelineStages?: number;
|
|
58
|
+
/** Cumulative bytes written between pipeline stages per invocation, including nested pipelines. */
|
|
59
|
+
readonly maxPipelineBytes?: number;
|
|
58
60
|
readonly maxLoopIterations?: number;
|
|
59
61
|
readonly maxSubstitutionDepth?: number;
|
|
60
62
|
/** Maximum simultaneously active shell functions; zero rejects function calls. Unlimited when omitted. */
|
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
import {
|
|
2
2
|
cloudflareWorkerLimits
|
|
3
|
-
} from "./chunks/chunk-
|
|
3
|
+
} from "./chunks/chunk-2LSAMQER.js";
|
|
4
4
|
import {
|
|
5
5
|
Shell,
|
|
6
6
|
ShellLimitError,
|
|
7
7
|
ShellSyntaxError,
|
|
8
8
|
parseShell
|
|
9
|
-
} from "./chunks/chunk-
|
|
9
|
+
} from "./chunks/chunk-B7PIL77G.js";
|
|
10
|
+
import "./chunks/chunk-A7XEHALN.js";
|
|
10
11
|
import "./chunks/chunk-TFIBK2GI.js";
|
|
11
12
|
import "./chunks/chunk-3NDIFSNM.js";
|
|
12
|
-
import "./chunks/chunk-
|
|
13
|
+
import "./chunks/chunk-6O77NL2S.js";
|
|
14
|
+
import "./chunks/chunk-PNBBUWSM.js";
|
|
13
15
|
import "./chunks/chunk-MHMMRCYC.js";
|
|
16
|
+
import "./chunks/chunk-OV6IHKO6.js";
|
|
17
|
+
import "./chunks/chunk-CHYGPFVM.js";
|
|
14
18
|
import "./chunks/chunk-AUSNDQTJ.js";
|
|
15
19
|
import "./chunks/chunk-CTVWDACF.js";
|
|
16
20
|
import "./chunks/chunk-3R3AANOR.js";
|
|
17
|
-
import "./chunks/chunk-OV6IHKO6.js";
|
|
18
21
|
import "./chunks/chunk-XVOSKJE2.js";
|
|
19
22
|
import "./chunks/chunk-C5OWC2TL.js";
|
|
20
23
|
import "./chunks/chunk-PH63PLPZ.js";
|
|
21
|
-
import "./chunks/chunk-
|
|
22
|
-
import "./chunks/chunk-6O77NL2S.js";
|
|
23
|
-
import "./chunks/chunk-BJA5XNP6.js";
|
|
24
|
+
import "./chunks/chunk-D3ANYGMC.js";
|
|
24
25
|
import "./chunks/chunk-J42RIHHJ.js";
|
|
25
26
|
import "./chunks/chunk-I5HZ4FGE.js";
|
|
27
|
+
import "./chunks/chunk-VTH3MLDU.js";
|
|
28
|
+
import "./chunks/chunk-5OHX7C2V.js";
|
|
29
|
+
import "./chunks/chunk-74GHTNJA.js";
|
|
26
30
|
import {
|
|
27
31
|
CommandRegistry,
|
|
28
32
|
commandRuntimeIdentity,
|
|
@@ -33,11 +37,7 @@ import "./chunks/chunk-55YJASTN.js";
|
|
|
33
37
|
import "./chunks/chunk-4BSJLKNM.js";
|
|
34
38
|
import "./chunks/chunk-DQP3VHSB.js";
|
|
35
39
|
import "./chunks/chunk-GEG3BWGE.js";
|
|
36
|
-
import "./chunks/chunk-
|
|
37
|
-
import "./chunks/chunk-D3ANYGMC.js";
|
|
38
|
-
import "./chunks/chunk-VTH3MLDU.js";
|
|
39
|
-
import "./chunks/chunk-NZQXYWA3.js";
|
|
40
|
-
import "./chunks/chunk-74GHTNJA.js";
|
|
40
|
+
import "./chunks/chunk-VBTDHOWC.js";
|
|
41
41
|
import "./chunks/chunk-QGUV42T5.js";
|
|
42
42
|
import "./chunks/chunk-ZVD5IS4V.js";
|
|
43
43
|
import "./chunks/chunk-E7OYNDGL.js";
|
|
@@ -14,7 +14,7 @@ export function createWorkerKillAfterPolicy(registry, configuration, requiresMod
|
|
|
14
14
|
// These counters/leases belong to the interpreter, not to a separate Shell.
|
|
15
15
|
// Until a shared ledger is available, refuse rather than reset their quota.
|
|
16
16
|
const limits = runtimeContext?.budget.limits ?? configuration.limits;
|
|
17
|
-
const shared = ["maxCommands", "maxLoopIterations", "maxSourceBytes", "maxParseUnits", "maxExpansionBytes", "maxExpansionFields", "maxPipelineStages", "maxSubstitutionDepth", "maxFunctionDepth", "maxCpuMs"];
|
|
17
|
+
const shared = ["maxCommands", "maxLoopIterations", "maxSourceBytes", "maxParseUnits", "maxExpansionBytes", "maxExpansionFields", "maxPipelineStages", "maxPipelineBytes", "maxSubstitutionDepth", "maxFunctionDepth", "maxCpuMs"];
|
|
18
18
|
if (shared.some(key => limits?.[key] !== undefined && limits[key] !== Infinity)) {
|
|
19
19
|
await writeBytes(context.stderr, new TextEncoder().encode("timeout: worker escalation cannot preserve finite shared interpreter quotas\n"), context.signal);
|
|
20
20
|
return { exitCode: 125 };
|
|
@@ -35,11 +35,12 @@ var UsageError = class extends Error {
|
|
|
35
35
|
super(message);
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
|
-
async function collectSourceBytes(source, signal, maxBytes) {
|
|
38
|
+
async function collectSourceBytes(source, signal, maxBytes, admit) {
|
|
39
39
|
const chunks = [];
|
|
40
40
|
let total = 0;
|
|
41
41
|
for await (const chunk of readBytes(source, signal)) {
|
|
42
42
|
total += chunk.byteLength;
|
|
43
|
+
admit(chunk.byteLength);
|
|
43
44
|
if (total > maxBytes) throw new Error(`input exceeds maximum size (${maxBytes} bytes)`);
|
|
44
45
|
chunks.push(chunk);
|
|
45
46
|
}
|
|
@@ -673,6 +674,11 @@ function createBcCommand(options = {}) {
|
|
|
673
674
|
description: "Arbitrary-precision calculator language",
|
|
674
675
|
runtimeIdentity: commandRuntimeIdentity,
|
|
675
676
|
async execute(context) {
|
|
677
|
+
let inputBytes = 0;
|
|
678
|
+
const admit = (bytes) => {
|
|
679
|
+
context.signal.throwIfAborted();
|
|
680
|
+
context.inputBudget?.check(inputBytes += bytes);
|
|
681
|
+
};
|
|
676
682
|
context.signal.throwIfAborted();
|
|
677
683
|
try {
|
|
678
684
|
let mathlib = false;
|
|
@@ -721,14 +727,15 @@ function createBcCommand(options = {}) {
|
|
|
721
727
|
}
|
|
722
728
|
const sources = [...expressions];
|
|
723
729
|
if (files.length === 0 && expressions.length === 0) {
|
|
724
|
-
sources.push(decoder.decode(await collectSourceBytes(context.stdin, context.signal, maxInputBytes)));
|
|
730
|
+
sources.push(decoder.decode(await collectSourceBytes(context.stdin, context.signal, maxInputBytes, admit)));
|
|
725
731
|
} else if (files.length > 0) {
|
|
726
732
|
for (const file of files) {
|
|
727
733
|
if (file === "-") {
|
|
728
|
-
sources.push(decoder.decode(await collectSourceBytes(context.stdin, context.signal, maxInputBytes)));
|
|
734
|
+
sources.push(decoder.decode(await collectSourceBytes(context.stdin, context.signal, maxInputBytes, admit)));
|
|
729
735
|
} else {
|
|
730
|
-
const raw = await context.fs.readFile(pathPosix.resolve(context.cwd, file));
|
|
736
|
+
const raw = await context.fs.readFile(pathPosix.resolve(context.cwd, file), { signal: context.signal });
|
|
731
737
|
context.signal.throwIfAborted();
|
|
738
|
+
admit(raw.byteLength);
|
|
732
739
|
if (raw.byteLength > maxInputBytes) throw new Error(`bc program exceeds maximum input size (${maxInputBytes} bytes)`);
|
|
733
740
|
sources.push(decoder.decode(raw));
|
|
734
741
|
}
|
|
@@ -1064,7 +1071,7 @@ function createBcCommand(options = {}) {
|
|
|
1064
1071
|
return { exitCode: 0 };
|
|
1065
1072
|
} catch (err) {
|
|
1066
1073
|
context.signal.throwIfAborted();
|
|
1067
|
-
if (err instanceof Error && err.name === "AbortError") throw err;
|
|
1074
|
+
if (err instanceof Error && (err.name === "AbortError" || err.name === "BudgetExceededError")) throw err;
|
|
1068
1075
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1069
1076
|
const code = err instanceof UsageError ? 2 : 1;
|
|
1070
1077
|
await writeText(context.stderr, `bc: ${msg}
|
|
@@ -6,7 +6,8 @@ import {
|
|
|
6
6
|
init_buffer();
|
|
7
7
|
import { PublicDiagnostic, UsageError } from "../safe-bash-contracts/diagnostics.js";
|
|
8
8
|
import {
|
|
9
|
-
commandRuntimeIdentity
|
|
9
|
+
commandRuntimeIdentity,
|
|
10
|
+
withInputByteBudget
|
|
10
11
|
} from "../safe-bash-contracts/index.js";
|
|
11
12
|
import { codeOf, diagnostic, output } from "../safe-bash-compression-engine/internal.js";
|
|
12
13
|
import { runOperand } from "../safe-bash-compression-engine/operand.js";
|
|
@@ -35,7 +36,7 @@ function createNamedBzip2Command(name, options = {}) {
|
|
|
35
36
|
name,
|
|
36
37
|
description: `${name} block-sorting file compressor`,
|
|
37
38
|
runtimeIdentity: commandRuntimeIdentity,
|
|
38
|
-
async
|
|
39
|
+
execute: withInputByteBudget(async (context) => {
|
|
39
40
|
context.signal.throwIfAborted();
|
|
40
41
|
try {
|
|
41
42
|
const parsed = parseOptions(name, context.args);
|
|
@@ -105,7 +106,7 @@ No FILE or FILE '-' uses stdin; file output uses private VFS staging.
|
|
|
105
106
|
await diagnostic(context, error);
|
|
106
107
|
return { exitCode: error instanceof UsageError ? 2 : 1 };
|
|
107
108
|
}
|
|
108
|
-
}
|
|
109
|
+
})
|
|
109
110
|
};
|
|
110
111
|
}
|
|
111
112
|
function createBzip2Command(options = {}) {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Poe Platform
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { modeChange } from "../safe-bash-io-engine/commands/mode-change.js";
|
|
2
|
+
import { type MetadataCommandsOptions } from "../safe-bash-metadata-engine/index.js";
|
|
3
|
+
export declare function createChmodCommand(configuration?: MetadataCommandsOptions): import("../safe-bash-contracts/index.js").CommandDefinition;
|
|
4
|
+
export declare function evalSyncChmod(opArgs: readonly string[], umask: number, chmodNodeSync?: (filePath: string, change: (stat: {
|
|
5
|
+
type: "file" | "directory" | "symlink";
|
|
6
|
+
mode: number;
|
|
7
|
+
}) => number) => boolean): string | undefined;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { VirtualShellPlugin } from "../safe-bash-contracts/index.js";
|
|
2
|
+
import type { MetadataCommandsOptions } from "../safe-bash-metadata-engine/index.js";
|
|
3
|
+
export * from "./command.js";
|
|
4
|
+
export type { MetadataCommandsOptions as ChmodCommandsOptions, MetadataLimits as ChmodLimits } from "../safe-bash-metadata-engine/index.js";
|
|
5
|
+
export declare function createChmodCommands(options?: MetadataCommandsOptions): import("../safe-bash-contracts/index.js").CommandDefinition[];
|
|
6
|
+
export declare function chmodCommands(options?: MetadataCommandsOptions): VirtualShellPlugin;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createChmodCommand,
|
|
3
|
+
evalSyncChmod,
|
|
4
|
+
modeChange
|
|
5
|
+
} from "../safe-bash/command-chunks/chunk-A7MU7762.js";
|
|
6
|
+
import {
|
|
7
|
+
init_buffer
|
|
8
|
+
} from "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
|
|
9
|
+
|
|
10
|
+
// packages/safe-bash-command-chmod/src/index.ts
|
|
11
|
+
init_buffer();
|
|
12
|
+
function createChmodCommands(options = {}) {
|
|
13
|
+
return [createChmodCommand(options)];
|
|
14
|
+
}
|
|
15
|
+
function chmodCommands(options = {}) {
|
|
16
|
+
const commands = createChmodCommands(options);
|
|
17
|
+
return { name: "chmod-commands", setup(host) {
|
|
18
|
+
for (const command of commands) host.commands.register(command, { replace: options.replace ?? false });
|
|
19
|
+
} };
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
chmodCommands,
|
|
23
|
+
createChmodCommand,
|
|
24
|
+
createChmodCommands,
|
|
25
|
+
evalSyncChmod,
|
|
26
|
+
modeChange
|
|
27
|
+
};
|
|
@@ -10,7 +10,7 @@ init_buffer();
|
|
|
10
10
|
import { yieldTurn } from "../safe-bash-contracts/yield.js";
|
|
11
11
|
import { commandRuntimeIdentity, getCommandArguments } from "../safe-bash-contracts/command.js";
|
|
12
12
|
import { FsError as FsError2 } from "../safe-bash-contracts/errors.js";
|
|
13
|
-
import { readBytes as readBytes2, writeBytes } from "../safe-bash-contracts/io.js";
|
|
13
|
+
import { readBytes as readBytes2, writeBytes, withInputByteBudget } from "../safe-bash-contracts/io.js";
|
|
14
14
|
import { createOutputOperation } from "../safe-bash-contracts/output.js";
|
|
15
15
|
import { shellValueByteLength } from "../safe-bash-contracts/value.js";
|
|
16
16
|
|
|
@@ -1779,7 +1779,7 @@ function createExiftoolCommand(options = {}) {
|
|
|
1779
1779
|
name: "exiftool",
|
|
1780
1780
|
runtimeIdentity: commandRuntimeIdentity,
|
|
1781
1781
|
description: "Inspect and edit admitted PNG, JPEG and PDF metadata through virtual files",
|
|
1782
|
-
async
|
|
1782
|
+
execute: withInputByteBudget(async (context) => {
|
|
1783
1783
|
const publication = new Publication(context, limits.maxStagingAttempts);
|
|
1784
1784
|
let stdout, stderr;
|
|
1785
1785
|
let failed = false, failure;
|
|
@@ -1824,7 +1824,7 @@ function createExiftoolCommand(options = {}) {
|
|
|
1824
1824
|
invocation = parseArguments(await expandArgfiles(context.args, context, publication, resources), resources.limits);
|
|
1825
1825
|
} catch (error) {
|
|
1826
1826
|
context.signal.throwIfAborted();
|
|
1827
|
-
if (error instanceof ResourceLimitError) throw error;
|
|
1827
|
+
if (error instanceof ResourceLimitError || error instanceof Error && error.name === "BudgetExceededError" || error instanceof FsError2 && error.code === "EFBIG") throw error;
|
|
1828
1828
|
await output("Error: " + (error instanceof Error ? error.message : String(error)) + "\n", true);
|
|
1829
1829
|
return { exitCode: 1 };
|
|
1830
1830
|
}
|
|
@@ -1948,7 +1948,7 @@ function createExiftoolCommand(options = {}) {
|
|
|
1948
1948
|
tags = jpeg ? inspectJpeg(bytes, resources).tags : png ? inspectPng(bytes, resources).tags : isPdf ? inspectPdf(bytes, resources).tags : [];
|
|
1949
1949
|
} catch (error) {
|
|
1950
1950
|
context.signal.throwIfAborted();
|
|
1951
|
-
if (error instanceof ResourceLimitError) throw error;
|
|
1951
|
+
if (error instanceof ResourceLimitError || error instanceof Error && error.name === "BudgetExceededError" || error instanceof FsError2 && error.code === "EFBIG") throw error;
|
|
1952
1952
|
errors++;
|
|
1953
1953
|
const message = error instanceof FsError2 && error.code === "ENOENT" ? "File not found" : error instanceof Error ? error.message : String(error);
|
|
1954
1954
|
await output("Error: " + message + " - " + file + "\n", true);
|
|
@@ -2053,7 +2053,7 @@ function createExiftoolCommand(options = {}) {
|
|
|
2053
2053
|
} finally {
|
|
2054
2054
|
await cleanup();
|
|
2055
2055
|
}
|
|
2056
|
-
}
|
|
2056
|
+
})
|
|
2057
2057
|
});
|
|
2058
2058
|
}
|
|
2059
2059
|
var exiftoolCommand = createExiftoolCommand();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createFindDefinitions,
|
|
3
3
|
evalSyncFind
|
|
4
|
-
} from "../safe-bash/command-chunks/chunk-
|
|
4
|
+
} from "../safe-bash/command-chunks/chunk-GFC2NTDG.js";
|
|
5
5
|
import "../safe-bash/command-chunks/chunk-5ZMZ573Q.js";
|
|
6
6
|
import "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
|
|
7
7
|
export {
|
|
@@ -2217,12 +2217,14 @@ function pathOf(context, path) {
|
|
|
2217
2217
|
return isAbsolutePath(path) ? path : `${context.cwd.endsWith("/") ? context.cwd.slice(0, -1) : context.cwd}/${path}`;
|
|
2218
2218
|
}
|
|
2219
2219
|
var InputBudget = class {
|
|
2220
|
-
constructor(maximum, sourceBufferBytes) {
|
|
2220
|
+
constructor(maximum, sourceBufferBytes, inputBudget) {
|
|
2221
2221
|
this.maximum = maximum;
|
|
2222
2222
|
this.sourceBufferBytes = sourceBufferBytes;
|
|
2223
|
+
this.inputBudget = inputBudget;
|
|
2223
2224
|
}
|
|
2224
2225
|
maximum;
|
|
2225
2226
|
sourceBufferBytes;
|
|
2227
|
+
inputBudget;
|
|
2226
2228
|
used = 0;
|
|
2227
2229
|
get maxReadBytes() {
|
|
2228
2230
|
return Math.max(0, Math.min(this.sourceBufferBytes, this.maximum - this.used));
|
|
@@ -2234,6 +2236,7 @@ var InputBudget = class {
|
|
|
2234
2236
|
if (size > this.maximum - this.used) throw new FsError("EFBIG", { message: "byte command input limit exceeded" });
|
|
2235
2237
|
if (size > this.maxReadBytes) throw new FmtError("LIMIT", "source chunk retention limit exceeded");
|
|
2236
2238
|
this.used += size;
|
|
2239
|
+
this.inputBudget?.check(this.used);
|
|
2237
2240
|
if (!size) yield byteSpan(chunk, 0, 0);
|
|
2238
2241
|
for (let offset = 0; offset < size; offset += 4096) yield byteSpan(chunk, offset, Math.min(4096, size - offset));
|
|
2239
2242
|
}
|
|
@@ -2390,7 +2393,7 @@ async function fmt(context, configuration = {}) {
|
|
|
2390
2393
|
const engineBytes = 10120 + settings.prefix.length;
|
|
2391
2394
|
const batchBytes = limits.retainedBytes >= Math.max(32768, engineBytes + 16384 + 4096) ? 16384 : 0;
|
|
2392
2395
|
const engineLimit = limits.retainedBytes - batchBytes;
|
|
2393
|
-
const budget = new InputBudget(limits.inputBytes, engineLimit - engineBytes);
|
|
2396
|
+
const budget = new InputBudget(limits.inputBytes, engineLimit - engineBytes, context.inputBudget);
|
|
2394
2397
|
let work = 0, outputBytes = 0;
|
|
2395
2398
|
stdout = createOutputOperation({ signal: local.signal }, context.stdout);
|
|
2396
2399
|
const outputContext = { ...context, stdout: stdout.output };
|
|
@@ -2406,6 +2409,7 @@ async function fmt(context, configuration = {}) {
|
|
|
2406
2409
|
try {
|
|
2407
2410
|
await current.open(name, nameBytes);
|
|
2408
2411
|
} catch (error) {
|
|
2412
|
+
if (error instanceof Error && (error.name === "BudgetExceededError" || error.name === "AbortError")) throw error;
|
|
2409
2413
|
local.signal.throwIfAborted();
|
|
2410
2414
|
await diagnostic(context, fileError(error, name, nameBytes, true, context));
|
|
2411
2415
|
await current.close();
|
|
@@ -2439,6 +2443,7 @@ async function fmt(context, configuration = {}) {
|
|
|
2439
2443
|
bytes2 = await current.next();
|
|
2440
2444
|
if (bytes2?.length) received = true;
|
|
2441
2445
|
} catch (error) {
|
|
2446
|
+
if (error instanceof Error && (error.name === "BudgetExceededError" || error.name === "AbortError")) throw error;
|
|
2442
2447
|
local.signal.throwIfAborted();
|
|
2443
2448
|
if (isFsError(error, "EFBIG")) throw new FmtError("LIMIT", "byte command input limit exceeded");
|
|
2444
2449
|
readFailed = true;
|
|
@@ -2467,6 +2472,7 @@ async function fmt(context, configuration = {}) {
|
|
|
2467
2472
|
}
|
|
2468
2473
|
if (outBatchUsed) await flushOutBatch();
|
|
2469
2474
|
} catch (error) {
|
|
2475
|
+
if (error instanceof Error && (error.name === "BudgetExceededError" || error.name === "AbortError")) throw error;
|
|
2470
2476
|
local.signal.throwIfAborted();
|
|
2471
2477
|
try {
|
|
2472
2478
|
await flushOutBatch();
|
|
@@ -2496,6 +2502,7 @@ async function fmt(context, configuration = {}) {
|
|
|
2496
2502
|
} catch (error) {
|
|
2497
2503
|
failed = true;
|
|
2498
2504
|
context.signal.throwIfAborted();
|
|
2505
|
+
if (error instanceof Error && (error.name === "BudgetExceededError" || error.name === "AbortError")) throw error;
|
|
2499
2506
|
if (error instanceof FmtError && error.usage) await writeBytes(context.stderr, Uint8Array.from(`fmt: ${error.message}
|
|
2500
2507
|
Try 'fmt --help' for more information.
|
|
2501
2508
|
`, (character) => character.charCodeAt(0)), context.signal);
|
|
@@ -16,10 +16,11 @@ function createGzipCommands(config = {}) {
|
|
|
16
16
|
if (maxDecodedBytes !== void 0 && maxDecodedBytes !== Infinity && (!Number.isSafeInteger(maxDecodedBytes) || maxDecodedBytes < 0)) {
|
|
17
17
|
throw new RangeError("maxDecodedBytes must be a nonnegative safe integer or Infinity");
|
|
18
18
|
}
|
|
19
|
-
const commands = profiles.filter((profile) => profile.format === "gzip").flatMap((profile) => profile.names.map((name) =>
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
const commands = profiles.filter((profile) => profile.format === "gzip").flatMap((profile) => profile.names.map((name) => {
|
|
20
|
+
const command = define(name, async (context) => {
|
|
21
|
+
const options = parseOptions(name, context.args);
|
|
22
|
+
if (options.help) {
|
|
23
|
+
await output(context, `Usage: ${name} [OPTION]... [FILE]...
|
|
23
24
|
-c, --stdout, --to-stdout
|
|
24
25
|
-d, --decompress, --uncompress
|
|
25
26
|
-k, --keep
|
|
@@ -29,48 +30,50 @@ ${options.format === "zstd" ? "-1..-9, --best\nHigher levels and --fast[=NUM] ar
|
|
|
29
30
|
`}-h, --help
|
|
30
31
|
No FILE or FILE '-' uses stdin; file output uses private VFS staging.
|
|
31
32
|
`);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
if (options.operands.length > 1) {
|
|
38
|
-
plans = [];
|
|
39
|
-
for (const name2 of options.operands) {
|
|
40
|
-
try {
|
|
41
|
-
plans.push(...await planOperands(context, { ...options, operands: [name2] }));
|
|
42
|
-
} catch (error) {
|
|
43
|
-
context.signal.throwIfAborted();
|
|
44
|
-
if (codeOf(error) === "EROFS") throw error;
|
|
45
|
-
planningFailed = true;
|
|
46
|
-
if (options.quiet < 2) await diagnostic(context, error);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
if (plans.length > 1) await verifyOperandDestinations(context, plans);
|
|
50
|
-
} else plans = await planOperands(context, options);
|
|
51
|
-
} catch (error) {
|
|
52
|
-
context.signal.throwIfAborted();
|
|
53
|
-
if (options.quiet < 2) throw error;
|
|
54
|
-
return { exitCode: 1 };
|
|
55
|
-
}
|
|
56
|
-
const decodedBudget = new DecodedBudget(maxDecodedBytes);
|
|
57
|
-
let exitCode = planningFailed ? 1 : 0;
|
|
58
|
-
for (const plan of plans) {
|
|
33
|
+
return { exitCode: 0 };
|
|
34
|
+
}
|
|
35
|
+
let plans;
|
|
36
|
+
let planningFailed = false;
|
|
59
37
|
try {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
38
|
+
if (options.operands.length > 1) {
|
|
39
|
+
plans = [];
|
|
40
|
+
for (const name2 of options.operands) {
|
|
41
|
+
try {
|
|
42
|
+
plans.push(...await planOperands(context, { ...options, operands: [name2] }));
|
|
43
|
+
} catch (error) {
|
|
44
|
+
context.signal.throwIfAborted();
|
|
45
|
+
if (codeOf(error) === "EROFS") throw error;
|
|
46
|
+
planningFailed = true;
|
|
47
|
+
if (options.quiet < 2) await diagnostic(context, error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (plans.length > 1) await verifyOperandDestinations(context, plans);
|
|
51
|
+
} else plans = await planOperands(context, options);
|
|
65
52
|
} catch (error) {
|
|
66
53
|
context.signal.throwIfAborted();
|
|
67
|
-
if (options.quiet < 2)
|
|
68
|
-
exitCode
|
|
69
|
-
if (decodedBudget.exceeded) break;
|
|
54
|
+
if (options.quiet < 2) throw error;
|
|
55
|
+
return { exitCode: 1 };
|
|
70
56
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
57
|
+
const decodedBudget = new DecodedBudget(maxDecodedBytes);
|
|
58
|
+
let exitCode = planningFailed ? 1 : 0;
|
|
59
|
+
for (const plan of plans) {
|
|
60
|
+
try {
|
|
61
|
+
const warned = await runOperand(context, plan, options, decodedBudget);
|
|
62
|
+
if (warned) {
|
|
63
|
+
if (!options.quiet) await diagnostic(context, new PublicDiagnostic(`${plan.source}: decompression OK, trailing garbage ignored`));
|
|
64
|
+
if (exitCode === 0) exitCode = 2;
|
|
65
|
+
}
|
|
66
|
+
} catch (error) {
|
|
67
|
+
context.signal.throwIfAborted();
|
|
68
|
+
if (options.quiet < 2) await diagnostic(context, error);
|
|
69
|
+
exitCode = 1;
|
|
70
|
+
if (decodedBudget.exceeded) break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return { exitCode };
|
|
74
|
+
});
|
|
75
|
+
return { ...command, execute: withInputByteBudget(async (context) => command.execute(context)) };
|
|
76
|
+
}));
|
|
74
77
|
if (maxDecodedBytes === void 0 || maxDecodedBytes === Infinity) {
|
|
75
78
|
for (const c of commands) builtInDirectContextExecutors.add(c.execute);
|
|
76
79
|
}
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
|
|
36
36
|
// packages/safe-bash-command-imagemagick/src/index.ts
|
|
37
37
|
init_buffer();
|
|
38
|
+
import { FsError } from "../safe-bash-contracts/errors.js";
|
|
38
39
|
import { resolvePath } from "../safe-bash-contracts/path.js";
|
|
39
40
|
import { yieldTurn, drainCooperativeSteps as drainSteps } from "../safe-bash-contracts/yield.js";
|
|
40
41
|
import { InputByteBudget } from "../safe-bash-contracts/io.js";
|
|
@@ -5089,7 +5090,8 @@ async function executeVfsMagickTool(context, runner, maxInputBytes) {
|
|
|
5089
5090
|
bytes = await context.fs.readFile(resolvePath(context.cwd, candidate), {
|
|
5090
5091
|
signal: invocation.signal
|
|
5091
5092
|
});
|
|
5092
|
-
} catch {
|
|
5093
|
+
} catch (error) {
|
|
5094
|
+
if (!(error instanceof FsError) || !["ENOENT", "ENOTDIR", "EISDIR", "EACCES", "EPERM"].includes(error.code)) throw error;
|
|
5093
5095
|
continue;
|
|
5094
5096
|
}
|
|
5095
5097
|
chargeInput(bytes.byteLength);
|