@poe-platform/safe-bash 0.1.157 → 0.1.159
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/safe-bash/browser.js +274 -228
- package/dist/safe-bash/browser.js.map +4 -4
- package/dist/safe-bash/commands/apply-patch/shared.d.ts.map +1 -1
- package/dist/safe-bash/commands/apply-patch/shared.js +4 -2
- package/dist/safe-bash/commands/apply-patch/shared.js.map +1 -1
- package/dist/safe-bash/commands/archive/create.d.ts.map +1 -1
- package/dist/safe-bash/commands/archive/create.js +2 -1
- package/dist/safe-bash/commands/archive/create.js.map +1 -1
- package/dist/safe-bash/commands/archive/index.d.ts.map +1 -1
- package/dist/safe-bash/commands/archive/index.js +2 -1
- package/dist/safe-bash/commands/archive/index.js.map +1 -1
- package/dist/safe-bash/commands/basic.d.ts.map +1 -1
- package/dist/safe-bash/commands/basic.js +5 -4
- package/dist/safe-bash/commands/basic.js.map +1 -1
- package/dist/safe-bash/commands/column/internal.d.ts.map +1 -1
- package/dist/safe-bash/commands/column/internal.js +2 -1
- package/dist/safe-bash/commands/column/internal.js.map +1 -1
- package/dist/safe-bash/commands/diff-patch/shared.d.ts.map +1 -1
- package/dist/safe-bash/commands/diff-patch/shared.js +3 -2
- package/dist/safe-bash/commands/diff-patch/shared.js.map +1 -1
- package/dist/safe-bash/commands/du/budget.d.ts.map +1 -1
- package/dist/safe-bash/commands/du/budget.js +2 -1
- package/dist/safe-bash/commands/du/budget.js.map +1 -1
- package/dist/safe-bash/commands/execution.d.ts.map +1 -1
- package/dist/safe-bash/commands/execution.js +4 -3
- package/dist/safe-bash/commands/execution.js.map +1 -1
- package/dist/safe-bash/commands/expr/index.d.ts.map +1 -1
- package/dist/safe-bash/commands/expr/index.js +5 -3
- package/dist/safe-bash/commands/expr/index.js.map +1 -1
- package/dist/safe-bash/commands/filesystem.d.ts.map +1 -1
- package/dist/safe-bash/commands/filesystem.js +10 -9
- package/dist/safe-bash/commands/filesystem.js.map +1 -1
- package/dist/safe-bash/commands/find.d.ts.map +1 -1
- package/dist/safe-bash/commands/find.js +3 -2
- package/dist/safe-bash/commands/find.js.map +1 -1
- package/dist/safe-bash/commands/html-to-markdown/index.d.ts.map +1 -1
- package/dist/safe-bash/commands/html-to-markdown/index.js +2 -1
- package/dist/safe-bash/commands/html-to-markdown/index.js.map +1 -1
- package/dist/safe-bash/commands/internal.d.ts.map +1 -1
- package/dist/safe-bash/commands/internal.js +2 -1
- package/dist/safe-bash/commands/internal.js.map +1 -1
- package/dist/safe-bash/commands/network/shared.js +2 -2
- package/dist/safe-bash/commands/network/shared.js.map +1 -1
- package/dist/safe-bash/commands/node/host.d.ts.map +1 -1
- package/dist/safe-bash/commands/node/host.js +4 -2
- package/dist/safe-bash/commands/node/host.js.map +1 -1
- package/dist/safe-bash/commands/safejs/index.d.ts.map +1 -1
- package/dist/safe-bash/commands/safejs/index.js +2 -1
- package/dist/safe-bash/commands/safejs/index.js.map +1 -1
- package/dist/safe-bash/commands/search/shared.d.ts.map +1 -1
- package/dist/safe-bash/commands/search/shared.js +2 -1
- package/dist/safe-bash/commands/search/shared.js.map +1 -1
- package/dist/safe-bash/commands/split/split.d.ts.map +1 -1
- package/dist/safe-bash/commands/split/split.js +3 -2
- package/dist/safe-bash/commands/split/split.js.map +1 -1
- package/dist/safe-bash/commands/structured/jq.d.ts.map +1 -1
- package/dist/safe-bash/commands/structured/jq.js +5 -4
- package/dist/safe-bash/commands/structured/jq.js.map +1 -1
- package/dist/safe-bash/commands/text-programs/shared.d.ts.map +1 -1
- package/dist/safe-bash/commands/text-programs/shared.js +2 -1
- package/dist/safe-bash/commands/text-programs/shared.js.map +1 -1
- package/dist/safe-bash/commands/time-env/shared.d.ts.map +1 -1
- package/dist/safe-bash/commands/time-env/shared.js +2 -1
- package/dist/safe-bash/commands/time-env/shared.js.map +1 -1
- package/dist/safe-bash/commands/tree/io.d.ts.map +1 -1
- package/dist/safe-bash/commands/tree/io.js +2 -8
- package/dist/safe-bash/commands/tree/io.js.map +1 -1
- package/dist/safe-bash/commands/which/which.d.ts.map +1 -1
- package/dist/safe-bash/commands/which/which.js +3 -1
- package/dist/safe-bash/commands/which/which.js.map +1 -1
- package/dist/safe-bash/escaping.d.ts +4 -0
- package/dist/safe-bash/escaping.d.ts.map +1 -0
- package/dist/safe-bash/escaping.js +47 -0
- package/dist/safe-bash/escaping.js.map +1 -0
- package/dist/safe-bash/shell/runtime.d.ts.map +1 -1
- package/dist/safe-bash/shell/runtime.js +58 -57
- package/dist/safe-bash/shell/runtime.js.map +1 -1
- package/dist/safe-bash/shell/shell.d.ts.map +1 -1
- package/dist/safe-bash/shell/shell.js +7 -6
- package/dist/safe-bash/shell/shell.js.map +1 -1
- package/package.json +2 -2
|
@@ -117,23 +117,23 @@ var require_base64_js = __commonJS({
|
|
|
117
117
|
var tmp;
|
|
118
118
|
var len2 = uint8.length;
|
|
119
119
|
var extraBytes = len2 % 3;
|
|
120
|
-
var
|
|
120
|
+
var parts2 = [];
|
|
121
121
|
var maxChunkLength = 16383;
|
|
122
122
|
for (var i2 = 0, len22 = len2 - extraBytes; i2 < len22; i2 += maxChunkLength) {
|
|
123
|
-
|
|
123
|
+
parts2.push(encodeChunk(uint8, i2, i2 + maxChunkLength > len22 ? len22 : i2 + maxChunkLength));
|
|
124
124
|
}
|
|
125
125
|
if (extraBytes === 1) {
|
|
126
126
|
tmp = uint8[len2 - 1];
|
|
127
|
-
|
|
127
|
+
parts2.push(
|
|
128
128
|
lookup[tmp >> 2] + lookup[tmp << 4 & 63] + "=="
|
|
129
129
|
);
|
|
130
130
|
} else if (extraBytes === 2) {
|
|
131
131
|
tmp = (uint8[len2 - 2] << 8) + uint8[len2 - 1];
|
|
132
|
-
|
|
132
|
+
parts2.push(
|
|
133
133
|
lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63] + "="
|
|
134
134
|
);
|
|
135
135
|
}
|
|
136
|
-
return
|
|
136
|
+
return parts2.join("");
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
});
|
|
@@ -1831,6 +1831,9 @@ init_platform();
|
|
|
1831
1831
|
// packages/safe-bash/src/commands/basic.ts
|
|
1832
1832
|
init_platform();
|
|
1833
1833
|
|
|
1834
|
+
// packages/safe-bash/src/escaping.ts
|
|
1835
|
+
init_platform();
|
|
1836
|
+
|
|
1834
1837
|
// packages/safe-bash/src/contracts/command.ts
|
|
1835
1838
|
init_platform();
|
|
1836
1839
|
|
|
@@ -2139,14 +2142,14 @@ function ownedCommandArguments(size, valueAt, allocation, extent) {
|
|
|
2139
2142
|
const transaction2 = argumentAllocation(allocation);
|
|
2140
2143
|
const scratch = transaction2.allocation?.reserve(bytes3, count2 + 1);
|
|
2141
2144
|
try {
|
|
2142
|
-
const
|
|
2145
|
+
const parts2 = [];
|
|
2143
2146
|
for (let index = 0; index < length; index++) {
|
|
2144
|
-
if (index)
|
|
2145
|
-
|
|
2147
|
+
if (index) parts2.push(separator);
|
|
2148
|
+
parts2.push(values[index]);
|
|
2146
2149
|
}
|
|
2147
|
-
Object.freeze(
|
|
2148
|
-
scratch?.commit(
|
|
2149
|
-
const result = concatShellValues(
|
|
2150
|
+
Object.freeze(parts2);
|
|
2151
|
+
scratch?.commit(parts2);
|
|
2152
|
+
const result = concatShellValues(parts2, transaction2.allocation);
|
|
2150
2153
|
scratch?.release();
|
|
2151
2154
|
return result;
|
|
2152
2155
|
} catch (error) {
|
|
@@ -2600,6 +2603,85 @@ function composeMiddleware(middleware, terminal) {
|
|
|
2600
2603
|
};
|
|
2601
2604
|
}
|
|
2602
2605
|
|
|
2606
|
+
// packages/safe-bash/src/contracts/yield.ts
|
|
2607
|
+
init_platform();
|
|
2608
|
+
var checkpoints = /* @__PURE__ */ new WeakMap();
|
|
2609
|
+
function monotonicNow() {
|
|
2610
|
+
return globalThis.performance?.now() ?? Date.now();
|
|
2611
|
+
}
|
|
2612
|
+
function registerYieldCheckpoint(signal, checkpoint) {
|
|
2613
|
+
checkpoints.set(signal, checkpoint);
|
|
2614
|
+
}
|
|
2615
|
+
function scheduleTurn(callback) {
|
|
2616
|
+
const host = globalThis;
|
|
2617
|
+
return host.setImmediate ? { kind: "immediate", value: host.setImmediate(callback) } : { kind: "timeout", value: setTimeout(callback, 0) };
|
|
2618
|
+
}
|
|
2619
|
+
function cancelTurn(handle) {
|
|
2620
|
+
if (handle?.kind === "immediate") globalThis.clearImmediate?.(handle.value);
|
|
2621
|
+
else if (handle) clearTimeout(handle.value);
|
|
2622
|
+
}
|
|
2623
|
+
function yieldTurn(signal) {
|
|
2624
|
+
signal?.throwIfAborted();
|
|
2625
|
+
if (signal) checkpoints.get(signal)?.();
|
|
2626
|
+
return new Promise((resolve, reject) => {
|
|
2627
|
+
let handle;
|
|
2628
|
+
const finish = () => {
|
|
2629
|
+
signal?.removeEventListener("abort", abort);
|
|
2630
|
+
resolve();
|
|
2631
|
+
};
|
|
2632
|
+
const abort = () => {
|
|
2633
|
+
cancelTurn(handle);
|
|
2634
|
+
reject(signal.reason);
|
|
2635
|
+
};
|
|
2636
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
2637
|
+
if (signal?.aborted) abort();
|
|
2638
|
+
else handle = scheduleTurn(finish);
|
|
2639
|
+
});
|
|
2640
|
+
}
|
|
2641
|
+
|
|
2642
|
+
// packages/safe-bash/src/escaping.ts
|
|
2643
|
+
var controls = { 8: "\\b", 9: "\\t", 10: "\\n", 11: "\\v", 12: "\\f", 13: "\\r", 92: "\\\\" };
|
|
2644
|
+
var encoder2 = new TextEncoder();
|
|
2645
|
+
function* parts(value2, mode) {
|
|
2646
|
+
for (const character of value2) {
|
|
2647
|
+
const point = character.codePointAt(0);
|
|
2648
|
+
if (mode === "diagnostic" && (point === 9 || point === 10 || point >= 32 && (point < 127 || point > 159))) {
|
|
2649
|
+
yield character;
|
|
2650
|
+
} else {
|
|
2651
|
+
for (const byte of encoder2.encode(character)) {
|
|
2652
|
+
yield controls[byte] ?? (byte >= 32 && byte < 127 ? String.fromCharCode(byte) : `\\${byte.toString(8).padStart(3, "0")}`);
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
}
|
|
2656
|
+
}
|
|
2657
|
+
function escapeText(value2, mode, checkOutput) {
|
|
2658
|
+
let result = "", bytes2 = 0;
|
|
2659
|
+
for (const part of parts(value2, mode)) {
|
|
2660
|
+
bytes2 += import_buffer.Buffer.byteLength(part);
|
|
2661
|
+
checkOutput?.(bytes2);
|
|
2662
|
+
result += part;
|
|
2663
|
+
}
|
|
2664
|
+
return result;
|
|
2665
|
+
}
|
|
2666
|
+
async function writeDiagnostic(sink, value2, signal) {
|
|
2667
|
+
signal?.throwIfAborted();
|
|
2668
|
+
let chunk = "", bytes2 = 0, work = 0;
|
|
2669
|
+
for (const part of parts(value2, "diagnostic")) {
|
|
2670
|
+
signal?.throwIfAborted();
|
|
2671
|
+
const size = import_buffer.Buffer.byteLength(part);
|
|
2672
|
+
if (bytes2 + size > 16384) {
|
|
2673
|
+
await writeBytes(sink, encoder2.encode(chunk), signal);
|
|
2674
|
+
chunk = "";
|
|
2675
|
+
bytes2 = 0;
|
|
2676
|
+
}
|
|
2677
|
+
chunk += part;
|
|
2678
|
+
bytes2 += size;
|
|
2679
|
+
if (++work % 1024 === 0) await yieldTurn(signal);
|
|
2680
|
+
}
|
|
2681
|
+
if (bytes2) await writeBytes(sink, encoder2.encode(chunk), signal);
|
|
2682
|
+
signal?.throwIfAborted();
|
|
2683
|
+
}
|
|
2684
|
+
|
|
2603
2685
|
// packages/safe-bash/src/commands/internal.ts
|
|
2604
2686
|
init_platform();
|
|
2605
2687
|
|
|
@@ -2687,7 +2769,7 @@ var RecordBuffer = class {
|
|
|
2687
2769
|
};
|
|
2688
2770
|
|
|
2689
2771
|
// packages/safe-bash/src/commands/internal.ts
|
|
2690
|
-
var
|
|
2772
|
+
var encoder3 = new TextEncoder();
|
|
2691
2773
|
var decoder2 = new TextDecoder();
|
|
2692
2774
|
var bufferLimit = 32 * 1024 * 1024;
|
|
2693
2775
|
var UsageError = class extends Error {
|
|
@@ -2767,12 +2849,12 @@ function codeOf(error) {
|
|
|
2767
2849
|
}
|
|
2768
2850
|
async function output(context, text) {
|
|
2769
2851
|
context.signal.throwIfAborted();
|
|
2770
|
-
await writeBytes(context.stdout, typeof text === "string" ?
|
|
2852
|
+
await writeBytes(context.stdout, typeof text === "string" ? encoder3.encode(text) : text, context.signal);
|
|
2771
2853
|
}
|
|
2772
2854
|
async function diagnostic(context, error) {
|
|
2773
2855
|
context.signal.throwIfAborted();
|
|
2774
|
-
await
|
|
2775
|
-
|
|
2856
|
+
await writeDiagnostic(context.stderr, `${context.command}: ${error instanceof Error ? error.message : String(error)}
|
|
2857
|
+
`, context.signal);
|
|
2776
2858
|
}
|
|
2777
2859
|
function define(name2, handler, failureCode = 1) {
|
|
2778
2860
|
return {
|
|
@@ -2881,9 +2963,9 @@ function emptyInput() {
|
|
|
2881
2963
|
}
|
|
2882
2964
|
function replaceArgument(source, pattern, replacement) {
|
|
2883
2965
|
if (typeof source === "string") return source.split(pattern).join(replacement);
|
|
2884
|
-
const needle =
|
|
2966
|
+
const needle = encoder3.encode(pattern);
|
|
2885
2967
|
if (!needle.length) throw new UsageError("replacement string cannot be empty");
|
|
2886
|
-
const substituted =
|
|
2968
|
+
const substituted = encoder3.encode(replacement);
|
|
2887
2969
|
const chunks = [];
|
|
2888
2970
|
let start = 0;
|
|
2889
2971
|
for (let offset = 0; offset <= source.length - needle.length; ) {
|
|
@@ -2903,7 +2985,7 @@ function escapeBytes(text, zeroOctal = false, bareOctal = false) {
|
|
|
2903
2985
|
for (let index = 0; index < text.length; ) {
|
|
2904
2986
|
if (text[index] !== "\\" || index + 1 === text.length) {
|
|
2905
2987
|
const character = String.fromCodePoint(text.codePointAt(index));
|
|
2906
|
-
chunks.push(
|
|
2988
|
+
chunks.push(encoder3.encode(character));
|
|
2907
2989
|
index += character.length;
|
|
2908
2990
|
continue;
|
|
2909
2991
|
}
|
|
@@ -2927,7 +3009,7 @@ function escapeBytes(text, zeroOctal = false, bareOctal = false) {
|
|
|
2927
3009
|
index += 1 + hexadecimal[0].length;
|
|
2928
3010
|
continue;
|
|
2929
3011
|
}
|
|
2930
|
-
chunks.push(
|
|
3012
|
+
chunks.push(encoder3.encode(`\\${next}`));
|
|
2931
3013
|
index += 2;
|
|
2932
3014
|
}
|
|
2933
3015
|
return { bytes: concatenate(chunks), stop: false };
|
|
@@ -3113,8 +3195,8 @@ async function formatPrintf(context) {
|
|
|
3113
3195
|
else number = parseInt(supplied.replace(/^[+-]?0/u, ""), 8) * (supplied.startsWith("-") ? -1 : 1);
|
|
3114
3196
|
}
|
|
3115
3197
|
if (!Number.isFinite(number)) {
|
|
3116
|
-
await
|
|
3117
|
-
|
|
3198
|
+
await writeDiagnostic(context.stderr, `printf: '${supplied}': invalid number
|
|
3199
|
+
`, context.signal);
|
|
3118
3200
|
exitCode = 1;
|
|
3119
3201
|
number = 0;
|
|
3120
3202
|
}
|
|
@@ -3135,8 +3217,8 @@ async function formatPrintf(context) {
|
|
|
3135
3217
|
}
|
|
3136
3218
|
} catch {
|
|
3137
3219
|
integral = 0n;
|
|
3138
|
-
if (exitCode === 0) await
|
|
3139
|
-
|
|
3220
|
+
if (exitCode === 0) await writeDiagnostic(context.stderr, `printf: '${supplied}': invalid integer
|
|
3221
|
+
`, context.signal);
|
|
3140
3222
|
exitCode = 1;
|
|
3141
3223
|
}
|
|
3142
3224
|
text = (unsigned ? BigInt.asUintN(64, integral) : integral).toString(radix);
|
|
@@ -3207,42 +3289,6 @@ async function compareObservedEntries(fs, path, stat, peer, peerPath, peerStat,
|
|
|
3207
3289
|
// packages/safe-bash/src/commands/move.ts
|
|
3208
3290
|
init_platform();
|
|
3209
3291
|
|
|
3210
|
-
// packages/safe-bash/src/contracts/yield.ts
|
|
3211
|
-
init_platform();
|
|
3212
|
-
var checkpoints = /* @__PURE__ */ new WeakMap();
|
|
3213
|
-
function monotonicNow() {
|
|
3214
|
-
return globalThis.performance?.now() ?? Date.now();
|
|
3215
|
-
}
|
|
3216
|
-
function registerYieldCheckpoint(signal, checkpoint) {
|
|
3217
|
-
checkpoints.set(signal, checkpoint);
|
|
3218
|
-
}
|
|
3219
|
-
function scheduleTurn(callback) {
|
|
3220
|
-
const host = globalThis;
|
|
3221
|
-
return host.setImmediate ? { kind: "immediate", value: host.setImmediate(callback) } : { kind: "timeout", value: setTimeout(callback, 0) };
|
|
3222
|
-
}
|
|
3223
|
-
function cancelTurn(handle) {
|
|
3224
|
-
if (handle?.kind === "immediate") globalThis.clearImmediate?.(handle.value);
|
|
3225
|
-
else if (handle) clearTimeout(handle.value);
|
|
3226
|
-
}
|
|
3227
|
-
function yieldTurn(signal) {
|
|
3228
|
-
signal?.throwIfAborted();
|
|
3229
|
-
if (signal) checkpoints.get(signal)?.();
|
|
3230
|
-
return new Promise((resolve, reject) => {
|
|
3231
|
-
let handle;
|
|
3232
|
-
const finish = () => {
|
|
3233
|
-
signal?.removeEventListener("abort", abort);
|
|
3234
|
-
resolve();
|
|
3235
|
-
};
|
|
3236
|
-
const abort = () => {
|
|
3237
|
-
cancelTurn(handle);
|
|
3238
|
-
reject(signal.reason);
|
|
3239
|
-
};
|
|
3240
|
-
signal?.addEventListener("abort", abort, { once: true });
|
|
3241
|
-
if (signal?.aborted) abort();
|
|
3242
|
-
else handle = scheduleTurn(finish);
|
|
3243
|
-
});
|
|
3244
|
-
}
|
|
3245
|
-
|
|
3246
3292
|
// packages/safe-bash/src/commands/filesystem-requirements.ts
|
|
3247
3293
|
init_platform();
|
|
3248
3294
|
var filesystemCommandRequirements = {
|
|
@@ -3651,7 +3697,7 @@ async function copy(context, source, target, flags, readDirectory, top = true, a
|
|
|
3651
3697
|
await context.fs.copyFile(source, target, { exclusive: true, signal: context.signal });
|
|
3652
3698
|
}
|
|
3653
3699
|
}
|
|
3654
|
-
if (!preflight && flags.has("v")) await output(context, `'${source}' -> '${target}'
|
|
3700
|
+
if (!preflight && flags.has("v")) await output(context, `'${escapeText(source, "display")}' -> '${escapeText(target, "display")}'
|
|
3655
3701
|
`);
|
|
3656
3702
|
}
|
|
3657
3703
|
function modeText(stat) {
|
|
@@ -3681,7 +3727,7 @@ function filesystemCommands(maxDirectoryEntries) {
|
|
|
3681
3727
|
));
|
|
3682
3728
|
return eachOperand(context, parsed.operands, async (operand) => {
|
|
3683
3729
|
await context.fs.mkdir(pathOf(context, operand), { recursive: parsed.flags.has("p"), ...mode === void 0 ? {} : { mode: parseInt(mode, 8) }, signal: context.signal });
|
|
3684
|
-
if (parsed.flags.has("v")) await output(context, `mkdir: created directory '${operand}'
|
|
3730
|
+
if (parsed.flags.has("v")) await output(context, `mkdir: created directory '${escapeText(operand, "display")}'
|
|
3685
3731
|
`);
|
|
3686
3732
|
});
|
|
3687
3733
|
}),
|
|
@@ -3766,7 +3812,7 @@ function filesystemCommands(maxDirectoryEntries) {
|
|
|
3766
3812
|
return;
|
|
3767
3813
|
}
|
|
3768
3814
|
}
|
|
3769
|
-
if (parsed.flags.has("v")) await output(context, `'${operand}' -> '${target}'
|
|
3815
|
+
if (parsed.flags.has("v")) await output(context, `'${escapeText(operand, "display")}' -> '${escapeText(target, "display")}'
|
|
3770
3816
|
`);
|
|
3771
3817
|
});
|
|
3772
3818
|
}),
|
|
@@ -3801,7 +3847,7 @@ function filesystemCommands(maxDirectoryEntries) {
|
|
|
3801
3847
|
} else {
|
|
3802
3848
|
await context.fs.rm(path, { recursive, force: parsed.flags.has("f"), signal: context.signal });
|
|
3803
3849
|
}
|
|
3804
|
-
if (parsed.flags.has("v")) await output(context, `removed '${operand}'
|
|
3850
|
+
if (parsed.flags.has("v")) await output(context, `removed '${escapeText(operand, "display")}'
|
|
3805
3851
|
`);
|
|
3806
3852
|
});
|
|
3807
3853
|
}),
|
|
@@ -3822,7 +3868,7 @@ function filesystemCommands(maxDirectoryEntries) {
|
|
|
3822
3868
|
do {
|
|
3823
3869
|
if (path === "/") throw new FsError("EBUSY", { path });
|
|
3824
3870
|
await removeEmptyDirectory(context, path, readDirectory);
|
|
3825
|
-
if (parsed.flags.has("v")) await output(context, `rmdir: removing directory '${path}'
|
|
3871
|
+
if (parsed.flags.has("v")) await output(context, `rmdir: removing directory '${escapeText(path, "display")}'
|
|
3826
3872
|
`);
|
|
3827
3873
|
path = dirname(path);
|
|
3828
3874
|
} while (parsed.flags.has("p") && path !== "/" && path !== stop);
|
|
@@ -3991,11 +4037,11 @@ function filesystemCommands(maxDirectoryEntries) {
|
|
|
3991
4037
|
if (stat.type === "symlink") {
|
|
3992
4038
|
await admitFilesystemModes(context, "ls", ["link"], [path]);
|
|
3993
4039
|
needCapability(context, "readlink");
|
|
3994
|
-
target = ` -> ${await context.fs.readlink(path, { signal: context.signal })}`;
|
|
4040
|
+
target = ` -> ${escapeText(await context.fs.readlink(path, { signal: context.signal }), "display")}`;
|
|
3995
4041
|
}
|
|
3996
|
-
await output(context, `${modeText(stat)} ${stat.nlink ?? 1} ${stat.uid ?? 0} ${stat.gid ?? 0} ${size} ${date} ${display}${suffix2}${target}
|
|
4042
|
+
await output(context, `${modeText(stat)} ${stat.nlink ?? 1} ${stat.uid ?? 0} ${stat.gid ?? 0} ${size} ${date} ${escapeText(display, "display")}${suffix2}${target}
|
|
3997
4043
|
`);
|
|
3998
|
-
} else await output(context, `${display}${suffix2}
|
|
4044
|
+
} else await output(context, `${escapeText(display, "display")}${suffix2}
|
|
3999
4045
|
`);
|
|
4000
4046
|
outputWritten = true;
|
|
4001
4047
|
};
|
|
@@ -4011,7 +4057,7 @@ function filesystemCommands(maxDirectoryEntries) {
|
|
|
4011
4057
|
ancestors.add(physical);
|
|
4012
4058
|
try {
|
|
4013
4059
|
if (header) {
|
|
4014
|
-
await output(context, `${outputWritten ? "\n" : ""}${display}:
|
|
4060
|
+
await output(context, `${outputWritten ? "\n" : ""}${escapeText(display, "display")}:
|
|
4015
4061
|
`);
|
|
4016
4062
|
outputWritten = true;
|
|
4017
4063
|
}
|
|
@@ -5012,7 +5058,7 @@ function characterSet(specification) {
|
|
|
5012
5058
|
continue;
|
|
5013
5059
|
}
|
|
5014
5060
|
const character = String.fromCodePoint(specification.codePointAt(offset));
|
|
5015
|
-
tokens2.push({ bytes: [...
|
|
5061
|
+
tokens2.push({ bytes: [...encoder3.encode(character)], literal: character === "-" });
|
|
5016
5062
|
offset += character.length;
|
|
5017
5063
|
}
|
|
5018
5064
|
const result = [];
|
|
@@ -5067,7 +5113,7 @@ function streamCommands(maxTeeTargets = 64, maxTailFollowHandles = 64) {
|
|
|
5067
5113
|
for await (const chunk of source) {
|
|
5068
5114
|
const transformed = [];
|
|
5069
5115
|
const append = (text) => {
|
|
5070
|
-
for (const byte of
|
|
5116
|
+
for (const byte of encoder3.encode(text)) transformed.push(byte);
|
|
5071
5117
|
};
|
|
5072
5118
|
for (const byte of chunk) {
|
|
5073
5119
|
if (lineStart && byte === 10 && parsed.flags.has("s") && blankCount > 0) continue;
|
|
@@ -5399,7 +5445,7 @@ var CutOutput = class {
|
|
|
5399
5445
|
let end = Math.min(offset + 4096, text.length);
|
|
5400
5446
|
const last = text.charCodeAt(end - 1);
|
|
5401
5447
|
if (end < text.length && last >= 55296 && last <= 56319) end--;
|
|
5402
|
-
await this.write(
|
|
5448
|
+
await this.write(encoder3.encode(text.slice(offset, end)));
|
|
5403
5449
|
offset = end;
|
|
5404
5450
|
}
|
|
5405
5451
|
}
|
|
@@ -5585,8 +5631,8 @@ function textCommands() {
|
|
|
5585
5631
|
await assertInputRequirements(context, parsed.operands);
|
|
5586
5632
|
if (!parsed.flags.has("c")) await admitTextOutput(context, value(parsed, "o"));
|
|
5587
5633
|
const separatorText = value(parsed, "t");
|
|
5588
|
-
if (separatorText !== void 0 &&
|
|
5589
|
-
const separator = separatorText === void 0 ? void 0 :
|
|
5634
|
+
if (separatorText !== void 0 && encoder3.encode(separatorText).length !== 1) throw new UsageError("field separator must be one byte");
|
|
5635
|
+
const separator = separatorText === void 0 ? void 0 : encoder3.encode(separatorText)[0];
|
|
5590
5636
|
const keys = (parsed.values.get("k") ?? []).map(sortKey);
|
|
5591
5637
|
for (const key of keys.length ? keys : [void 0]) {
|
|
5592
5638
|
const flags = key?.flags.size ? key.flags : parsed.flags;
|
|
@@ -5755,7 +5801,7 @@ function textCommands() {
|
|
|
5755
5801
|
let previousKey;
|
|
5756
5802
|
let count2 = 0;
|
|
5757
5803
|
const selected = () => (!parsed.flags.has("d") || count2 > 1) && (!parsed.flags.has("u") || count2 === 1);
|
|
5758
|
-
const record4 = () => concatenate([...parsed.flags.has("c") ? [
|
|
5804
|
+
const record4 = () => concatenate([...parsed.flags.has("c") ? [encoder3.encode(`${String(count2).padStart(7)} `)] : [], previous, Uint8Array.of(delimiter)]);
|
|
5759
5805
|
for await (const line of lines(input(context, parsed.operands[0]), delimiter)) {
|
|
5760
5806
|
context.signal.throwIfAborted();
|
|
5761
5807
|
const currentKey = key(line.bytes);
|
|
@@ -5937,7 +5983,7 @@ async function splitString(source, environment, work) {
|
|
|
5937
5983
|
work.expansion();
|
|
5938
5984
|
work.account(source);
|
|
5939
5985
|
const result = [];
|
|
5940
|
-
let
|
|
5986
|
+
let parts2 = [];
|
|
5941
5987
|
let active = false;
|
|
5942
5988
|
let quote = "";
|
|
5943
5989
|
const start = () => {
|
|
@@ -5949,11 +5995,11 @@ async function splitString(source, environment, work) {
|
|
|
5949
5995
|
const append = (text) => {
|
|
5950
5996
|
work.account(text);
|
|
5951
5997
|
start();
|
|
5952
|
-
|
|
5998
|
+
parts2.push(text);
|
|
5953
5999
|
};
|
|
5954
6000
|
const finish = () => {
|
|
5955
|
-
if (active) result.push(
|
|
5956
|
-
|
|
6001
|
+
if (active) result.push(parts2.join(""));
|
|
6002
|
+
parts2 = [];
|
|
5957
6003
|
active = false;
|
|
5958
6004
|
};
|
|
5959
6005
|
for (let index = 0; index < source.length; ) {
|
|
@@ -5984,8 +6030,8 @@ async function splitString(source, environment, work) {
|
|
|
5984
6030
|
else finish();
|
|
5985
6031
|
continue;
|
|
5986
6032
|
}
|
|
5987
|
-
const
|
|
5988
|
-
if (Object.hasOwn(
|
|
6033
|
+
const controls2 = { f: "\f", n: "\n", r: "\r", t: " ", v: "\v" };
|
|
6034
|
+
if (Object.hasOwn(controls2, escaped)) append(controls2[escaped]);
|
|
5989
6035
|
else if (`"#$'\\`.includes(escaped)) append(escaped);
|
|
5990
6036
|
else throw new EnvSplitError(`invalid sequence '\\${escaped}' in -S`);
|
|
5991
6037
|
continue;
|
|
@@ -6068,8 +6114,8 @@ async function splitBytes(source, environment, work) {
|
|
|
6068
6114
|
else finish();
|
|
6069
6115
|
continue;
|
|
6070
6116
|
}
|
|
6071
|
-
const
|
|
6072
|
-
if (Object.hasOwn(
|
|
6117
|
+
const controls2 = { 102: 12, 110: 10, 114: 13, 116: 9, 118: 11 };
|
|
6118
|
+
if (Object.hasOwn(controls2, escaped)) append(Uint8Array.of(controls2[escaped]));
|
|
6073
6119
|
else if ([34, 35, 36, 39, 92].includes(escaped)) append(Uint8Array.of(escaped));
|
|
6074
6120
|
else throw new EnvSplitError(`invalid sequence '\\${String.fromCharCode(escaped)}' in -S`);
|
|
6075
6121
|
continue;
|
|
@@ -6085,7 +6131,7 @@ async function splitBytes(source, environment, work) {
|
|
|
6085
6131
|
const name2 = decoder2.decode(source.subarray(index + 2, end));
|
|
6086
6132
|
if (Object.hasOwn(environment, name2)) {
|
|
6087
6133
|
const text = environment[name2];
|
|
6088
|
-
append(
|
|
6134
|
+
append(encoder3.encode(text));
|
|
6089
6135
|
if (work.tick(text.length)) await work.pause();
|
|
6090
6136
|
}
|
|
6091
6137
|
index = end + 1;
|
|
@@ -6274,8 +6320,8 @@ function executionCommands(execute3, configuration = {}) {
|
|
|
6274
6320
|
} catch (error) {
|
|
6275
6321
|
context.signal.throwIfAborted();
|
|
6276
6322
|
if (!(error instanceof EnvSplitError)) throw error;
|
|
6277
|
-
await
|
|
6278
|
-
|
|
6323
|
+
await writeDiagnostic(context.stderr, `${context.command}: ${error.message}
|
|
6324
|
+
`, context.signal);
|
|
6279
6325
|
return { exitCode: 125 };
|
|
6280
6326
|
}
|
|
6281
6327
|
const env = Object.assign(/* @__PURE__ */ Object.create(null), parsed.flags.has("i") ? {} : context.env);
|
|
@@ -6343,7 +6389,7 @@ function executionCommands(execute3, configuration = {}) {
|
|
|
6343
6389
|
}
|
|
6344
6390
|
const command2 = parsed.operands[0] ?? "echo";
|
|
6345
6391
|
const initial = argumentValues.select(operandIndices).slice(1);
|
|
6346
|
-
const baseBytes =
|
|
6392
|
+
const baseBytes = encoder3.encode(command2).length + 1 + initial.values.reduce((sum, argument) => sum + shellValueByteLength(argument) + 1, 0);
|
|
6347
6393
|
if (baseBytes >= maxBytes) throw new UsageError("initial arguments exceed command size limit");
|
|
6348
6394
|
let batch = [];
|
|
6349
6395
|
let bytes2 = baseBytes;
|
|
@@ -6426,9 +6472,9 @@ function executionCommands(execute3, configuration = {}) {
|
|
|
6426
6472
|
if (stop) return;
|
|
6427
6473
|
const childArguments = initial.withValues(replacement === void 0 ? [...initial.values, ...batch] : initial.values.map((argument, index) => replaceArgument(typeof argument === "string" ? argument : initial.bytes(index), replacement, batch[0] ?? "")));
|
|
6428
6474
|
const args = childArguments.args;
|
|
6429
|
-
const size =
|
|
6475
|
+
const size = encoder3.encode(command2).length + 1 + childArguments.values.reduce((sum, argument) => sum + shellValueByteLength(argument) + 1, 0);
|
|
6430
6476
|
if (size > maxBytes) throw new UsageError("expanded arguments exceed command size limit");
|
|
6431
|
-
if (parsed.flags.has("t")) await
|
|
6477
|
+
if (parsed.flags.has("t")) await writeDiagnostic(context.stderr, [command2, ...args].map((argument) => /^[A-Za-z0-9_./-]+$/u.test(argument) ? argument : `'${argument.replaceAll("'", "'\\''")}'`).join(" ") + "\n", context.signal);
|
|
6432
6478
|
if (stop) return;
|
|
6433
6479
|
context.signal.throwIfAborted();
|
|
6434
6480
|
executed = true;
|
|
@@ -6464,7 +6510,7 @@ function executionCommands(execute3, configuration = {}) {
|
|
|
6464
6510
|
try {
|
|
6465
6511
|
for await (const argument of argumentsFrom(source, inputSignal, delimiter, replacement !== void 0)) {
|
|
6466
6512
|
if (stop || delimiter === void 0 && eof !== void 0 && eof !== "" && argument === eof) break;
|
|
6467
|
-
const size =
|
|
6513
|
+
const size = encoder3.encode(argument).length + 1;
|
|
6468
6514
|
if (replacement === void 0 && baseBytes + size > maxBytes) throw new UsageError("single argument exceeds command size limit");
|
|
6469
6515
|
if (batch.length && (batch.length === maxArgs || bytes2 + size > maxBytes)) {
|
|
6470
6516
|
if (parsed.flags.has("x") && batch.length < maxArgs) throw new UsageError("command size limit exceeded");
|
|
@@ -6950,21 +6996,21 @@ function getArrayAssignment(word) {
|
|
|
6950
6996
|
}
|
|
6951
6997
|
function removePrefix(word, length, budget) {
|
|
6952
6998
|
budget.admit();
|
|
6953
|
-
const
|
|
6999
|
+
const parts2 = [];
|
|
6954
7000
|
for (const part of word.parts) {
|
|
6955
|
-
if (length === 0)
|
|
7001
|
+
if (length === 0) parts2.push(part);
|
|
6956
7002
|
else {
|
|
6957
7003
|
if (part.kind !== "text") throw new ShellSyntaxError("Unsupported indexed-array subscript", word.offset);
|
|
6958
7004
|
if (part.value.length <= length) length -= part.value.length;
|
|
6959
7005
|
else {
|
|
6960
7006
|
budget.admit();
|
|
6961
|
-
|
|
7007
|
+
parts2.push({ ...part, value: part.value.slice(length) });
|
|
6962
7008
|
length = 0;
|
|
6963
7009
|
}
|
|
6964
7010
|
}
|
|
6965
7011
|
}
|
|
6966
7012
|
if (length !== 0) throw new ShellSyntaxError("Invalid indexed-array assignment", word.offset);
|
|
6967
|
-
return { offset: word.offset, parts };
|
|
7013
|
+
return { offset: word.offset, parts: parts2 };
|
|
6968
7014
|
}
|
|
6969
7015
|
function elementAssignment(word, budget = new ParseBudget()) {
|
|
6970
7016
|
const source = word.spelling;
|
|
@@ -7520,9 +7566,9 @@ var Lexer = class {
|
|
|
7520
7566
|
}
|
|
7521
7567
|
const offset = this.position;
|
|
7522
7568
|
this.budget.admit();
|
|
7523
|
-
const
|
|
7569
|
+
const parts2 = [];
|
|
7524
7570
|
try {
|
|
7525
|
-
this.expansion(
|
|
7571
|
+
this.expansion(parts2, true);
|
|
7526
7572
|
} catch (error) {
|
|
7527
7573
|
if (!(error instanceof ShellSyntaxError) || /nesting|exceeds/u.test(error.reason)) throw error;
|
|
7528
7574
|
if (this.source.startsWith("${", offset)) throw new HereDocumentSyntaxError(`shell: line ${this.documentLine}: ${this.source}: bad substitution
|
|
@@ -7534,7 +7580,7 @@ var Lexer = class {
|
|
|
7534
7580
|
throw new HereDocumentSyntaxError(`shell: line ${this.documentLine}: ${error.message}
|
|
7535
7581
|
`);
|
|
7536
7582
|
}
|
|
7537
|
-
yield { offset, parts };
|
|
7583
|
+
yield { offset, parts: parts2 };
|
|
7538
7584
|
} else if (current === "\\" && /[$`\\]/u.test(this.source[this.position + 1] ?? "")) {
|
|
7539
7585
|
text += this.source[this.position + 1];
|
|
7540
7586
|
this.position += 2;
|
|
@@ -7602,7 +7648,7 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
7602
7648
|
const offset = this.position;
|
|
7603
7649
|
const reduction = this.printedNewlineReduction;
|
|
7604
7650
|
const unprinted = this.unprintedWords;
|
|
7605
|
-
const
|
|
7651
|
+
const parts2 = [];
|
|
7606
7652
|
let parentheses = 0;
|
|
7607
7653
|
let conditionals = 0;
|
|
7608
7654
|
let patternParentheses = 0;
|
|
@@ -7618,7 +7664,7 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
7618
7664
|
regexBracketFirst = false;
|
|
7619
7665
|
regexBracketNegation = false;
|
|
7620
7666
|
}
|
|
7621
|
-
const previous =
|
|
7667
|
+
const previous = parts2.at(-1);
|
|
7622
7668
|
if (previous?.kind === "text" && previous.quoted === quoted && !previous.byteValue && typeof value2 === "string" && !ansi && !expansionSpellings.get(previous)?.ansi) {
|
|
7623
7669
|
previous.value += value2;
|
|
7624
7670
|
const spelling2 = expansionSpellings.get(previous);
|
|
@@ -7632,7 +7678,7 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
7632
7678
|
this.budget.admit();
|
|
7633
7679
|
expansionSpellings.set(part, { source: this.source, start, end, ...ansi ? { ansi } : {} });
|
|
7634
7680
|
}
|
|
7635
|
-
|
|
7681
|
+
parts2.push(part);
|
|
7636
7682
|
}
|
|
7637
7683
|
};
|
|
7638
7684
|
while (this.position < this.source.length) {
|
|
@@ -7697,14 +7743,14 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
7697
7743
|
const quoteLine = this.lineAt(this.position);
|
|
7698
7744
|
this.position++;
|
|
7699
7745
|
text("", true, true, this.position - 1, this.position);
|
|
7700
|
-
const quoteParts =
|
|
7746
|
+
const quoteParts = parts2.length;
|
|
7701
7747
|
while (this.position < this.source.length && this.source[this.position] !== '"') {
|
|
7702
7748
|
const inner = this.source[this.position];
|
|
7703
7749
|
const opaque2 = this.braceReplay?.get(this.position);
|
|
7704
7750
|
if (opaque2 !== void 0) {
|
|
7705
7751
|
text(opaque2, true);
|
|
7706
7752
|
this.position++;
|
|
7707
|
-
} else if (!literal && (inner === "$" || inner === "`")) this.expansion(
|
|
7753
|
+
} else if (!literal && (inner === "$" || inner === "`")) this.expansion(parts2, true);
|
|
7708
7754
|
else if (inner === "\\" && /[$`"\\\n]/u.test(this.source[this.position + 1] ?? "")) {
|
|
7709
7755
|
const escaped = this.source[this.position + 1];
|
|
7710
7756
|
if (escaped !== "\n") text(escaped, true, false, this.position, this.position + 2);
|
|
@@ -7716,8 +7762,8 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
7716
7762
|
}
|
|
7717
7763
|
}
|
|
7718
7764
|
if (this.source[this.position] !== '"' && !this.braceReplay) this.error("Unterminated double quote", { quote: '"', line: quoteLine });
|
|
7719
|
-
if (
|
|
7720
|
-
const spelling2 = expansionSpellings.get(
|
|
7765
|
+
if (parts2.length === quoteParts) setQuoteMarker(parts2.at(-1), false);
|
|
7766
|
+
const spelling2 = expansionSpellings.get(parts2.at(-1));
|
|
7721
7767
|
if (spelling2) spelling2.end = Math.min(this.position + 1, this.source.length);
|
|
7722
7768
|
if (this.position < this.source.length) this.position++;
|
|
7723
7769
|
} else if (current === "\\") {
|
|
@@ -7736,7 +7782,7 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
7736
7782
|
if (literal) {
|
|
7737
7783
|
if (current === "$" && ["'", '"'].includes(this.source[this.position + 1] ?? "")) this.error("Unsupported shell quoting in here-document delimiter");
|
|
7738
7784
|
text(this.literalExpansion(), current === "`");
|
|
7739
|
-
} else this.expansion(
|
|
7785
|
+
} else this.expansion(parts2, enclosingQuoted);
|
|
7740
7786
|
} else {
|
|
7741
7787
|
if (arithmetic) {
|
|
7742
7788
|
if (current === "(") parentheses++;
|
|
@@ -7750,13 +7796,13 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
7750
7796
|
}
|
|
7751
7797
|
if (conditionalPattern === "regex" && patternParentheses > 0) this.error("Unterminated conditional regular expression group");
|
|
7752
7798
|
const printedNewlines = this.source.slice(offset, this.position).split("\n").length - 1 - (this.printedNewlineReduction - reduction);
|
|
7753
|
-
return { parts, offset, ...unprinted === this.unprintedWords ? { printedNewlines } : {}, ...plain ? { plain:
|
|
7799
|
+
return { parts: parts2, offset, ...unprinted === this.unprintedWords ? { printedNewlines } : {}, ...plain ? { plain: parts2.map((part) => part.kind === "text" ? part.value : "").join("") } : {} };
|
|
7754
7800
|
}
|
|
7755
7801
|
ansiWord() {
|
|
7756
7802
|
const quoteLine = this.lineAt(this.position);
|
|
7757
7803
|
this.position += 2;
|
|
7758
7804
|
const bytes2 = [];
|
|
7759
|
-
const
|
|
7805
|
+
const encoder4 = new TextEncoder();
|
|
7760
7806
|
const escapes = { a: 7, b: 8, e: 27, E: 27, f: 12, n: 10, r: 13, t: 9, v: 11, "\\": 92, "'": 39, '"': 34, "?": 63 };
|
|
7761
7807
|
while (this.position < this.source.length) {
|
|
7762
7808
|
const character = String.fromCodePoint(this.source.codePointAt(this.position));
|
|
@@ -7773,7 +7819,7 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
7773
7819
|
}
|
|
7774
7820
|
}
|
|
7775
7821
|
if (character !== "\\") {
|
|
7776
|
-
bytes2.push(...
|
|
7822
|
+
bytes2.push(...encoder4.encode(character));
|
|
7777
7823
|
continue;
|
|
7778
7824
|
}
|
|
7779
7825
|
const escape = this.source[this.position++];
|
|
@@ -7797,26 +7843,26 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
7797
7843
|
const code = parseInt(digits, 16);
|
|
7798
7844
|
if (escape === "x") bytes2.push(code);
|
|
7799
7845
|
else if (this.byteLocale && code > 127) {
|
|
7800
|
-
bytes2.push(...
|
|
7846
|
+
bytes2.push(...encoder4.encode(`\\${code <= 65535 ? "u" : "U"}${code.toString(16).toUpperCase().padStart(code <= 65535 ? 4 : 8, "0")}`));
|
|
7801
7847
|
} else {
|
|
7802
7848
|
if (code > 1114111 || code >= 55296 && code <= 57343) this.error("Unsupported non-scalar ANSI-C Unicode escape");
|
|
7803
|
-
bytes2.push(...
|
|
7849
|
+
bytes2.push(...encoder4.encode(String.fromCodePoint(code)));
|
|
7804
7850
|
}
|
|
7805
7851
|
} else if (escape === "c" && this.source[this.position] !== "'" && this.position < this.source.length) {
|
|
7806
7852
|
const control = this.source[this.position++];
|
|
7807
7853
|
if (control === "\\" && this.source[this.position] === "\\") this.position++;
|
|
7808
7854
|
bytes2.push(control === "?" ? 127 : control.toUpperCase().charCodeAt(0) & 31);
|
|
7809
|
-
} else bytes2.push(92, ...
|
|
7855
|
+
} else bytes2.push(92, ...encoder4.encode(escape));
|
|
7810
7856
|
}
|
|
7811
7857
|
this.error("Unterminated ANSI-C quote", { quote: "'", line: quoteLine });
|
|
7812
7858
|
}
|
|
7813
|
-
expansion(
|
|
7859
|
+
expansion(parts2, quoted) {
|
|
7814
7860
|
this.budget.admit();
|
|
7815
7861
|
const spellingStart = this.position;
|
|
7816
7862
|
const line = this.documentLine ?? this.lineAt(this.position);
|
|
7817
7863
|
if (this.source[this.position] === "`") {
|
|
7818
7864
|
if (this.braceReplay && this.position === this.source.length - 1) {
|
|
7819
|
-
|
|
7865
|
+
parts2.push({ kind: "text", value: "`", quoted });
|
|
7820
7866
|
this.position++;
|
|
7821
7867
|
return;
|
|
7822
7868
|
}
|
|
@@ -7829,15 +7875,15 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
7829
7875
|
if (this.source[this.position] !== "`") this.error("Unterminated command substitution");
|
|
7830
7876
|
this.position++;
|
|
7831
7877
|
try {
|
|
7832
|
-
|
|
7878
|
+
parts2.push({ kind: "substitution", script: parseSource(source, this.depth + this.operandDepth + 1, this.warnings, line - 1, this.byteLocale, this.budget), line, quoted });
|
|
7833
7879
|
} catch (error) {
|
|
7834
7880
|
if (this.documentLine === void 0 || !(error instanceof ShellSyntaxError) || /nesting|exceeds/u.test(error.reason)) throw error;
|
|
7835
7881
|
this.budget.admit();
|
|
7836
|
-
|
|
7882
|
+
parts2.push({ kind: "failed-substitution", diagnostic: this.documentSubstitutionError(source, error, true).diagnostic, quoted });
|
|
7837
7883
|
}
|
|
7838
7884
|
if (this.documentLine === void 0) {
|
|
7839
7885
|
this.budget.admit();
|
|
7840
|
-
expansionSpellings.set(
|
|
7886
|
+
expansionSpellings.set(parts2.at(-1), { source: this.source, start: spellingStart, end: this.position });
|
|
7841
7887
|
}
|
|
7842
7888
|
return;
|
|
7843
7889
|
}
|
|
@@ -7847,7 +7893,7 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
7847
7893
|
const start = this.position + 2;
|
|
7848
7894
|
const end = arithmeticEnd(this.source, start);
|
|
7849
7895
|
const source = this.source.slice(start, end);
|
|
7850
|
-
|
|
7896
|
+
parts2.push({ kind: "arithmetic", expression: prepareArithmetic(source, this.budget), source, line, quoted });
|
|
7851
7897
|
this.position = end + 2;
|
|
7852
7898
|
} else if (this.source[this.position] === "(") {
|
|
7853
7899
|
const start = this.position + 1;
|
|
@@ -7870,7 +7916,7 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
7870
7916
|
this.position += nested.current.end + 1;
|
|
7871
7917
|
if (script.printedNewlines === void 0) this.unprintedWords++;
|
|
7872
7918
|
else this.printedNewlineReduction += this.source.slice(start, this.position - 1).split("\n").length - 1 - script.printedNewlines;
|
|
7873
|
-
|
|
7919
|
+
parts2.push({ kind: "substitution", script, line, sourceLine: script.line ?? line, quoted });
|
|
7874
7920
|
} else if (this.source[this.position] === "{") {
|
|
7875
7921
|
this.position++;
|
|
7876
7922
|
const parameterStart = this.position - 2;
|
|
@@ -7925,17 +7971,17 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
7925
7971
|
this.position++;
|
|
7926
7972
|
const part = { kind: "variable", name: name2, quoted, line, ...length ? { length } : {}, ...operator ? { operator, alternate } : {}, ...replacement ? { replacement } : {}, ...substring ? { substring } : {} };
|
|
7927
7973
|
if (selector) setArraySelector(part, selector);
|
|
7928
|
-
|
|
7974
|
+
parts2.push(part);
|
|
7929
7975
|
} else {
|
|
7930
7976
|
const name2 = /^(?:[a-zA-Z_][a-zA-Z_0-9]*|[?@*#0-9-])/u.exec(this.source.slice(this.position))?.[0];
|
|
7931
7977
|
if (name2) {
|
|
7932
7978
|
this.position += name2.length;
|
|
7933
|
-
|
|
7934
|
-
} else
|
|
7979
|
+
parts2.push({ kind: "variable", name: name2, quoted, line });
|
|
7980
|
+
} else parts2.push({ kind: "text", value: "$", quoted });
|
|
7935
7981
|
}
|
|
7936
7982
|
if (this.documentLine === void 0) {
|
|
7937
7983
|
this.budget.admit();
|
|
7938
|
-
expansionSpellings.set(
|
|
7984
|
+
expansionSpellings.set(parts2.at(-1), { source: this.source, start: spellingStart, end: this.position });
|
|
7939
7985
|
}
|
|
7940
7986
|
}
|
|
7941
7987
|
};
|
|
@@ -8805,7 +8851,7 @@ async function* expandBraces(word, budget, signal) {
|
|
|
8805
8851
|
const materialized = budget.values.scope();
|
|
8806
8852
|
try {
|
|
8807
8853
|
materialized.reserve(64, 0);
|
|
8808
|
-
const
|
|
8854
|
+
const parts2 = [];
|
|
8809
8855
|
const generatedSyntax = /* @__PURE__ */ new WeakSet();
|
|
8810
8856
|
const pending = [{ node: root, rank }];
|
|
8811
8857
|
while (pending.length) {
|
|
@@ -8847,24 +8893,24 @@ async function* expandBraces(word, budget, signal) {
|
|
|
8847
8893
|
generatedSyntax.add(part);
|
|
8848
8894
|
}
|
|
8849
8895
|
}
|
|
8850
|
-
const previous =
|
|
8896
|
+
const previous = parts2.at(-1);
|
|
8851
8897
|
if (part.kind === "text" && !part.quoted && !part.byteValue && !generatedSyntax.has(part) && previous?.kind === "text" && !previous.quoted && !previous.byteValue && !generatedSyntax.has(previous)) {
|
|
8852
8898
|
materialized.reserve((previous.value.length + part.value.length) * 2, 0);
|
|
8853
|
-
|
|
8854
|
-
} else
|
|
8899
|
+
parts2[parts2.length - 1] = { kind: "text", value: previous.value + part.value, quoted: false };
|
|
8900
|
+
} else parts2.push(part);
|
|
8855
8901
|
}
|
|
8856
8902
|
}
|
|
8857
|
-
for (let index = 0; index <
|
|
8903
|
+
for (let index = 0; index < parts2.length; index++) {
|
|
8858
8904
|
await checkpoint();
|
|
8859
|
-
const part =
|
|
8905
|
+
const part = parts2[index];
|
|
8860
8906
|
if (!generatedSyntax.has(part) || part.kind !== "text") continue;
|
|
8861
8907
|
materialized.reserve(128, 0);
|
|
8862
8908
|
const fragments = [];
|
|
8863
8909
|
const opaque = /* @__PURE__ */ new Map();
|
|
8864
8910
|
let length = 0;
|
|
8865
|
-
for (let position = index; position <
|
|
8911
|
+
for (let position = index; position < parts2.length; position++) {
|
|
8866
8912
|
await checkpoint();
|
|
8867
|
-
const current =
|
|
8913
|
+
const current = parts2[position];
|
|
8868
8914
|
const spelling2 = expansionSpellings.get(current);
|
|
8869
8915
|
materialized.reserve(32, 0);
|
|
8870
8916
|
let fragment;
|
|
@@ -8892,11 +8938,11 @@ async function* expandBraces(word, budget, signal) {
|
|
|
8892
8938
|
throw new BraceExpansionFailure(error.reason);
|
|
8893
8939
|
}
|
|
8894
8940
|
materialized.reserve(replayed.parts.length * 32, 0);
|
|
8895
|
-
|
|
8896
|
-
for (const replayedPart of replayed.parts)
|
|
8941
|
+
parts2.length = index;
|
|
8942
|
+
for (const replayedPart of replayed.parts) parts2.push(replayedPart);
|
|
8897
8943
|
break;
|
|
8898
8944
|
}
|
|
8899
|
-
yield { parts, offset: word.offset };
|
|
8945
|
+
yield { parts: parts2, offset: word.offset };
|
|
8900
8946
|
} finally {
|
|
8901
8947
|
materialized.close();
|
|
8902
8948
|
}
|
|
@@ -9703,11 +9749,11 @@ function stagedFailure(state, reason) {
|
|
|
9703
9749
|
throwAdmissionFailure(state);
|
|
9704
9750
|
throw reason;
|
|
9705
9751
|
}
|
|
9706
|
-
function prepareControls(parent,
|
|
9707
|
-
if (
|
|
9708
|
-
if (!Array.isArray(
|
|
9752
|
+
function prepareControls(parent, controls2) {
|
|
9753
|
+
if (controls2 === void 0) return Object.freeze([]);
|
|
9754
|
+
if (!Array.isArray(controls2)) return stagedFailure(parent, new TypeError("Cancellation controls must be an array"));
|
|
9709
9755
|
const prepared = [];
|
|
9710
|
-
for (const input3 of
|
|
9756
|
+
for (const input3 of controls2) {
|
|
9711
9757
|
let role;
|
|
9712
9758
|
let signal;
|
|
9713
9759
|
try {
|
|
@@ -9725,13 +9771,13 @@ function prepareControls(parent, controls) {
|
|
|
9725
9771
|
throwAdmissionFailure(parent);
|
|
9726
9772
|
return Object.freeze(prepared);
|
|
9727
9773
|
}
|
|
9728
|
-
function makePrepared(parent, localSignal,
|
|
9774
|
+
function makePrepared(parent, localSignal, controls2, admission) {
|
|
9729
9775
|
const state = {
|
|
9730
9776
|
parent,
|
|
9731
9777
|
localSignal,
|
|
9732
|
-
controls,
|
|
9778
|
+
controls: controls2,
|
|
9733
9779
|
admission,
|
|
9734
|
-
owned: localSignal !== void 0 ||
|
|
9780
|
+
owned: localSignal !== void 0 || controls2.length > 0,
|
|
9735
9781
|
replayError: new Error("Prepared cancellation admission was already activated"),
|
|
9736
9782
|
activated: false
|
|
9737
9783
|
};
|
|
@@ -9751,7 +9797,7 @@ function throwLocalActivationFailure(state) {
|
|
|
9751
9797
|
const failure = localActivationFailure(state);
|
|
9752
9798
|
if (failure.failed) throw failure.reason;
|
|
9753
9799
|
}
|
|
9754
|
-
function prepareChildCancellation(parent, options3, snapshot,
|
|
9800
|
+
function prepareChildCancellation(parent, options3, snapshot, controls2) {
|
|
9755
9801
|
const parentState = requireLink(parent);
|
|
9756
9802
|
throwAdmissionFailure(parentState);
|
|
9757
9803
|
let localSignal;
|
|
@@ -9773,7 +9819,7 @@ function prepareChildCancellation(parent, options3, snapshot, controls) {
|
|
|
9773
9819
|
throwAdmissionFailure(parentState);
|
|
9774
9820
|
if (localSignal !== void 0 && signalAborted(localSignal)) throw localSignal.reason;
|
|
9775
9821
|
}
|
|
9776
|
-
const preparedControls = prepareControls(parentState,
|
|
9822
|
+
const preparedControls = prepareControls(parentState, controls2);
|
|
9777
9823
|
if (localSignal === void 0 && preparedControls.length === 0) {
|
|
9778
9824
|
return makePrepared(parentState, void 0, preparedControls, void 0);
|
|
9779
9825
|
}
|
|
@@ -9846,16 +9892,16 @@ function createRootCancellationLink(input3) {
|
|
|
9846
9892
|
const admission = validateSnapshot(input3.admission);
|
|
9847
9893
|
if (admission.depth !== 0) throw new RangeError("Root cancellation depth must be zero");
|
|
9848
9894
|
if (input3.callerSignal !== void 0 && !nativeSignal(input3.callerSignal)) throw new TypeError("Root caller signal must be an AbortSignal");
|
|
9849
|
-
const
|
|
9850
|
-
if (!Array.isArray(
|
|
9851
|
-
for (const control of
|
|
9895
|
+
const controls2 = input3.controls ?? [];
|
|
9896
|
+
if (!Array.isArray(controls2)) throw new TypeError("Cancellation controls must be an array");
|
|
9897
|
+
for (const control of controls2) {
|
|
9852
9898
|
if (!control || typeof control !== "object" || control.role !== "budget-control" && control.role !== "pipeline-control" || !nativeSignal(control.signal)) throw new TypeError("Invalid cancellation control origin");
|
|
9853
9899
|
}
|
|
9854
|
-
const required = 1 + Number(input3.callerSignal !== void 0 && !signalAborted(input3.callerSignal)) +
|
|
9900
|
+
const required = 1 + Number(input3.callerSignal !== void 0 && !signalAborted(input3.callerSignal)) + controls2.filter((control) => !signalAborted(control.signal)).length;
|
|
9855
9901
|
if (admission.resourceLimit < required) throw new CancellationCapacityError();
|
|
9856
9902
|
const state = initializeState(void 0, admission);
|
|
9857
9903
|
state.rootCaller = input3.callerSignal === void 0 ? void 0 : Object.freeze({ role: "root-caller", signal: input3.callerSignal, frame: state.boundary });
|
|
9858
|
-
state.controls = Object.freeze(
|
|
9904
|
+
state.controls = Object.freeze(controls2.map((control) => Object.freeze({
|
|
9859
9905
|
role: control.role,
|
|
9860
9906
|
signal: control.signal,
|
|
9861
9907
|
frame: state.boundary
|
|
@@ -12686,16 +12732,16 @@ var Runtime = class _Runtime {
|
|
|
12686
12732
|
resourceLimit: _Runtime.cancellationResourceLimit(budget, 0, maxDepth, 2)
|
|
12687
12733
|
};
|
|
12688
12734
|
}
|
|
12689
|
-
static cancellationResourceLimit(budget, depth, maxDepth,
|
|
12735
|
+
static cancellationResourceLimit(budget, depth, maxDepth, controls2) {
|
|
12690
12736
|
const remainingCommands = Math.max(0, budget.limits.maxCommands - budget.commands);
|
|
12691
12737
|
const remainingDepth = Math.max(0, maxDepth - depth);
|
|
12692
|
-
return saturatedSum(saturatedSum(4,
|
|
12738
|
+
return saturatedSum(saturatedSum(4, controls2), saturatedSum(remainingCommands, remainingDepth));
|
|
12693
12739
|
}
|
|
12694
|
-
cancellationAdmission(depth,
|
|
12740
|
+
cancellationAdmission(depth, controls2 = 0) {
|
|
12695
12741
|
return {
|
|
12696
12742
|
depth,
|
|
12697
12743
|
maxDepth: this.cancellationMaxDepth,
|
|
12698
|
-
resourceLimit: _Runtime.cancellationResourceLimit(this.budget, depth, this.cancellationMaxDepth,
|
|
12744
|
+
resourceLimit: _Runtime.cancellationResourceLimit(this.budget, depth, this.cancellationMaxDepth, controls2)
|
|
12699
12745
|
};
|
|
12700
12746
|
}
|
|
12701
12747
|
observeRuntimeReturn(rawReturn, frame, downstream = () => void 0) {
|
|
@@ -12794,7 +12840,7 @@ var Runtime = class _Runtime {
|
|
|
12794
12840
|
if (this.outcomeFrame) this.outcomeFrame.report = void 0;
|
|
12795
12841
|
}
|
|
12796
12842
|
diagnostic(io, text) {
|
|
12797
|
-
return
|
|
12843
|
+
return writeDiagnostic(io.stderr, `${io.scriptName ?? "shell"}: line ${io.diagnosticLine ?? 1}: ${text}
|
|
12798
12844
|
`);
|
|
12799
12845
|
}
|
|
12800
12846
|
writeVariable(state, name2, value2, origin = "assignment") {
|
|
@@ -12945,10 +12991,10 @@ var Runtime = class _Runtime {
|
|
|
12945
12991
|
await textToken(store.owner, env[key], this.signal);
|
|
12946
12992
|
publications.set(key, operation.reserve({ generation: true, version: true, epoch: true, work: 8 }));
|
|
12947
12993
|
}
|
|
12948
|
-
const
|
|
12994
|
+
const controls2 = operation.reserve({ epoch: true, work: state.exported.size + keys.length + 5 });
|
|
12949
12995
|
this.signal.throwIfAborted();
|
|
12950
12996
|
if (stateMonitor(state).epoch !== epoch) throw new ArrayFailure("stale state snapshot");
|
|
12951
|
-
stateMonitor(state).publish(
|
|
12997
|
+
stateMonitor(state).publish(controls2, void 0, () => {
|
|
12952
12998
|
for (const key of state.exported) delete state.variables[key];
|
|
12953
12999
|
state.exported = new Set(keys);
|
|
12954
13000
|
});
|
|
@@ -13268,14 +13314,14 @@ var Runtime = class _Runtime {
|
|
|
13268
13314
|
const incoming = pipes[index - 1];
|
|
13269
13315
|
const outgoing = pipes[index];
|
|
13270
13316
|
const childDepth = this.cancellationDepth + 1;
|
|
13271
|
-
const
|
|
13317
|
+
const controls2 = [
|
|
13272
13318
|
{ role: "pipeline-control", signal: controllers[index].signal }
|
|
13273
13319
|
];
|
|
13274
13320
|
const prepared = prepareChildCancellation(
|
|
13275
13321
|
this.cancellation,
|
|
13276
13322
|
void 0,
|
|
13277
|
-
this.cancellationAdmission(childDepth,
|
|
13278
|
-
|
|
13323
|
+
this.cancellationAdmission(childDepth, controls2.length),
|
|
13324
|
+
controls2
|
|
13279
13325
|
);
|
|
13280
13326
|
const owner = new InvocationCancellationOwner(io[invocationScope], prepared, this.cancellationState);
|
|
13281
13327
|
let boundary;
|
|
@@ -13629,7 +13675,7 @@ var Runtime = class _Runtime {
|
|
|
13629
13675
|
if (error instanceof Flow || error instanceof ShellLimitError || error instanceof ShellSyntaxError) throw error;
|
|
13630
13676
|
this.clearOutcomeReport();
|
|
13631
13677
|
if (error instanceof HereDocumentSyntaxError) {
|
|
13632
|
-
await
|
|
13678
|
+
await writeDiagnostic(io.stderr, error.diagnostic);
|
|
13633
13679
|
if (command2.kind !== "simple" && command2.kind !== "subshell" && command2.kind !== "arithmetic" && command2.kind !== "conditional") this.errexit(1, state, io);
|
|
13634
13680
|
return 1;
|
|
13635
13681
|
}
|
|
@@ -13641,7 +13687,7 @@ var Runtime = class _Runtime {
|
|
|
13641
13687
|
if (error instanceof NounsetFailure || error instanceof ParameterExpansionFailure) {
|
|
13642
13688
|
const detail = error instanceof ParameterExpansionFailure ? diagnostic3 ?? message(error) : message(error);
|
|
13643
13689
|
try {
|
|
13644
|
-
await
|
|
13690
|
+
await writeDiagnostic(io.stderr, `${io.scriptName ?? "shell"}: line ${line}: ${detail}
|
|
13645
13691
|
`);
|
|
13646
13692
|
} catch (reason) {
|
|
13647
13693
|
this.signal.throwIfAborted();
|
|
@@ -13651,11 +13697,11 @@ var Runtime = class _Runtime {
|
|
|
13651
13697
|
}
|
|
13652
13698
|
throw completedExit(error instanceof ParameterExpansionFailure && !state.isolated ? 127 : 1);
|
|
13653
13699
|
}
|
|
13654
|
-
if (error instanceof ArrayFailure) await
|
|
13700
|
+
if (error instanceof ArrayFailure) await writeDiagnostic(io.stderr, `${io.scriptName ?? "shell"}: line ${line}: ${diagnostic3 ?? message(error)}
|
|
13655
13701
|
`);
|
|
13656
13702
|
else {
|
|
13657
13703
|
try {
|
|
13658
|
-
await
|
|
13704
|
+
await writeDiagnostic(io.stderr, `${io.scriptName ?? "shell"}: line ${line}: ${diagnostic3 ?? message(error)}
|
|
13659
13705
|
`);
|
|
13660
13706
|
} catch {
|
|
13661
13707
|
this.signal.throwIfAborted();
|
|
@@ -13700,7 +13746,7 @@ var Runtime = class _Runtime {
|
|
|
13700
13746
|
try {
|
|
13701
13747
|
for (const word of hereDocumentWords(document, line, byteLocale(state.variables), warnings, this.budget.parsing)) {
|
|
13702
13748
|
this.signal.throwIfAborted();
|
|
13703
|
-
for (const warning of warnings.splice(0)) await
|
|
13749
|
+
for (const warning of warnings.splice(0)) await writeDiagnostic(io.stderr, `shell: warning: ${warning}
|
|
13704
13750
|
`);
|
|
13705
13751
|
if (++words % 128 === 0) await yieldTurn(this.signal);
|
|
13706
13752
|
const part = (await this.word(word, state, io, false)).join("");
|
|
@@ -13709,7 +13755,7 @@ var Runtime = class _Runtime {
|
|
|
13709
13755
|
value2 += part;
|
|
13710
13756
|
}
|
|
13711
13757
|
} finally {
|
|
13712
|
-
for (const warning of warnings.splice(0)) await
|
|
13758
|
+
for (const warning of warnings.splice(0)) await writeDiagnostic(io.stderr, `shell: warning: ${warning}
|
|
13713
13759
|
`);
|
|
13714
13760
|
}
|
|
13715
13761
|
return value2;
|
|
@@ -14402,8 +14448,8 @@ var Runtime = class _Runtime {
|
|
|
14402
14448
|
} else {
|
|
14403
14449
|
if (command2 && flag !== "p") {
|
|
14404
14450
|
await this.diagnostic({ ...io, ...context }, `command: -${flag}: invalid option`);
|
|
14405
|
-
await
|
|
14406
|
-
} else await
|
|
14451
|
+
await writeDiagnostic(context.stderr, "command: usage: command [-pVv] command [arg ...]\n");
|
|
14452
|
+
} else await writeDiagnostic(context.stderr, `${context.command}: ${option}: unsupported option
|
|
14407
14453
|
`);
|
|
14408
14454
|
return 2;
|
|
14409
14455
|
}
|
|
@@ -14452,7 +14498,7 @@ var Runtime = class _Runtime {
|
|
|
14452
14498
|
}));
|
|
14453
14499
|
}
|
|
14454
14500
|
if (!matches.length) {
|
|
14455
|
-
if (mode === "describe") await
|
|
14501
|
+
if (mode === "describe") await writeDiagnostic(context.stderr, `${io.scriptName ?? "shell"}: line ${io.diagnosticLine ?? 1}: ${context.command}: ${name2}: not found
|
|
14456
14502
|
`);
|
|
14457
14503
|
continue;
|
|
14458
14504
|
}
|
|
@@ -14554,7 +14600,7 @@ ${functionDisplay(name2, state.functions.get(name2))}`;
|
|
|
14554
14600
|
}
|
|
14555
14601
|
const flags = option.slice(1);
|
|
14556
14602
|
if (!flags.length || [...flags].some((flag) => !(option[0] === "-" ? "cseB" : "eB").includes(flag))) {
|
|
14557
|
-
await
|
|
14603
|
+
await writeDiagnostic(context.stderr, `${context.command}: ${option}: unsupported option; supported flags are -c, -s, -e, +e, -B, +B and +/-o braceexpand
|
|
14558
14604
|
`);
|
|
14559
14605
|
return 2;
|
|
14560
14606
|
}
|
|
@@ -14566,7 +14612,7 @@ ${functionDisplay(name2, state.functions.get(name2))}`;
|
|
|
14566
14612
|
if (!commandString && !standardInput && args.length) return this.scriptFile(context, state, io, args[0], args.slice(1), false, errexit, loadedSource, braceexpand);
|
|
14567
14613
|
const source = commandString ? args.shift() : void 0;
|
|
14568
14614
|
if (commandString && source === void 0) {
|
|
14569
|
-
await
|
|
14615
|
+
await writeDiagnostic(context.stderr, `${context.command}: -c: option requires an argument
|
|
14570
14616
|
`);
|
|
14571
14617
|
return 2;
|
|
14572
14618
|
}
|
|
@@ -14586,15 +14632,15 @@ ${functionDisplay(name2, state.functions.get(name2))}`;
|
|
|
14586
14632
|
const offset = io.diagnosticOffset ?? 0;
|
|
14587
14633
|
const line = source.slice(0, error.offset).split("\n").length;
|
|
14588
14634
|
const prefix2 = `${io.scriptName ?? "shell"}:${commandString ? " -c:" : ""}`;
|
|
14589
|
-
if (error.unclosedQuote) await
|
|
14635
|
+
if (error.unclosedQuote) await writeDiagnostic(io.stderr, `${prefix2} line ${offset + error.unclosedQuote.line}: unexpected EOF while looking for matching \`${error.unclosedQuote.quote}'
|
|
14590
14636
|
`);
|
|
14591
14637
|
else if (error.offset >= source.length && !/Unterminated|nesting|Unsupported/u.test(error.reason)) {
|
|
14592
14638
|
const context = error.incompleteCommand ? ` from \`${error.incompleteCommand.name}' command on line ${offset + error.incompleteCommand.line}` : "";
|
|
14593
|
-
await
|
|
14639
|
+
await writeDiagnostic(io.stderr, `${prefix2} line ${offset + source.split("\n").length + Number(!source.endsWith("\n"))}: syntax error: unexpected end of file${context}
|
|
14594
14640
|
`);
|
|
14595
14641
|
} else {
|
|
14596
14642
|
const token = /^[;&|()<>]|^[^\s;&|()<>]+/u.exec(source.slice(error.offset))?.[0] ?? "newline";
|
|
14597
|
-
await
|
|
14643
|
+
await writeDiagnostic(io.stderr, `${prefix2} line ${offset + line}: syntax error near unexpected token \`${token}'
|
|
14598
14644
|
${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
14599
14645
|
`);
|
|
14600
14646
|
}
|
|
@@ -14608,7 +14654,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
14608
14654
|
do {
|
|
14609
14655
|
this.signal.throwIfAborted();
|
|
14610
14656
|
const unit = parseShellUnit(source, position, byteLocale(state.variables), this.budget.parsing, lineIndex);
|
|
14611
|
-
for (const warning of unit.script.warnings ?? []) await
|
|
14657
|
+
for (const warning of unit.script.warnings ?? []) await writeDiagnostic(io.stderr, `${io.scriptName}: warning: ${warning}
|
|
14612
14658
|
`);
|
|
14613
14659
|
if (unit.script.lists.length) {
|
|
14614
14660
|
const result = await this.runUnit(unit.script, state, io);
|
|
@@ -14650,7 +14696,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
14650
14696
|
try {
|
|
14651
14697
|
const unit = eof ? parseShellUnit(source, 0, byteLocale(state.variables), this.budget.parsing, lineIndex) : parseShellInputUnit(source, byteLocale(state.variables), this.budget.parsing, lineIndex);
|
|
14652
14698
|
if (unit) {
|
|
14653
|
-
for (const warning of unit.script.warnings ?? []) await
|
|
14699
|
+
for (const warning of unit.script.warnings ?? []) await writeDiagnostic(io.stderr, `${io.scriptName}: warning: ${warning}
|
|
14654
14700
|
`);
|
|
14655
14701
|
if (unit.script.lists.length) {
|
|
14656
14702
|
const result = await this.runUnit(unit.script, state, unitIO);
|
|
@@ -14828,7 +14874,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
14828
14874
|
}
|
|
14829
14875
|
if (direct) return { exitCode: await runtime.scriptFile(forwarded, state2, childIO, command2, forwarded.args, true) };
|
|
14830
14876
|
if (definition) return definition.execute(forwarded);
|
|
14831
|
-
await
|
|
14877
|
+
await writeDiagnostic(forwarded.stderr, `env: ${command2}: command not found
|
|
14832
14878
|
`);
|
|
14833
14879
|
return { exitCode: 127 };
|
|
14834
14880
|
}, void 0, options3.stdin !== context.stdin ? options3.stdin : void 0, scope);
|
|
@@ -14921,7 +14967,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
14921
14967
|
} catch (error) {
|
|
14922
14968
|
if (!(error instanceof ShellSyntaxError)) throw error;
|
|
14923
14969
|
const line = source.slice(0, error.offset).split("\n").length;
|
|
14924
|
-
await
|
|
14970
|
+
await writeDiagnostic(context.stderr, `${target}: line ${line}: syntax error: ${error.reason}
|
|
14925
14971
|
`);
|
|
14926
14972
|
return error.exitCode;
|
|
14927
14973
|
}
|
|
@@ -14932,7 +14978,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
14932
14978
|
const childIO = isolateIO({ ...io, ...context, execution: { ignoreErrexit: false }, diagnosticLine: 1, diagnosticOffset: 0, scriptName: target });
|
|
14933
14979
|
let status = 0;
|
|
14934
14980
|
for (const unit of units) {
|
|
14935
|
-
for (const warning of unit.warnings ?? []) await
|
|
14981
|
+
for (const warning of unit.warnings ?? []) await writeDiagnostic(context.stderr, `${target}: warning: ${warning}
|
|
14936
14982
|
`);
|
|
14937
14983
|
if (!unit.lists.length) continue;
|
|
14938
14984
|
const result = await this.runUnit(unit, child, childIO);
|
|
@@ -14950,7 +14996,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
14950
14996
|
do {
|
|
14951
14997
|
this.signal.throwIfAborted();
|
|
14952
14998
|
const unit = parseShellUnit(source, position, byteLocale(state.variables), this.budget.parsing, lineIndex);
|
|
14953
|
-
for (const warning of unit.script.warnings ?? []) await
|
|
14999
|
+
for (const warning of unit.script.warnings ?? []) await writeDiagnostic(io.stderr, `${io.scriptName ?? "shell"}: warning: ${warning}
|
|
14954
15000
|
`);
|
|
14955
15001
|
if (unit.script.lists.length) {
|
|
14956
15002
|
status = await this.script(unit.script, state, io);
|
|
@@ -14971,7 +15017,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
14971
15017
|
if (args[0] === "--") args.shift();
|
|
14972
15018
|
else if (args[0]?.startsWith("-") && args[0] !== "-") {
|
|
14973
15019
|
await this.diagnostic(io, `eval: -${args[0][1]}: invalid option`);
|
|
14974
|
-
await
|
|
15020
|
+
await writeDiagnostic(io.stderr, "eval: usage: eval [arg ...]\n");
|
|
14975
15021
|
if (special2) throw new Flow("exit", 2);
|
|
14976
15022
|
return 2;
|
|
14977
15023
|
}
|
|
@@ -15008,7 +15054,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15008
15054
|
const filename = args.shift();
|
|
15009
15055
|
if (filename === void 0) {
|
|
15010
15056
|
await this.diagnostic(io, `${context.command}: filename argument required`);
|
|
15011
|
-
await
|
|
15057
|
+
await writeDiagnostic(io.stderr, `${context.command}: usage: ${context.command} [-p path] filename [arguments]
|
|
15012
15058
|
`);
|
|
15013
15059
|
if (special2) throw new Flow("exit", 2);
|
|
15014
15060
|
return 2;
|
|
@@ -15220,7 +15266,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15220
15266
|
} else valid = false;
|
|
15221
15267
|
}
|
|
15222
15268
|
if (!valid) {
|
|
15223
|
-
await
|
|
15269
|
+
await writeDiagnostic(stderr, "set: unsupported shell option; supported forms are +/- e/u/B clusters, -- arguments and terminal o with braceexpand, pipefail, errexit or nounset\n");
|
|
15224
15270
|
return 1;
|
|
15225
15271
|
}
|
|
15226
15272
|
index++;
|
|
@@ -15299,11 +15345,11 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15299
15345
|
const offset = context.args[0] === "--" ? 1 : 0;
|
|
15300
15346
|
if (!offset && context.args[0]?.startsWith("-") && context.args[0] !== "-") {
|
|
15301
15347
|
await this.diagnostic(context, `getopts: -${context.args[0][1]}: invalid option`);
|
|
15302
|
-
await
|
|
15348
|
+
await writeDiagnostic(context.stderr, "getopts: usage: getopts optstring name [arg ...]\n");
|
|
15303
15349
|
return 2;
|
|
15304
15350
|
}
|
|
15305
15351
|
if (context.args.length - offset < 2) {
|
|
15306
|
-
await
|
|
15352
|
+
await writeDiagnostic(context.stderr, "getopts: usage: getopts optstring name [arg ...]\n");
|
|
15307
15353
|
return 2;
|
|
15308
15354
|
}
|
|
15309
15355
|
const optstring = context.args[offset];
|
|
@@ -15333,7 +15379,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15333
15379
|
state.getopts.cursor = result.state;
|
|
15334
15380
|
if (result.diagnostic) {
|
|
15335
15381
|
const explanation = result.diagnostic.kind === "unknown-option" ? "illegal option" : "option requires an argument";
|
|
15336
|
-
await
|
|
15382
|
+
await writeDiagnostic(context.stderr, `${state.arg0 ?? context.scriptName ?? "shell"}: ${explanation} -- ${result.diagnostic.option}
|
|
15337
15383
|
`);
|
|
15338
15384
|
}
|
|
15339
15385
|
this.signal.throwIfAborted();
|
|
@@ -15348,13 +15394,13 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15348
15394
|
const name2 = stackHooks?.name ?? "cd";
|
|
15349
15395
|
this.signal.throwIfAborted();
|
|
15350
15396
|
if (args.length > 1) {
|
|
15351
|
-
await
|
|
15397
|
+
await writeDiagnostic(context.stderr, `${name2}: too many arguments
|
|
15352
15398
|
`);
|
|
15353
15399
|
return 1;
|
|
15354
15400
|
}
|
|
15355
15401
|
const target = args[0] === "-" ? state.variables.OLDPWD : args[0] ?? state.variables.HOME;
|
|
15356
15402
|
if (target === void 0) {
|
|
15357
|
-
await
|
|
15403
|
+
await writeDiagnostic(context.stderr, `${name2}: ${args[0] === "-" ? "OLDPWD" : "HOME"} not set
|
|
15358
15404
|
`);
|
|
15359
15405
|
return 1;
|
|
15360
15406
|
}
|
|
@@ -15566,7 +15612,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15566
15612
|
else if (flag === "u") unset = true;
|
|
15567
15613
|
else {
|
|
15568
15614
|
await this.diagnostic(context, `shopt: ${option.startsWith("--") ? option : `-${flag}`}: unsupported option`);
|
|
15569
|
-
await
|
|
15615
|
+
await writeDiagnostic(context.stderr, "shopt: usage: shopt [-pqsu] [--] [dotglob ...]\n");
|
|
15570
15616
|
return 2;
|
|
15571
15617
|
}
|
|
15572
15618
|
}
|
|
@@ -15608,20 +15654,20 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15608
15654
|
const option = incoming.args[offset++];
|
|
15609
15655
|
const target = option.slice(2) || incoming.args[offset++];
|
|
15610
15656
|
if (target === void 0) {
|
|
15611
|
-
await
|
|
15657
|
+
await writeDiagnostic(context.stderr, "printf: -v: option requires an argument\n");
|
|
15612
15658
|
return 2;
|
|
15613
15659
|
}
|
|
15614
15660
|
const bracket = target.indexOf("[");
|
|
15615
15661
|
name2 = bracket < 0 ? target : target.slice(0, bracket);
|
|
15616
15662
|
if (!/^[a-zA-Z_][a-zA-Z_0-9]*$/u.test(name2) || bracket >= 0 && !target.endsWith("]")) {
|
|
15617
|
-
await
|
|
15663
|
+
await writeDiagnostic(context.stderr, `printf: '${target}': not a valid identifier
|
|
15618
15664
|
`);
|
|
15619
15665
|
return 2;
|
|
15620
15666
|
}
|
|
15621
15667
|
index = void 0;
|
|
15622
15668
|
if (bracket >= 0) {
|
|
15623
15669
|
if (target[bracket + 1] === "'" || target[bracket + 1] === '"') {
|
|
15624
|
-
await
|
|
15670
|
+
await writeDiagnostic(context.stderr, `printf: '${target}': unsupported indexed-array subscript
|
|
15625
15671
|
`);
|
|
15626
15672
|
return 2;
|
|
15627
15673
|
}
|
|
@@ -15630,12 +15676,12 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15630
15676
|
} catch (error) {
|
|
15631
15677
|
this.signal.throwIfAborted();
|
|
15632
15678
|
if (!(error instanceof ShellSyntaxError)) throw error;
|
|
15633
|
-
await
|
|
15679
|
+
await writeDiagnostic(context.stderr, `printf: '${target}': unsupported indexed-array subscript
|
|
15634
15680
|
`);
|
|
15635
15681
|
return 2;
|
|
15636
15682
|
}
|
|
15637
15683
|
if (numericIndex(index) === void 0) {
|
|
15638
|
-
await
|
|
15684
|
+
await writeDiagnostic(context.stderr, "printf: index outside 0..2147483647\n");
|
|
15639
15685
|
return 2;
|
|
15640
15686
|
}
|
|
15641
15687
|
}
|
|
@@ -15643,7 +15689,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15643
15689
|
const arguments_ = incoming.slice(offset);
|
|
15644
15690
|
const format = arguments_.args[0] === "--" ? arguments_.args[1] : arguments_.args[0];
|
|
15645
15691
|
if (format === void 0 || arguments_.args[0] !== "--" && format.startsWith("-")) {
|
|
15646
|
-
await
|
|
15692
|
+
await writeDiagnostic(context.stderr, "printf: usage: printf [-v var] format [arguments]\n");
|
|
15647
15693
|
return 2;
|
|
15648
15694
|
}
|
|
15649
15695
|
const allocation = this.budget.values.scope();
|
|
@@ -15668,14 +15714,14 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15668
15714
|
} catch (error) {
|
|
15669
15715
|
this.signal.throwIfAborted();
|
|
15670
15716
|
if (!(error instanceof UsageError)) throw error;
|
|
15671
|
-
await
|
|
15717
|
+
await writeDiagnostic(context.stderr, `printf: ${error.message}
|
|
15672
15718
|
`);
|
|
15673
15719
|
status = 1;
|
|
15674
15720
|
}
|
|
15675
15721
|
const value2 = concatShellValues(chunks, allocation);
|
|
15676
15722
|
this.signal.throwIfAborted();
|
|
15677
15723
|
if (state.readonlyVariables?.has(name2)) {
|
|
15678
|
-
await
|
|
15724
|
+
await writeDiagnostic(context.stderr, `printf: ${name2}: readonly variable
|
|
15679
15725
|
`);
|
|
15680
15726
|
return 1;
|
|
15681
15727
|
}
|
|
@@ -15696,7 +15742,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15696
15742
|
if (decode(shellValueBytes(previous2, allocation)) === void 0) text = void 0;
|
|
15697
15743
|
}
|
|
15698
15744
|
if (text === void 0) {
|
|
15699
|
-
await
|
|
15745
|
+
await writeDiagnostic(context.stderr, "printf: indexed variables do not support non-UTF-8 bytes\n");
|
|
15700
15746
|
return 1;
|
|
15701
15747
|
}
|
|
15702
15748
|
if (index) await this.arrayAssignment({ kind: "element", name: name2, index, append: false, value: { offset: 0, parts: [{ kind: "text", value: text, quoted: true }] } }, state, context);
|
|
@@ -15723,7 +15769,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15723
15769
|
if (command2 === "pushd" || command2 === "dirs" || command2 === "popd") return this.directoryStackBuiltin(context, state, diagnose);
|
|
15724
15770
|
if (command2 === "pwd") {
|
|
15725
15771
|
if (args.some((arg) => arg !== "-L" && arg !== "-P")) {
|
|
15726
|
-
await
|
|
15772
|
+
await writeDiagnostic(stderr, "pwd: invalid option\n");
|
|
15727
15773
|
return 2;
|
|
15728
15774
|
}
|
|
15729
15775
|
const path = args.at(-1) === "-P" ? await this.fs.realpath(state.cwd, { signal: this.signal }) : state.cwd;
|
|
@@ -15762,7 +15808,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15762
15808
|
continue;
|
|
15763
15809
|
}
|
|
15764
15810
|
if (/^[+-]/u.test(option)) {
|
|
15765
|
-
await
|
|
15811
|
+
await writeDiagnostic(stderr, "set: unsupported shell option; supported forms are +/- e/u clusters, -- arguments and terminal o with pipefail, errexit or nounset\n");
|
|
15766
15812
|
if (state.profile === "sh" && suppressSpecial) return 2;
|
|
15767
15813
|
throw new Flow("exit", 2);
|
|
15768
15814
|
}
|
|
@@ -15774,7 +15820,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15774
15820
|
state.positionalSetVersion = (state.positionalSetVersion ?? 0) + 1;
|
|
15775
15821
|
}
|
|
15776
15822
|
if (args.length) return 0;
|
|
15777
|
-
await
|
|
15823
|
+
await writeDiagnostic(stderr, "set: supported forms are +/- e/u clusters, -- arguments and terminal o with pipefail, errexit or nounset\n");
|
|
15778
15824
|
return 2;
|
|
15779
15825
|
}
|
|
15780
15826
|
if (command2 === "shift") {
|
|
@@ -15789,14 +15835,14 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15789
15835
|
if (command2 === "local") {
|
|
15790
15836
|
const options3 = localDeclarationOptions(declarationArgs, this.signal);
|
|
15791
15837
|
if (options3.error !== void 0) {
|
|
15792
|
-
await
|
|
15838
|
+
await writeDiagnostic(stderr, `local: ${options3.error}: unsupported option
|
|
15793
15839
|
`);
|
|
15794
15840
|
return 2;
|
|
15795
15841
|
}
|
|
15796
15842
|
indexedLocal = options3.indexed;
|
|
15797
15843
|
declarationArgs.splice(0, options3.offset);
|
|
15798
15844
|
if (indexedLocal && declarationArgs.length === 0) {
|
|
15799
|
-
await
|
|
15845
|
+
await writeDiagnostic(stderr, "local: -a requires a variable name\n");
|
|
15800
15846
|
return 2;
|
|
15801
15847
|
}
|
|
15802
15848
|
}
|
|
@@ -15805,7 +15851,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15805
15851
|
const option = declarationArgs.shift();
|
|
15806
15852
|
if (option === "--") break;
|
|
15807
15853
|
if (option !== "-p") {
|
|
15808
|
-
await
|
|
15854
|
+
await writeDiagnostic(stderr, `readonly: ${option}: unsupported option
|
|
15809
15855
|
`);
|
|
15810
15856
|
return 2;
|
|
15811
15857
|
}
|
|
@@ -15813,7 +15859,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
15813
15859
|
}
|
|
15814
15860
|
const locals = state.locals.at(-1);
|
|
15815
15861
|
if (command2 === "local" && !locals) {
|
|
15816
|
-
await
|
|
15862
|
+
await writeDiagnostic(stderr, "local: not in a function\n");
|
|
15817
15863
|
return 1;
|
|
15818
15864
|
}
|
|
15819
15865
|
let status = 0;
|
|
@@ -16062,7 +16108,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
16062
16108
|
continue;
|
|
16063
16109
|
}
|
|
16064
16110
|
if (!/^[a-zA-Z_][a-zA-Z_0-9]*$/u.test(name2)) {
|
|
16065
|
-
await
|
|
16111
|
+
await writeDiagnostic(stderr, `unset: ${name2}: not a valid identifier
|
|
16066
16112
|
`);
|
|
16067
16113
|
status = 1;
|
|
16068
16114
|
continue;
|
|
@@ -16104,7 +16150,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
16104
16150
|
else if (flag === "d") delimiter = new TextEncoder().encode(value2)[0] ?? 0;
|
|
16105
16151
|
else if (exact && (!/^[ \t]*[+-]?\d+[ \t]*$/u.test(value2) || !Number.isSafeInteger(Number(value2)) || Number(value2) < 0)) {
|
|
16106
16152
|
const diagnosticIO = context;
|
|
16107
|
-
await
|
|
16153
|
+
await writeDiagnostic(stderr, `${diagnosticIO.scriptName ?? "shell"}: line ${diagnosticIO.diagnosticLine ?? 1}: read: ${value2}: invalid ${/^[+-]?0[xX]/u.test(value2) ? "hex " : ""}number
|
|
16108
16154
|
`);
|
|
16109
16155
|
return 1;
|
|
16110
16156
|
} else if (!exact && (!/^\d+$/u.test(value2) || !Number.isSafeInteger(Number(value2)))) invalid = true;
|
|
@@ -16117,12 +16163,12 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
16117
16163
|
const invalidName = names.find((name2) => !/^[a-zA-Z_][a-zA-Z_0-9]*$/u.test(name2));
|
|
16118
16164
|
if (exact && !invalid && invalidName !== void 0) {
|
|
16119
16165
|
const diagnosticIO = context;
|
|
16120
|
-
await
|
|
16166
|
+
await writeDiagnostic(stderr, `${diagnosticIO.scriptName ?? "shell"}: line ${diagnosticIO.diagnosticLine ?? 1}: read: \`${invalidName}': not a valid identifier
|
|
16121
16167
|
`);
|
|
16122
16168
|
return 1;
|
|
16123
16169
|
}
|
|
16124
16170
|
if (invalid || names.some((name2) => !/^[a-zA-Z_][a-zA-Z_0-9]*$/u.test(name2))) {
|
|
16125
|
-
await
|
|
16171
|
+
await writeDiagnostic(stderr, "read: invalid variable name or unsupported option\n");
|
|
16126
16172
|
return 2;
|
|
16127
16173
|
}
|
|
16128
16174
|
const input3 = context.stdin instanceof ShellInput ? context.stdin : new ShellInput(context.stdin, this.budget, this.signal);
|
|
@@ -16179,16 +16225,16 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
16179
16225
|
}
|
|
16180
16226
|
if (command2 === "exit" || command2 === "return") {
|
|
16181
16227
|
if (command2 === "return" && state.functionDepth === 0 && !state.sourceDepth) {
|
|
16182
|
-
await
|
|
16228
|
+
await writeDiagnostic(stderr, "return: not in a function\n");
|
|
16183
16229
|
return 1;
|
|
16184
16230
|
}
|
|
16185
16231
|
if (args.length > 1) {
|
|
16186
|
-
await
|
|
16232
|
+
await writeDiagnostic(stderr, `${command2}: too many arguments
|
|
16187
16233
|
`);
|
|
16188
16234
|
return 1;
|
|
16189
16235
|
}
|
|
16190
16236
|
if (args[0] !== void 0 && !/^[+-]?\d+$/u.test(args[0])) {
|
|
16191
|
-
await
|
|
16237
|
+
await writeDiagnostic(stderr, `${command2}: ${args[0]}: numeric argument required
|
|
16192
16238
|
`);
|
|
16193
16239
|
throw completedExit(2, command2);
|
|
16194
16240
|
}
|
|
@@ -16198,12 +16244,12 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
16198
16244
|
if (command2 === "break" || command2 === "continue") {
|
|
16199
16245
|
const levels = args[0] === void 0 ? 1 : Number(args[0]);
|
|
16200
16246
|
if (args.length > 1 || !Number.isSafeInteger(levels) || levels < 1) {
|
|
16201
|
-
await
|
|
16247
|
+
await writeDiagnostic(stderr, `${command2}: invalid loop count
|
|
16202
16248
|
`);
|
|
16203
16249
|
return 1;
|
|
16204
16250
|
}
|
|
16205
16251
|
if (!state.loopDepth) {
|
|
16206
|
-
await
|
|
16252
|
+
await writeDiagnostic(stderr, `${command2}: only meaningful in a loop
|
|
16207
16253
|
`);
|
|
16208
16254
|
return 0;
|
|
16209
16255
|
}
|
|
@@ -16252,7 +16298,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
16252
16298
|
this.signal.throwIfAborted();
|
|
16253
16299
|
if (part.kind === "failed-substitution") {
|
|
16254
16300
|
if (state.depth >= this.budget.limits.maxSubstitutionDepth) this.budget.fail("maxSubstitutionDepth");
|
|
16255
|
-
await
|
|
16301
|
+
await writeDiagnostic(io.stderr, part.diagnostic);
|
|
16256
16302
|
state.status = state.substitutionStatus = 2;
|
|
16257
16303
|
return "";
|
|
16258
16304
|
}
|
|
@@ -16305,7 +16351,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
16305
16351
|
}
|
|
16306
16352
|
state.status = state.substitutionStatus;
|
|
16307
16353
|
const bytes2 = capture.bytes();
|
|
16308
|
-
if (bytes2.includes(0)) await
|
|
16354
|
+
if (bytes2.includes(0)) await writeDiagnostic(io.stderr, `${io.scriptName ?? "shell"}: line ${warningLine}: warning: command substitution: ignored null byte in input
|
|
16309
16355
|
`);
|
|
16310
16356
|
let length = 0;
|
|
16311
16357
|
for (const byte of bytes2) if (byte !== 0) bytes2[length++] = byte;
|
|
@@ -16701,9 +16747,9 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
16701
16747
|
separatorScope.close();
|
|
16702
16748
|
}
|
|
16703
16749
|
};
|
|
16704
|
-
const
|
|
16705
|
-
for (let index = 0; index <
|
|
16706
|
-
const { part, splitText, io: partIO } =
|
|
16750
|
+
const parts2 = word.parts.map((part) => ({ part, splitText: false, io }));
|
|
16751
|
+
for (let index = 0; index < parts2.length; index++) {
|
|
16752
|
+
const { part, splitText, io: partIO } = parts2[index];
|
|
16707
16753
|
const quotedPresence = part.quoted && !(arrayOwned && isQuoteMarker(part));
|
|
16708
16754
|
if (part.kind === "variable" && ["-", "+", ":-", ":+"].includes(part.operator ?? "") && /^[a-zA-Z_][a-zA-Z_0-9]*$/u.test(part.name)) {
|
|
16709
16755
|
const value2 = this.variable(state, part.name);
|
|
@@ -16713,7 +16759,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
16713
16759
|
scratch?.reserve(part.alternate.parts.length * 32, 0);
|
|
16714
16760
|
const alternate = part.alternate.parts.map((entry) => ({ part: copyArraySelector(entry, { ...entry, quoted: entry.quoted || part.quoted }), splitText: true, io: operandIO }));
|
|
16715
16761
|
if (!alternate.length && part.quoted) append("", false, true);
|
|
16716
|
-
|
|
16762
|
+
parts2.splice(index + 1, 0, ...alternate);
|
|
16717
16763
|
continue;
|
|
16718
16764
|
}
|
|
16719
16765
|
}
|
|
@@ -17546,7 +17592,7 @@ var Shell = class {
|
|
|
17546
17592
|
);
|
|
17547
17593
|
exitCode = 0;
|
|
17548
17594
|
while (true) {
|
|
17549
|
-
for (const warning of unit.script.warnings ?? []) await
|
|
17595
|
+
for (const warning of unit.script.warnings ?? []) await writeDiagnostic(io.stderr, `shell: warning: ${warning}
|
|
17550
17596
|
`);
|
|
17551
17597
|
if (unit.script.lists.length) {
|
|
17552
17598
|
const result = await interruptible(runtime.runUnit(unit.script, state, io), budget.signal);
|
|
@@ -17561,18 +17607,18 @@ var Shell = class {
|
|
|
17561
17607
|
if (!(error instanceof ShellSyntaxError)) throw error;
|
|
17562
17608
|
const line = source.slice(0, error.offset).split("\n").length;
|
|
17563
17609
|
if (error.unclosedQuote) {
|
|
17564
|
-
await
|
|
17610
|
+
await writeDiagnostic(io.stderr, `shell: -c: line ${error.unclosedQuote.line}: unexpected EOF while looking for matching \`${error.unclosedQuote.quote}'
|
|
17565
17611
|
`);
|
|
17566
17612
|
} else if (error.exitCode === 127) {
|
|
17567
17613
|
const token = /^[;&|()<>]|^[^\s;&|()<>]+/u.exec(source.slice(error.offset))?.[0] ?? "newline";
|
|
17568
|
-
await
|
|
17614
|
+
await writeDiagnostic(io.stderr, `shell: -c: line ${line}: syntax error near unexpected token \`${token}'
|
|
17569
17615
|
shell: -c: line ${line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
17570
17616
|
`);
|
|
17571
17617
|
} else if (error.offset >= source.length && !/Unterminated|nesting|Unsupported/u.test(error.reason)) {
|
|
17572
17618
|
const context = error.incompleteCommand ? ` from \`${error.incompleteCommand.name}' command on line ${error.incompleteCommand.line}` : "";
|
|
17573
|
-
await
|
|
17619
|
+
await writeDiagnostic(io.stderr, `shell: -c: line ${source.split("\n").length + Number(!source.endsWith("\n"))}: syntax error: unexpected end of file${context}
|
|
17574
17620
|
`);
|
|
17575
|
-
} else await
|
|
17621
|
+
} else await writeDiagnostic(io.stderr, `shell: ${error.message}
|
|
17576
17622
|
`);
|
|
17577
17623
|
exitCode = error.exitCode;
|
|
17578
17624
|
}
|
|
@@ -17794,9 +17840,9 @@ function privateHostname(input3) {
|
|
|
17794
17840
|
}
|
|
17795
17841
|
return (hextets[0] & 65024) === 64512 || (hextets[0] & 65472) === 65152;
|
|
17796
17842
|
}
|
|
17797
|
-
const
|
|
17798
|
-
if (
|
|
17799
|
-
const octets =
|
|
17843
|
+
const parts2 = hostname.split(".");
|
|
17844
|
+
if (parts2.length !== 4 || parts2.some((part) => !part || Array.from(part).some((character) => character < "0" || character > "9"))) return false;
|
|
17845
|
+
const octets = parts2.map(Number);
|
|
17800
17846
|
if (octets.some((value2) => value2 < 0 || value2 > 255)) return false;
|
|
17801
17847
|
const [first, second] = octets;
|
|
17802
17848
|
return privateIPv4(first, second);
|
|
@@ -18507,8 +18553,8 @@ function command(name2, run) {
|
|
|
18507
18553
|
return { exitCode: await run(context) };
|
|
18508
18554
|
} catch (error) {
|
|
18509
18555
|
context.signal.throwIfAborted();
|
|
18510
|
-
await
|
|
18511
|
-
|
|
18556
|
+
await writeDiagnostic(context.stderr, `${name2}: ${error instanceof Error ? error.message : String(error)}
|
|
18557
|
+
`, context.signal);
|
|
18512
18558
|
return { exitCode: error instanceof ProgramError ? 2 : 1 };
|
|
18513
18559
|
}
|
|
18514
18560
|
}
|
|
@@ -20344,8 +20390,8 @@ var Limits = class {
|
|
|
20344
20390
|
}
|
|
20345
20391
|
};
|
|
20346
20392
|
async function diagnostic2(context, error) {
|
|
20347
|
-
await
|
|
20348
|
-
|
|
20393
|
+
await writeDiagnostic(context.stderr, `rg: ${error instanceof Error ? error.message : String(error)}
|
|
20394
|
+
`, context.signal);
|
|
20349
20395
|
}
|
|
20350
20396
|
async function* lines2(source, limits, state, binary, nullData) {
|
|
20351
20397
|
let pending = import_buffer.Buffer.alloc(0);
|