@poe-platform/safe-bash 0.1.522 → 0.1.524
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/core.browser.js +381 -58
- package/dist/safe-bash/core.browser.js.map +4 -4
- package/dist/safe-bash/shell/arrays/bindings.d.ts +1 -0
- package/dist/safe-bash/shell/arrays/bindings.d.ts.map +1 -1
- package/dist/safe-bash/shell/arrays/bindings.js +3 -0
- package/dist/safe-bash/shell/arrays/bindings.js.map +1 -1
- package/dist/safe-bash/shell/arrays/syntax.d.ts +1 -0
- package/dist/safe-bash/shell/arrays/syntax.d.ts.map +1 -1
- package/dist/safe-bash/shell/arrays/syntax.js +4 -0
- package/dist/safe-bash/shell/arrays/syntax.js.map +1 -1
- package/dist/safe-bash/shell/parameter-transforms.d.ts +12 -0
- package/dist/safe-bash/shell/parameter-transforms.d.ts.map +1 -0
- package/dist/safe-bash/shell/parameter-transforms.js +166 -0
- package/dist/safe-bash/shell/parameter-transforms.js.map +1 -0
- package/dist/safe-bash/shell/parser.d.ts +2 -0
- package/dist/safe-bash/shell/parser.d.ts.map +1 -1
- package/dist/safe-bash/shell/parser.js +41 -5
- package/dist/safe-bash/shell/parser.js.map +1 -1
- package/dist/safe-bash/shell/runtime.d.ts +4 -1
- package/dist/safe-bash/shell/runtime.d.ts.map +1 -1
- package/dist/safe-bash/shell/runtime.js +236 -53
- package/dist/safe-bash/shell/runtime.js.map +1 -1
- package/package.json +2 -2
|
@@ -33508,8 +33508,8 @@ async function entities(text3, budget) {
|
|
|
33508
33508
|
const name2 = match[1];
|
|
33509
33509
|
if (name2[0] !== "#") result2.append(Object.hasOwn(named, name2) ? named[name2] : match[0]);
|
|
33510
33510
|
else {
|
|
33511
|
-
const
|
|
33512
|
-
const value2 = Number.parseInt(name2.slice(
|
|
33511
|
+
const hexadecimal2 = name2[1]?.toLowerCase() === "x";
|
|
33512
|
+
const value2 = Number.parseInt(name2.slice(hexadecimal2 ? 2 : 1), hexadecimal2 ? 16 : 10);
|
|
33513
33513
|
result2.append(value2 === 0 || value2 > 1114111 || value2 >= 55296 && value2 <= 57343 ? "\uFFFD" : String.fromCodePoint(value2));
|
|
33514
33514
|
}
|
|
33515
33515
|
offset += match[0].length;
|
|
@@ -37479,6 +37479,7 @@ init_platform();
|
|
|
37479
37479
|
var assignments = /* @__PURE__ */ new WeakMap();
|
|
37480
37480
|
var selectors = /* @__PURE__ */ new WeakMap();
|
|
37481
37481
|
var quoteMarkers = /* @__PURE__ */ new WeakSet();
|
|
37482
|
+
var prefixNameQuoteGroups = /* @__PURE__ */ new WeakMap();
|
|
37482
37483
|
function setQuoteMarker(part, synthetic) {
|
|
37483
37484
|
if (synthetic) quoteMarkers.add(part);
|
|
37484
37485
|
else quoteMarkers.delete(part);
|
|
@@ -37514,6 +37515,8 @@ function copyArraySelector(original, copy2) {
|
|
|
37514
37515
|
const selector = selectors.get(original);
|
|
37515
37516
|
if (selector) selectors.set(copy2, selector);
|
|
37516
37517
|
setQuoteMarker(copy2, isQuoteMarker(original));
|
|
37518
|
+
const group = prefixNameQuoteGroups.get(original);
|
|
37519
|
+
if (group) prefixNameQuoteGroups.set(copy2, group);
|
|
37517
37520
|
return copy2;
|
|
37518
37521
|
}
|
|
37519
37522
|
function setArrayAssignment(word, assignment) {
|
|
@@ -38113,14 +38116,19 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
38113
38116
|
this.position++;
|
|
38114
38117
|
text3("", true, true, this.position - 1, this.position);
|
|
38115
38118
|
const quoteParts = parts.length;
|
|
38119
|
+
let nameListing = false;
|
|
38116
38120
|
while (this.position < this.source.length && this.source[this.position] !== '"') {
|
|
38117
38121
|
const inner = this.source[this.position];
|
|
38118
38122
|
const opaque2 = this.braceReplay?.get(this.position);
|
|
38119
38123
|
if (opaque2 !== void 0) {
|
|
38120
38124
|
text3(opaque2, true);
|
|
38121
38125
|
this.position++;
|
|
38122
|
-
} else if (!literal && (inner === "$" || inner === "`"))
|
|
38123
|
-
|
|
38126
|
+
} else if (!literal && (inner === "$" || inner === "`")) {
|
|
38127
|
+
this.expansion(parts, true);
|
|
38128
|
+
const part = parts.at(-1);
|
|
38129
|
+
const selector = getArraySelector(part);
|
|
38130
|
+
nameListing ||= part.kind === "variable" && (part.prefixNames === "@" || !!part.transform && (part.name === "@" || selector?.kind === "members" && selector.separator === "@"));
|
|
38131
|
+
} else if (inner === "\\" && /[$`"\\\n]/u.test(this.source[this.position + 1] ?? "")) {
|
|
38124
38132
|
const escaped3 = this.source[this.position + 1];
|
|
38125
38133
|
if (escaped3 !== "\n") text3(escaped3, true, false, this.position, this.position + 2);
|
|
38126
38134
|
else this.printedNewlineReduction++;
|
|
@@ -38132,6 +38140,15 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
38132
38140
|
}
|
|
38133
38141
|
if (this.source[this.position] !== '"' && !this.braceReplay) this.error("Unterminated double quote", { quote: '"', line: quoteLine });
|
|
38134
38142
|
if (parts.length === quoteParts) setQuoteMarker(parts.at(-1), false);
|
|
38143
|
+
if (nameListing) {
|
|
38144
|
+
this.budget.admit();
|
|
38145
|
+
const group = {};
|
|
38146
|
+
for (let index = quoteParts - 1; index < parts.length; index++) {
|
|
38147
|
+
this.budget.admit();
|
|
38148
|
+
const part = parts[index];
|
|
38149
|
+
if (index !== quoteParts - 1 || isQuoteMarker(part) || part.kind !== "text" || part.value !== "") prefixNameQuoteGroups.set(part, group);
|
|
38150
|
+
}
|
|
38151
|
+
}
|
|
38135
38152
|
const spelling2 = expansionSpellings.get(parts.at(-1));
|
|
38136
38153
|
if (spelling2) spelling2.end = Math.min(this.position + 1, this.source.length);
|
|
38137
38154
|
if (this.position < this.source.length) this.position++;
|
|
@@ -38291,11 +38308,20 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
38291
38308
|
} else if (this.source[this.position] === "{") {
|
|
38292
38309
|
this.position++;
|
|
38293
38310
|
const parameterStart = this.position - 2;
|
|
38294
|
-
const
|
|
38311
|
+
const listing = this.source[this.position] === "!";
|
|
38312
|
+
if (listing) this.position++;
|
|
38313
|
+
const length = !listing && this.source[this.position] === "#" && /[a-zA-Z_]/u.test(this.source[this.position + 1] ?? "");
|
|
38295
38314
|
if (length) this.position++;
|
|
38296
38315
|
const name2 = /^(?:[a-zA-Z_][a-zA-Z_0-9]*|[0-9]+|[?@*#-])/u.exec(this.source.slice(this.position))?.[0];
|
|
38297
38316
|
if (!name2) this.error("Unsupported parameter expansion");
|
|
38298
38317
|
this.position += name2.length;
|
|
38318
|
+
let prefixNames;
|
|
38319
|
+
if (listing) {
|
|
38320
|
+
const separator = this.source[this.position];
|
|
38321
|
+
if (!/^[a-zA-Z_][a-zA-Z_0-9]*$/u.test(name2) || separator !== "*" && separator !== "@" || this.source[this.position + 1] !== "}") this.error("Unsupported indirect parameter expansion");
|
|
38322
|
+
prefixNames = separator;
|
|
38323
|
+
this.position++;
|
|
38324
|
+
}
|
|
38299
38325
|
let selector;
|
|
38300
38326
|
if (this.source[this.position] === "[") {
|
|
38301
38327
|
if (!/^[a-zA-Z_][a-zA-Z_0-9]*$/u.test(name2)) this.error("Unsupported indexed-array parameter");
|
|
@@ -38304,7 +38330,14 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
38304
38330
|
if (end < 0) this.error("Unterminated indexed-array subscript");
|
|
38305
38331
|
selector = arraySelector(this.source.slice(start, end), start, this.budget);
|
|
38306
38332
|
this.position = end + 1;
|
|
38307
|
-
if (this.source[this.position] !== "}") this.error("Unsupported indexed-array operator");
|
|
38333
|
+
if (this.source[this.position] !== "}" && this.source[this.position] !== "@") this.error("Unsupported indexed-array operator");
|
|
38334
|
+
}
|
|
38335
|
+
let transform2;
|
|
38336
|
+
if (this.source[this.position] === "@") {
|
|
38337
|
+
const operation2 = this.source[this.position + 1];
|
|
38338
|
+
if (length || prefixNames || operation2 !== "Q" && operation2 !== "E" || this.source[this.position + 2] !== "}") this.error("Unsupported parameter transform");
|
|
38339
|
+
transform2 = operation2;
|
|
38340
|
+
this.position += 2;
|
|
38308
38341
|
}
|
|
38309
38342
|
const operator = /^(?::[-=+?]|##|%%|\/\/|\/[#%]?|[-=+?#%])/u.exec(this.source.slice(this.position))?.[0];
|
|
38310
38343
|
let alternate;
|
|
@@ -38348,7 +38381,7 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
38348
38381
|
parts.push({ kind: "failed-parameter", source: this.source.slice(parameterStart, this.position), line, quoted: quoted2 });
|
|
38349
38382
|
} else {
|
|
38350
38383
|
this.position++;
|
|
38351
|
-
const part = { kind: "variable", name: name2, quoted: quoted2, line, ...length ? { length } : {}, ...operator ? { operator, alternate } : {}, ...replacement ? { replacement } : {}, ...substring ? { substring } : {} };
|
|
38384
|
+
const part = { kind: "variable", name: name2, quoted: quoted2, line, ...prefixNames ? { prefixNames } : {}, ...transform2 ? { transform: transform2 } : {}, ...length ? { length } : {}, ...operator ? { operator, alternate } : {}, ...replacement ? { replacement } : {}, ...substring ? { substring } : {} };
|
|
38352
38385
|
if (selector) setArraySelector(part, selector);
|
|
38353
38386
|
parts.push(part);
|
|
38354
38387
|
}
|
|
@@ -40760,6 +40793,7 @@ var IndexedBinding = class _IndexedBinding {
|
|
|
40760
40793
|
generation = 0;
|
|
40761
40794
|
version = 0;
|
|
40762
40795
|
references = 1;
|
|
40796
|
+
assigned = false;
|
|
40763
40797
|
static create(parent) {
|
|
40764
40798
|
const owner = ArrayOwner.create(parent.ledger, parent);
|
|
40765
40799
|
try {
|
|
@@ -40791,11 +40825,13 @@ var IndexedBinding = class _IndexedBinding {
|
|
|
40791
40825
|
text3.release();
|
|
40792
40826
|
};
|
|
40793
40827
|
this.values.set(index, element);
|
|
40828
|
+
this.assigned = true;
|
|
40794
40829
|
if (index > this.maximum) this.maximum = index;
|
|
40795
40830
|
previous?.slot.release();
|
|
40796
40831
|
}
|
|
40797
40832
|
async copy(signal) {
|
|
40798
40833
|
const copy2 = _IndexedBinding.create(this.owner.parent);
|
|
40834
|
+
copy2.assigned = this.assigned;
|
|
40799
40835
|
this.retain();
|
|
40800
40836
|
try {
|
|
40801
40837
|
for (const [index, element] of this.values) {
|
|
@@ -41581,6 +41617,138 @@ function* pathTargets(name2, path, limits, signal, fail4) {
|
|
|
41581
41617
|
}
|
|
41582
41618
|
}
|
|
41583
41619
|
|
|
41620
|
+
// packages/safe-bash/src/shell/parameter-transforms.ts
|
|
41621
|
+
init_platform();
|
|
41622
|
+
function hexadecimal(byte) {
|
|
41623
|
+
return byte >= 48 && byte <= 57 ? byte - 48 : byte >= 65 && byte <= 70 ? byte - 55 : byte >= 97 && byte <= 102 ? byte - 87 : -1;
|
|
41624
|
+
}
|
|
41625
|
+
function utf8Unit(bytes3, offset) {
|
|
41626
|
+
const first = bytes3[offset];
|
|
41627
|
+
if (first < 128) return { point: first, size: 1 };
|
|
41628
|
+
const size = first >= 194 && first <= 223 ? 2 : first >= 224 && first <= 239 ? 3 : first >= 240 && first <= 244 ? 4 : 0;
|
|
41629
|
+
if (!size || offset + size > bytes3.length) return { point: -1, size: 1 };
|
|
41630
|
+
let point = first & 127 >> size;
|
|
41631
|
+
for (let index = 1; index < size; index++) {
|
|
41632
|
+
const byte = bytes3[offset + index];
|
|
41633
|
+
if (byte < 128 || byte > 191) return { point: -1, size: 1 };
|
|
41634
|
+
point = point * 64 + (byte & 63);
|
|
41635
|
+
}
|
|
41636
|
+
if (point < (size === 2 ? 128 : size === 3 ? 2048 : 65536) || point > 1114111 || point >= 55296 && point <= 57343) return { point: -1, size: 1 };
|
|
41637
|
+
return { point, size };
|
|
41638
|
+
}
|
|
41639
|
+
var controlEscapes = { 7: 97, 8: 98, 9: 116, 10: 110, 11: 118, 12: 102, 13: 114, 27: 69 };
|
|
41640
|
+
var decodedEscapes = { 97: 7, 98: 8, 116: 9, 110: 10, 118: 11, 102: 12, 114: 13, 101: 27, 69: 27, 92: 92, 39: 39, 34: 34, 63: 63 };
|
|
41641
|
+
async function transformParameter(value2, operator, options3) {
|
|
41642
|
+
const { work, allocation, maximumBytes } = options3;
|
|
41643
|
+
work.signal.throwIfAborted();
|
|
41644
|
+
if (typeof value2 === "string") {
|
|
41645
|
+
if (value2.length > maximumBytes) work.exhausted();
|
|
41646
|
+
if ((await scanString(value2, work)).bytes > maximumBytes) work.exhausted();
|
|
41647
|
+
} else if (shellValueByteLength(value2) > maximumBytes) work.exhausted();
|
|
41648
|
+
const input3 = shellValueBytes(value2, allocation);
|
|
41649
|
+
let ansi = false;
|
|
41650
|
+
if (operator === "Q") {
|
|
41651
|
+
for (let offset = 0; offset < input3.length; ) {
|
|
41652
|
+
const pending = stringCheckpoint(work);
|
|
41653
|
+
if (pending) await pending;
|
|
41654
|
+
const unit2 = options3.byteLocale ? { point: input3[offset], size: 1 } : utf8Unit(input3, offset);
|
|
41655
|
+
const printable = unit2.point >= 32 && unit2.point < 127 || !options3.byteLocale && unit2.point >= 128 && !/[\p{Cc}\p{Cf}\p{Cn}]/u.test(String.fromCodePoint(unit2.point));
|
|
41656
|
+
if (!printable) ansi = true;
|
|
41657
|
+
offset += unit2.size;
|
|
41658
|
+
}
|
|
41659
|
+
}
|
|
41660
|
+
let output2 = void 0;
|
|
41661
|
+
let size = 0;
|
|
41662
|
+
const emit2 = (byte) => {
|
|
41663
|
+
if (size >= maximumBytes) work.exhausted();
|
|
41664
|
+
if (output2) output2[size] = byte;
|
|
41665
|
+
size++;
|
|
41666
|
+
};
|
|
41667
|
+
const ascii2 = (text3) => {
|
|
41668
|
+
for (let index = 0; index < text3.length; index++) emit2(text3.charCodeAt(index));
|
|
41669
|
+
};
|
|
41670
|
+
const scan = async () => {
|
|
41671
|
+
size = 0;
|
|
41672
|
+
if (operator === "Q") {
|
|
41673
|
+
ascii2(ansi ? "$'" : "'");
|
|
41674
|
+
for (let offset = 0; offset < input3.length; ) {
|
|
41675
|
+
const pending = stringCheckpoint(work);
|
|
41676
|
+
if (pending) await pending;
|
|
41677
|
+
const unit2 = options3.byteLocale ? { point: input3[offset], size: 1 } : utf8Unit(input3, offset);
|
|
41678
|
+
const printable = unit2.point >= 32 && unit2.point < 127 || !options3.byteLocale && unit2.point >= 128 && !/[\p{Cc}\p{Cf}\p{Cn}]/u.test(String.fromCodePoint(unit2.point));
|
|
41679
|
+
if (ansi && !printable) {
|
|
41680
|
+
if (unit2.size === 1 && controlEscapes[input3[offset]] !== void 0) {
|
|
41681
|
+
emit2(92);
|
|
41682
|
+
emit2(controlEscapes[input3[offset]]);
|
|
41683
|
+
} else for (let index = 0; index < unit2.size; index++) ascii2("\\" + input3[offset + index].toString(8).padStart(3, "0"));
|
|
41684
|
+
} else if (unit2.point === 39) ascii2(ansi ? "\\'" : "'\\''");
|
|
41685
|
+
else if (ansi && unit2.point === 92) ascii2("\\\\");
|
|
41686
|
+
else for (let index = 0; index < unit2.size; index++) emit2(input3[offset + index]);
|
|
41687
|
+
offset += unit2.size;
|
|
41688
|
+
}
|
|
41689
|
+
emit2(39);
|
|
41690
|
+
return;
|
|
41691
|
+
}
|
|
41692
|
+
for (let offset = 0; offset < input3.length; ) {
|
|
41693
|
+
const pending = stringCheckpoint(work);
|
|
41694
|
+
if (pending) await pending;
|
|
41695
|
+
let byte = input3[offset++];
|
|
41696
|
+
if (byte === 92 && offset < input3.length) {
|
|
41697
|
+
const escape = input3[offset++];
|
|
41698
|
+
if (decodedEscapes[escape] !== void 0) byte = decodedEscapes[escape];
|
|
41699
|
+
else if (escape >= 48 && escape <= 55) {
|
|
41700
|
+
byte = escape - 48;
|
|
41701
|
+
for (let count2 = 1; count2 < 3 && offset < input3.length && input3[offset] >= 48 && input3[offset] <= 55; count2++) byte = byte * 8 + input3[offset++] - 48;
|
|
41702
|
+
byte &= 255;
|
|
41703
|
+
} else if (escape === 120 || escape === 117 || escape === 85) {
|
|
41704
|
+
const maximum = escape === 120 ? 2 : escape === 117 ? 4 : 8;
|
|
41705
|
+
let point = 0;
|
|
41706
|
+
let count2 = 0;
|
|
41707
|
+
while (count2 < maximum && offset < input3.length && hexadecimal(input3[offset]) >= 0) {
|
|
41708
|
+
point = point * 16 + hexadecimal(input3[offset++]);
|
|
41709
|
+
count2++;
|
|
41710
|
+
}
|
|
41711
|
+
if (!count2) {
|
|
41712
|
+
emit2(92);
|
|
41713
|
+
emit2(escape);
|
|
41714
|
+
continue;
|
|
41715
|
+
}
|
|
41716
|
+
if (escape === 120) byte = point;
|
|
41717
|
+
else {
|
|
41718
|
+
if (!point || point >= 2147483648) return;
|
|
41719
|
+
if (options3.byteLocale && point >= 55296 && point <= 57343) ascii2(`\\u${point.toString(16).toUpperCase().padStart(4, "0")}`);
|
|
41720
|
+
else {
|
|
41721
|
+
const width = point < 128 ? 1 : point < 2048 ? 2 : point < 65536 ? 3 : point < 2097152 ? 4 : point < 67108864 ? 5 : 6;
|
|
41722
|
+
if (width === 1) emit2(point);
|
|
41723
|
+
else {
|
|
41724
|
+
const divisor = 64 ** (width - 1);
|
|
41725
|
+
emit2(256 - 2 ** (8 - width) + Math.floor(point / divisor));
|
|
41726
|
+
for (let shift = width - 2; shift >= 0; shift--) emit2(128 + Math.floor(point / 64 ** shift) % 64);
|
|
41727
|
+
}
|
|
41728
|
+
}
|
|
41729
|
+
continue;
|
|
41730
|
+
}
|
|
41731
|
+
} else if (escape === 99 && offset < input3.length) {
|
|
41732
|
+
const control = input3[offset++];
|
|
41733
|
+
if (control === 92 && input3[offset] === 92) offset++;
|
|
41734
|
+
byte = control === 63 ? 127 : control & 31;
|
|
41735
|
+
} else {
|
|
41736
|
+
emit2(92);
|
|
41737
|
+
byte = escape;
|
|
41738
|
+
}
|
|
41739
|
+
}
|
|
41740
|
+
if (!byte) return;
|
|
41741
|
+
emit2(byte);
|
|
41742
|
+
}
|
|
41743
|
+
};
|
|
41744
|
+
await scan();
|
|
41745
|
+
allocation.reserve(size + 64, 1);
|
|
41746
|
+
output2 = new Uint8Array(size);
|
|
41747
|
+
await scan();
|
|
41748
|
+
work.signal.throwIfAborted();
|
|
41749
|
+
return shellValueFromBytes(output2, allocation);
|
|
41750
|
+
}
|
|
41751
|
+
|
|
41584
41752
|
// packages/safe-bash/src/shell/runtime.ts
|
|
41585
41753
|
var defaultLimits = {
|
|
41586
41754
|
maxParseUnits: defaultMaxParseUnits,
|
|
@@ -41671,6 +41839,35 @@ function resolveLimits(...limits) {
|
|
|
41671
41839
|
return result2;
|
|
41672
41840
|
}
|
|
41673
41841
|
var budgetedSinks = /* @__PURE__ */ new WeakMap();
|
|
41842
|
+
async function sortExpansionStrings(values, work) {
|
|
41843
|
+
const compare6 = async (left, right) => {
|
|
41844
|
+
for (let index = 0; index < Math.min(left.length, right.length); index++) {
|
|
41845
|
+
const pending = stringCheckpoint(work);
|
|
41846
|
+
if (pending) await pending;
|
|
41847
|
+
const difference = left.charCodeAt(index) - right.charCodeAt(index);
|
|
41848
|
+
if (difference) return difference;
|
|
41849
|
+
}
|
|
41850
|
+
return left.length - right.length;
|
|
41851
|
+
};
|
|
41852
|
+
const sift = async (root, end) => {
|
|
41853
|
+
while (root * 2 + 1 < end) {
|
|
41854
|
+
let child = root * 2 + 1;
|
|
41855
|
+
if (child + 1 < end && await compare6(values[child], values[child + 1]) < 0) child++;
|
|
41856
|
+
if (await compare6(values[root], values[child]) >= 0) return;
|
|
41857
|
+
const saved = values[root];
|
|
41858
|
+
values[root] = values[child];
|
|
41859
|
+
values[child] = saved;
|
|
41860
|
+
root = child;
|
|
41861
|
+
}
|
|
41862
|
+
};
|
|
41863
|
+
for (let index = Math.floor(values.length / 2) - 1; index >= 0; index--) await sift(index, values.length);
|
|
41864
|
+
for (let end = values.length - 1; end > 0; end--) {
|
|
41865
|
+
const saved = values[0];
|
|
41866
|
+
values[0] = values[end];
|
|
41867
|
+
values[end] = saved;
|
|
41868
|
+
await sift(0, end);
|
|
41869
|
+
}
|
|
41870
|
+
}
|
|
41674
41871
|
var Budget25 = class {
|
|
41675
41872
|
constructor(limits, signal, onInternalError) {
|
|
41676
41873
|
this.limits = limits;
|
|
@@ -41841,7 +42038,7 @@ var typedSavedVariables = /* @__PURE__ */ new WeakMap();
|
|
|
41841
42038
|
var valueScope = /* @__PURE__ */ Symbol("shell value allocation scope");
|
|
41842
42039
|
var invokedValues = /* @__PURE__ */ new WeakMap();
|
|
41843
42040
|
function isolateIO(io) {
|
|
41844
|
-
return { ...io, ...io.descriptors ? { descriptors: new Map([...io.descriptors].map(([number5, descriptor2]) => [number5, { ...descriptor2 }])) } : {} };
|
|
42041
|
+
return { ...io, nameExpansionContext: void 0, ...io.descriptors ? { descriptors: new Map([...io.descriptors].map(([number5, descriptor2]) => [number5, { ...descriptor2 }])) } : {} };
|
|
41845
42042
|
}
|
|
41846
42043
|
function activeIO(io) {
|
|
41847
42044
|
const input3 = io.descriptors?.get(0);
|
|
@@ -43038,6 +43235,7 @@ var Runtime = class _Runtime {
|
|
|
43038
43235
|
const current = store.get(name2);
|
|
43039
43236
|
if (index !== void 0 && current) {
|
|
43040
43237
|
staged = index === "members" ? IndexedBinding.create(store.owner) : await current.copy(this.signal);
|
|
43238
|
+
staged.assigned = current.assigned;
|
|
43041
43239
|
let maximum = -1;
|
|
43042
43240
|
for (const key of staged.values.keys()) {
|
|
43043
43241
|
operation2.reserve({ work: 2 }).release();
|
|
@@ -43238,7 +43436,8 @@ var Runtime = class _Runtime {
|
|
|
43238
43436
|
this.signal.throwIfAborted();
|
|
43239
43437
|
if (state.readonlyVariables?.has(name2)) throw new ArrayFailure("readonly binding");
|
|
43240
43438
|
if (!watch.valid()) throw new ArrayFailure("stale binding");
|
|
43241
|
-
|
|
43439
|
+
staged.assigned = true;
|
|
43440
|
+
if (!(assignment.kind === "compound" && assignment.append && writes === 0 && current?.assigned)) {
|
|
43242
43441
|
let released;
|
|
43243
43442
|
stateMonitor(state).publish(tickets, name2, () => {
|
|
43244
43443
|
supersede();
|
|
@@ -43541,8 +43740,8 @@ var Runtime = class _Runtime {
|
|
|
43541
43740
|
signal: this.signal,
|
|
43542
43741
|
locale: state.variables.LC_ALL || state.variables.LC_COLLATE || state.variables.LANG || "C",
|
|
43543
43742
|
work: { remaining: this.budget.limits.maxExpansionBytes, signal: this.signal, exhausted: () => this.budget.fail("maxExpansionBytes"), allocation },
|
|
43544
|
-
expand: async (word, pattern = false) => (await this.word(word, state, io, false, pattern, false, pattern)).join(""),
|
|
43545
|
-
regex: (subject, pattern) => this.ere(subject, pattern, state, io),
|
|
43743
|
+
expand: async (word, pattern = false) => (await this.word(word, state, { ...io, nameExpansionContext: "conditional" }, false, pattern, false, pattern)).join(""),
|
|
43744
|
+
regex: (subject, pattern) => this.ere(subject, pattern, state, { ...io, nameExpansionContext: "conditional" }),
|
|
43546
43745
|
option: (name2) => name2 === "braceexpand" ? state.braceexpand !== false : name2 === "errexit" ? !!state.errexit : name2 === "nounset" ? !!state.nounset : name2 === "pipefail" ? state.pipefail : false,
|
|
43547
43746
|
present: (name2) => {
|
|
43548
43747
|
const match = /^([a-zA-Z_][a-zA-Z_0-9]*)(?:\[(0|[1-9][0-9]*|[@*])\])?$/u.exec(name2);
|
|
@@ -43756,6 +43955,7 @@ var Runtime = class _Runtime {
|
|
|
43756
43955
|
async document(document, state, io, line = document.endLine) {
|
|
43757
43956
|
this.signal.throwIfAborted();
|
|
43758
43957
|
let value2 = "";
|
|
43958
|
+
let fragments;
|
|
43759
43959
|
let size = 0;
|
|
43760
43960
|
let words = 0;
|
|
43761
43961
|
const warnings = [];
|
|
@@ -43765,16 +43965,25 @@ var Runtime = class _Runtime {
|
|
|
43765
43965
|
for (const warning of warnings.splice(0)) await writeDiagnostic(io.stderr, `shell: warning: ${warning}
|
|
43766
43966
|
`);
|
|
43767
43967
|
if (++words % 128 === 0) await yieldTurn(this.signal);
|
|
43768
|
-
const part = (await this.
|
|
43769
|
-
size +=
|
|
43968
|
+
const part = concatShellValues(await this.valueWord(word, state, { ...io, nameExpansionContext: "document" }, false), io[valueScope]);
|
|
43969
|
+
size += shellValueByteLength(part);
|
|
43770
43970
|
if (size > this.budget.limits.maxExpansionBytes) this.budget.fail("maxExpansionBytes");
|
|
43771
|
-
value2 += part;
|
|
43971
|
+
if (!fragments && typeof part === "string") value2 += part;
|
|
43972
|
+
else {
|
|
43973
|
+
if (!fragments) {
|
|
43974
|
+
io[valueScope]?.reserve(64 + value2.length * 2, 0);
|
|
43975
|
+
fragments = [value2];
|
|
43976
|
+
value2 = "";
|
|
43977
|
+
}
|
|
43978
|
+
io[valueScope]?.reserve(32 + (typeof part === "string" ? part.length * 2 : 0), 0);
|
|
43979
|
+
fragments.push(part);
|
|
43980
|
+
}
|
|
43772
43981
|
}
|
|
43773
43982
|
} finally {
|
|
43774
43983
|
for (const warning of warnings.splice(0)) await writeDiagnostic(io.stderr, `shell: warning: ${warning}
|
|
43775
43984
|
`);
|
|
43776
43985
|
}
|
|
43777
|
-
return value2;
|
|
43986
|
+
return fragments ? concatShellValues(fragments, io[valueScope]) : value2;
|
|
43778
43987
|
}
|
|
43779
43988
|
async redirect(redirects, state, io, inputs2, outputs, isolatedInlineInput = false, persistMoves = false, fileShortcut = false, line) {
|
|
43780
43989
|
this.signal.throwIfAborted();
|
|
@@ -43803,6 +44012,7 @@ var Runtime = class _Runtime {
|
|
|
43803
44012
|
const stdinIsDefault = descriptor2?.input ? descriptor2.stdinIsDefault : false;
|
|
43804
44013
|
return {
|
|
43805
44014
|
[invocationScope]: io[invocationScope],
|
|
44015
|
+
...io[valueScope] === void 0 ? {} : { [valueScope]: io[valueScope] },
|
|
43806
44016
|
...io.execution === void 0 ? {} : { execution: io.execution },
|
|
43807
44017
|
...io.diagnosticLine === void 0 ? {} : { diagnosticLine: io.diagnosticLine },
|
|
43808
44018
|
...io.diagnosticOffset === void 0 ? {} : { diagnosticOffset: io.diagnosticOffset },
|
|
@@ -43823,7 +44033,7 @@ var Runtime = class _Runtime {
|
|
|
43823
44033
|
const hereString = redirect.operator === "<<<";
|
|
43824
44034
|
let value2;
|
|
43825
44035
|
try {
|
|
43826
|
-
value2 = redirect.document ? await this.document(redirect.document, state, currentIO(), line) : (await this.
|
|
44036
|
+
value2 = redirect.document ? await this.document(redirect.document, state, currentIO(), line) : concatShellValues(await this.valueWord(redirect.target, state, currentIO(), false, false, hereString), io[valueScope]);
|
|
43827
44037
|
} catch (error) {
|
|
43828
44038
|
if (error instanceof NounsetFailure) throw error;
|
|
43829
44039
|
if (error instanceof ParameterExpansionFailure && !isolatedInlineInput) throw error;
|
|
@@ -43832,10 +44042,10 @@ var Runtime = class _Runtime {
|
|
|
43832
44042
|
throw error;
|
|
43833
44043
|
}
|
|
43834
44044
|
if (hereString) {
|
|
43835
|
-
if (
|
|
43836
|
-
value2
|
|
44045
|
+
if (shellValueByteLength(value2) >= this.budget.limits.maxExpansionBytes) this.budget.fail("maxExpansionBytes");
|
|
44046
|
+
value2 = concatShellValues([value2, "\n"], io[valueScope]);
|
|
43837
44047
|
}
|
|
43838
|
-
const input3 = new ShellInput(toByteSource(value2), this.budget, this.signal);
|
|
44048
|
+
const input3 = new ShellInput(toByteSource(typeof value2 === "string" ? value2 : shellValueBytes(value2, io[valueScope])), this.budget, this.signal);
|
|
43839
44049
|
inputs2.add(input3);
|
|
43840
44050
|
descriptors.set(redirect.descriptor, { input: input3, stdinIsDefault: false });
|
|
43841
44051
|
continue;
|
|
@@ -46343,7 +46553,91 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
46343
46553
|
async part(part, state, io, hereString = false) {
|
|
46344
46554
|
return shellValueText(await this.valuePart(part, state, io, hereString));
|
|
46345
46555
|
}
|
|
46556
|
+
async *prefixNames(prefix3, state) {
|
|
46557
|
+
const allocation = this.budget.values.scope();
|
|
46558
|
+
const store = arrayStore(state);
|
|
46559
|
+
const holding = store?.owner.hold();
|
|
46560
|
+
const work = { remaining: Math.min(Number.MAX_SAFE_INTEGER, this.budget.limits.maxExpansionBytes * 4 + 1024), signal: this.signal, exhausted: () => this.budget.fail("maxExpansionBytes") };
|
|
46561
|
+
try {
|
|
46562
|
+
allocation.reserveBytes(128);
|
|
46563
|
+
const names = [];
|
|
46564
|
+
const seen = /* @__PURE__ */ new Set();
|
|
46565
|
+
let bytes3 = 0;
|
|
46566
|
+
const consider = async (name2, assigned) => {
|
|
46567
|
+
const scanned = await scanString(name2, work);
|
|
46568
|
+
const pending = stringCheckpoint(work, name2.length + 1);
|
|
46569
|
+
if (pending) await pending;
|
|
46570
|
+
if (!assigned || !name2.startsWith(prefix3) || seen.has(name2)) return;
|
|
46571
|
+
for (let index = 0; index < name2.length; index++) {
|
|
46572
|
+
const pending2 = stringCheckpoint(work);
|
|
46573
|
+
if (pending2) await pending2;
|
|
46574
|
+
const code = name2.charCodeAt(index);
|
|
46575
|
+
if (!(code === 95 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || index > 0 && code >= 48 && code <= 57)) return;
|
|
46576
|
+
}
|
|
46577
|
+
if (names.length >= this.budget.limits.maxExpansionFields) this.budget.fail("maxExpansionFields");
|
|
46578
|
+
if (scanned.bytes > this.budget.limits.maxExpansionBytes - bytes3) this.budget.fail("maxExpansionBytes");
|
|
46579
|
+
bytes3 += scanned.bytes;
|
|
46580
|
+
allocation.reserveBytes(name2.length * 2 + 64);
|
|
46581
|
+
seen.add(name2);
|
|
46582
|
+
names.push(name2);
|
|
46583
|
+
};
|
|
46584
|
+
for (const name2 in state.variables) if (Object.hasOwn(state.variables, name2)) await consider(name2, state.variables[name2] !== void 0);
|
|
46585
|
+
if (store) for (const [name2, entry] of store.bindings) await consider(name2, entry.binding.assigned);
|
|
46586
|
+
for (const frame of state.locals) for (const [name2, saved] of frame) {
|
|
46587
|
+
await consider(name2, saved.value !== void 0 || typedSavedVariables.get(saved)?.binding?.assigned === true);
|
|
46588
|
+
}
|
|
46589
|
+
await sortExpansionStrings(names, work);
|
|
46590
|
+
for (const name2 of names) {
|
|
46591
|
+
const pending = stringCheckpoint(work);
|
|
46592
|
+
if (pending) await pending;
|
|
46593
|
+
yield name2;
|
|
46594
|
+
}
|
|
46595
|
+
} finally {
|
|
46596
|
+
allocation.close();
|
|
46597
|
+
holding?.release();
|
|
46598
|
+
}
|
|
46599
|
+
}
|
|
46346
46600
|
async valuePart(part, state, io, hereString = false) {
|
|
46601
|
+
if (part.kind === "variable" && part.transform) {
|
|
46602
|
+
const selector2 = getArraySelector(part);
|
|
46603
|
+
if (selector2?.kind === "members" || part.name === "@" || part.name === "*") {
|
|
46604
|
+
const members = selector2 ? await this.arrayMembers(part.name, state) : this.positionalValues(state);
|
|
46605
|
+
const ifs = state.variables.IFS ?? " ";
|
|
46606
|
+
const separator = ifs.length ? String.fromCodePoint(ifs.codePointAt(0)) : "";
|
|
46607
|
+
const fragments = [];
|
|
46608
|
+
let bytes3 = 0;
|
|
46609
|
+
for (const member2 of members) {
|
|
46610
|
+
const value3 = await this.transformValue(member2, part.transform, state, io);
|
|
46611
|
+
bytes3 += shellValueByteLength(value3) + (fragments.length ? import_buffer.Buffer.byteLength(separator) : 0);
|
|
46612
|
+
if (bytes3 > this.budget.limits.maxExpansionBytes) this.budget.fail("maxExpansionBytes");
|
|
46613
|
+
io[valueScope]?.reserve(32, 0);
|
|
46614
|
+
if (fragments.length) fragments.push(separator);
|
|
46615
|
+
fragments.push(value3);
|
|
46616
|
+
}
|
|
46617
|
+
return concatShellValues(fragments, io[valueScope]);
|
|
46618
|
+
}
|
|
46619
|
+
const base = { ...part };
|
|
46620
|
+
delete base.transform;
|
|
46621
|
+
copyArraySelector(part, base);
|
|
46622
|
+
const existing2 = selector2?.kind === "element" ? arrayStore(state)?.get(part.name)?.get(numericIndex(selector2.index) ?? -1) ?? (numericIndex(selector2.index) === 0 ? this.variable(state, part.name) : void 0) : /^[a-zA-Z_][a-zA-Z_0-9]*$/u.test(part.name) ? this.variable(state, part.name) : /^[1-9][0-9]*$/u.test(part.name) ? state.positional[Number(part.name) - 1] : "";
|
|
46623
|
+
const value2 = await this.valuePart(base, state, io, hereString);
|
|
46624
|
+
return existing2 === void 0 ? "" : this.transformValue(value2, part.transform, state, io);
|
|
46625
|
+
}
|
|
46626
|
+
if (part.kind === "variable" && part.prefixNames) {
|
|
46627
|
+
const ifs = state.variables.IFS ?? " ";
|
|
46628
|
+
const separator = io.nameExpansionContext === "document" || io.nameExpansionContext === "conditional" && part.prefixNames === "@" ? " " : ifs.length ? String.fromCodePoint(ifs.codePointAt(0)) : "";
|
|
46629
|
+
const fragments = [];
|
|
46630
|
+
let bytes3 = 0;
|
|
46631
|
+
for await (const name2 of this.prefixNames(part.name, state)) {
|
|
46632
|
+
const join = fragments.length ? separator : "";
|
|
46633
|
+
bytes3 += import_buffer.Buffer.byteLength(name2) + import_buffer.Buffer.byteLength(join);
|
|
46634
|
+
if (bytes3 > this.budget.limits.maxExpansionBytes) this.budget.fail("maxExpansionBytes");
|
|
46635
|
+
io[valueScope]?.reserve((name2.length + join.length) * 2 + 32, 0);
|
|
46636
|
+
fragments.push(join, name2);
|
|
46637
|
+
}
|
|
46638
|
+
io[valueScope]?.reserve(bytes3 * 2, 0);
|
|
46639
|
+
return fragments.join("");
|
|
46640
|
+
}
|
|
46347
46641
|
const binding = part.kind === "variable" ? arrayStore(state)?.get(part.name) : void 0;
|
|
46348
46642
|
const holding = binding ? requireArrays(state).owner.hold() : void 0;
|
|
46349
46643
|
const selector = getArraySelector(part);
|
|
@@ -46365,6 +46659,19 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
46365
46659
|
if (state.depth + parameterDepth > 64) throw new ShellSyntaxError("Syntax nesting exceeds 64", word.offset);
|
|
46366
46660
|
return { ...io, parameterDepth };
|
|
46367
46661
|
}
|
|
46662
|
+
async transformValue(value2, operator, state, io) {
|
|
46663
|
+
const allocation = io[valueScope] ?? this.budget.values.scope();
|
|
46664
|
+
try {
|
|
46665
|
+
return await transformParameter(value2, operator, {
|
|
46666
|
+
maximumBytes: this.budget.limits.maxExpansionBytes,
|
|
46667
|
+
byteLocale: byteLocale(state.variables),
|
|
46668
|
+
allocation,
|
|
46669
|
+
work: { remaining: Math.min(Number.MAX_SAFE_INTEGER, this.budget.limits.maxExpansionBytes * 8 + 1024), signal: this.signal, exhausted: () => this.budget.fail("maxExpansionBytes") }
|
|
46670
|
+
});
|
|
46671
|
+
} finally {
|
|
46672
|
+
if (!io[valueScope]) allocation.close();
|
|
46673
|
+
}
|
|
46674
|
+
}
|
|
46368
46675
|
async partValue(part, state, io, hereString) {
|
|
46369
46676
|
this.signal.throwIfAborted();
|
|
46370
46677
|
if (part.kind === "compound-substitution-eof") {
|
|
@@ -46733,7 +47040,8 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
46733
47040
|
}
|
|
46734
47041
|
return fields3;
|
|
46735
47042
|
}
|
|
46736
|
-
const arrayOwned = word.parts.some((part) => part.kind === "variable" && (getArraySelector(part) !== void 0 || arrayStore(state)?.get(part.name) !== void 0));
|
|
47043
|
+
const arrayOwned = word.parts.some((part) => part.kind === "variable" && !part.prefixNames && (getArraySelector(part) !== void 0 || arrayStore(state)?.get(part.name) !== void 0));
|
|
47044
|
+
const prefixOwned = word.parts.some((part) => part.kind === "variable" && (part.prefixNames === "@" || part.transform && part.name === "@"));
|
|
46737
47045
|
const owner = arrayOwned ? requireArrays(state).owner : void 0;
|
|
46738
47046
|
const holding = owner?.hold();
|
|
46739
47047
|
const scratch = !owner && split4 && state.variables.IFS !== "" && word.parts.some((part) => !part.quoted && part.kind !== "text") ? this.budget.values.scope() : void 0;
|
|
@@ -46742,11 +47050,13 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
46742
47050
|
owner?.reserve({ metadata: 128 + word.parts.length * 32, allocatedSlots: word.parts.length + 1, work: word.parts.length + 5 });
|
|
46743
47051
|
scratch?.reserve(word.parts.length * 32, 0);
|
|
46744
47052
|
const fields3 = [];
|
|
47053
|
+
let emptyNameGroups;
|
|
47054
|
+
let quoteGroup;
|
|
46745
47055
|
const addField = () => {
|
|
46746
47056
|
if (fields3.length >= this.budget.limits.maxExpansionFields) this.budget.fail("maxExpansionFields");
|
|
46747
47057
|
scratch?.reserve(32, 0);
|
|
46748
47058
|
owner?.reserve({ metadata: 32, allocatedSlots: 1, work: 3 });
|
|
46749
|
-
fields3.push({ fragments: [], bytes: false, patterns: void 0, present: false });
|
|
47059
|
+
fields3.push({ fragments: [], bytes: false, patterns: void 0, present: false, independentPresence: false });
|
|
46750
47060
|
};
|
|
46751
47061
|
addField();
|
|
46752
47062
|
let expansionBytes = 0;
|
|
@@ -46779,6 +47089,14 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
46779
47089
|
regexAppend?.(text3, !glob);
|
|
46780
47090
|
field2.fragments.push(value2);
|
|
46781
47091
|
field2.present ||= present;
|
|
47092
|
+
if (present) {
|
|
47093
|
+
if (size > 0 || !quoteGroup) field2.independentPresence = true;
|
|
47094
|
+
else {
|
|
47095
|
+
io[valueScope]?.reserve(32, 0);
|
|
47096
|
+
field2.quoteGroups ??= [];
|
|
47097
|
+
field2.quoteGroups.push(quoteGroup);
|
|
47098
|
+
}
|
|
47099
|
+
}
|
|
46782
47100
|
};
|
|
46783
47101
|
const appendSplit = async (value2) => {
|
|
46784
47102
|
this.budget.cpuCheckpoint();
|
|
@@ -46827,7 +47145,8 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
46827
47145
|
const parts = word.parts.map((part) => ({ part, splitText: false, io }));
|
|
46828
47146
|
for (let index = 0; index < parts.length; index++) {
|
|
46829
47147
|
const { part, splitText, io: partIO } = parts[index];
|
|
46830
|
-
|
|
47148
|
+
quoteGroup = prefixNameQuoteGroups.get(part);
|
|
47149
|
+
const quotedPresence = part.quoted && !((arrayOwned || prefixOwned) && isQuoteMarker(part));
|
|
46831
47150
|
if (part.kind === "variable" && ["-", "+", ":-", ":+"].includes(part.operator ?? "") && /^[a-zA-Z_][a-zA-Z_0-9]*$/u.test(part.name)) {
|
|
46832
47151
|
const value2 = this.variable(state, part.name);
|
|
46833
47152
|
const missing = value2 === void 0 || part.operator.startsWith(":") && value2 === "";
|
|
@@ -46841,19 +47160,36 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
46841
47160
|
}
|
|
46842
47161
|
}
|
|
46843
47162
|
const selector = getArraySelector(part);
|
|
46844
|
-
if (part.kind === "variable" &&
|
|
46845
|
-
|
|
47163
|
+
if (part.kind === "variable" && part.prefixNames === "@" && split4 && (part.quoted || state.variables.IFS === "")) {
|
|
47164
|
+
let position = 0;
|
|
47165
|
+
for await (const name2 of this.prefixNames(part.name, state)) {
|
|
47166
|
+
if (position++) addField();
|
|
47167
|
+
append(name2, !part.quoted, true);
|
|
47168
|
+
}
|
|
47169
|
+
if (position === 0 && quoteGroup) {
|
|
47170
|
+
io[valueScope]?.reserve(32, 0);
|
|
47171
|
+
emptyNameGroups ??= /* @__PURE__ */ new Set();
|
|
47172
|
+
emptyNameGroups.add(quoteGroup);
|
|
47173
|
+
}
|
|
47174
|
+
} else if (part.kind === "variable" && split4 && (selector?.kind === "members" && !part.length && (!part.quoted || selector.separator === "@") || part.transform && part.name === "@")) {
|
|
47175
|
+
const members = selector?.kind === "members" ? await this.arrayMembers(part.name, state) : this.positionalValues(state);
|
|
46846
47176
|
for (let position = 0; position < members.length; position++) {
|
|
46847
47177
|
if (position > 0) addField();
|
|
46848
|
-
const
|
|
46849
|
-
|
|
47178
|
+
const original = members[position];
|
|
47179
|
+
const value2 = part.transform ? await this.transformValue(original, part.transform, state, partIO) : original;
|
|
47180
|
+
if (part.quoted || state.variables.IFS === "") append(value2, !part.quoted, part.quoted || shellValueByteLength(value2) > 0);
|
|
46850
47181
|
else await appendSplit(value2);
|
|
46851
47182
|
}
|
|
47183
|
+
if (part.transform && members.length === 0 && quoteGroup) {
|
|
47184
|
+
io[valueScope]?.reserve(32, 0);
|
|
47185
|
+
emptyNameGroups ??= /* @__PURE__ */ new Set();
|
|
47186
|
+
emptyNameGroups.add(quoteGroup);
|
|
47187
|
+
}
|
|
46852
47188
|
} else if (part.kind === "text" && !splitText) {
|
|
46853
47189
|
let value2 = invokedValues.get(part) ?? part.byteValue ?? part.value;
|
|
46854
47190
|
if (typeof value2 === "string" && index === 0 && !part.quoted && /^~(?:\/|$)/u.test(value2)) value2 = (state.variables.HOME ?? "~") + value2.slice(1);
|
|
46855
47191
|
append(value2, !part.quoted, quotedPresence || shellValueByteLength(value2) > 0);
|
|
46856
|
-
} else if (part.kind === "variable" && part.name === "@" && part.quoted && !part.operator && split4) {
|
|
47192
|
+
} else if (part.kind === "variable" && part.name === "@" && part.quoted && !part.operator && !part.transform && split4) {
|
|
46857
47193
|
for (let position = 0; position < state.positional.length; position++) {
|
|
46858
47194
|
if (position > 0) addField();
|
|
46859
47195
|
append(stateMonitor(state)?.positionals.get(String(position), state.positional[position]) ?? state.positional[position], false, true);
|
|
@@ -46871,6 +47207,19 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
46871
47207
|
let resultBytes = 0;
|
|
46872
47208
|
for (const field2 of fields3) {
|
|
46873
47209
|
if (!field2.present && split4) continue;
|
|
47210
|
+
if (split4 && !field2.independentPresence && field2.quoteGroups) {
|
|
47211
|
+
const work = { remaining: this.budget.limits.maxExpansionBytes, signal: this.signal, exhausted: () => this.budget.fail("maxExpansionBytes") };
|
|
47212
|
+
let empty2 = true;
|
|
47213
|
+
for (const group of field2.quoteGroups) {
|
|
47214
|
+
const pending = stringCheckpoint(work);
|
|
47215
|
+
if (pending) await pending;
|
|
47216
|
+
if (!emptyNameGroups?.has(group)) {
|
|
47217
|
+
empty2 = false;
|
|
47218
|
+
break;
|
|
47219
|
+
}
|
|
47220
|
+
}
|
|
47221
|
+
if (empty2) continue;
|
|
47222
|
+
}
|
|
46874
47223
|
if (scratch && field2.fragments.length > 1 && !field2.bytes) scratch.reserve(field2.fragments.reduce((bytes3, value2) => bytes3 + shellValueText(value2).length * 2, 0), 0);
|
|
46875
47224
|
const assembled = concatShellValues(field2.fragments, io[valueScope]);
|
|
46876
47225
|
const projection = shellValueText(assembled);
|
|
@@ -47141,33 +47490,7 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
47141
47490
|
if (!ignored(error)) throw error;
|
|
47142
47491
|
}
|
|
47143
47492
|
}
|
|
47144
|
-
|
|
47145
|
-
for (let index = 0; index < Math.min(left.length, right.length); index++) {
|
|
47146
|
-
const pending = stringCheckpoint(work);
|
|
47147
|
-
if (pending) await pending;
|
|
47148
|
-
const difference = left.charCodeAt(index) - right.charCodeAt(index);
|
|
47149
|
-
if (difference) return difference;
|
|
47150
|
-
}
|
|
47151
|
-
return left.length - right.length;
|
|
47152
|
-
};
|
|
47153
|
-
const sift = async (root, end) => {
|
|
47154
|
-
while (root * 2 + 1 < end) {
|
|
47155
|
-
let child = root * 2 + 1;
|
|
47156
|
-
if (child + 1 < end && await compare6(found[child], found[child + 1]) < 0) child++;
|
|
47157
|
-
if (await compare6(found[root], found[child]) >= 0) return;
|
|
47158
|
-
const saved = found[root];
|
|
47159
|
-
found[root] = found[child];
|
|
47160
|
-
found[child] = saved;
|
|
47161
|
-
root = child;
|
|
47162
|
-
}
|
|
47163
|
-
};
|
|
47164
|
-
for (let index = Math.floor(found.length / 2) - 1; index >= 0; index--) await sift(index, found.length);
|
|
47165
|
-
for (let end = found.length - 1; end > 0; end--) {
|
|
47166
|
-
const saved = found[0];
|
|
47167
|
-
found[0] = found[end];
|
|
47168
|
-
found[end] = saved;
|
|
47169
|
-
await sift(0, end);
|
|
47170
|
-
}
|
|
47493
|
+
await sortExpansionStrings(found, work);
|
|
47171
47494
|
return found.length ? found : [value2];
|
|
47172
47495
|
} finally {
|
|
47173
47496
|
scratch.close();
|
|
@@ -49866,15 +50189,15 @@ function* entities2(text3) {
|
|
|
49866
50189
|
const predefined = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'" };
|
|
49867
50190
|
if (Object.hasOwn(predefined, entity)) result2 += predefined[entity];
|
|
49868
50191
|
else {
|
|
49869
|
-
const
|
|
49870
|
-
const digits = entity.slice(
|
|
50192
|
+
const hexadecimal2 = entity.startsWith("#x");
|
|
50193
|
+
const digits = entity.slice(hexadecimal2 ? 2 : 1);
|
|
49871
50194
|
if (!entity.startsWith("#") || !digits.length) invalid("undeclared entity");
|
|
49872
50195
|
let point = 0;
|
|
49873
50196
|
for (let index = 0; index < digits.length; index++) {
|
|
49874
50197
|
const code = digits.charCodeAt(index);
|
|
49875
|
-
const digit3 = code >= 48 && code <= 57 ? code - 48 :
|
|
50198
|
+
const digit3 = code >= 48 && code <= 57 ? code - 48 : hexadecimal2 && code >= 65 && code <= 70 ? code - 55 : hexadecimal2 && code >= 97 && code <= 102 ? code - 87 : -1;
|
|
49876
50199
|
if (digit3 < 0) invalid("undeclared entity");
|
|
49877
|
-
point = point * (
|
|
50200
|
+
point = point * (hexadecimal2 ? 16 : 10) + digit3;
|
|
49878
50201
|
if (point > 1114111) invalid("invalid character reference");
|
|
49879
50202
|
if ((index + 1) % 512 === 0) yield 512;
|
|
49880
50203
|
}
|