@poe-platform/safe-bash 0.1.49 → 0.1.51
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 +115 -67
- package/dist/safe-bash/browser.js.map +2 -2
- package/dist/safe-bash/shell/arithmetic.d.ts.map +1 -1
- package/dist/safe-bash/shell/arithmetic.js +76 -52
- package/dist/safe-bash/shell/arithmetic.js.map +1 -1
- package/dist/safe-bash/shell/input.d.ts.map +1 -1
- package/dist/safe-bash/shell/input.js +39 -16
- package/dist/safe-bash/shell/input.js.map +1 -1
- package/dist/safe-bash/shell/runtime.d.ts.map +1 -1
- package/dist/safe-bash/shell/runtime.js +25 -18
- package/dist/safe-bash/shell/runtime.js.map +1 -1
- package/package.json +2 -2
|
@@ -4822,47 +4822,62 @@ function evaluateArithmetic(program, variables) {
|
|
|
4822
4822
|
throw new Error(`Unsupported arithmetic operator ${operator}`);
|
|
4823
4823
|
}
|
|
4824
4824
|
};
|
|
4825
|
-
const evaluate = (node) => {
|
|
4826
|
-
if (++steps > 1e4) throw new Error("Arithmetic operation limit exceeded");
|
|
4827
|
-
let value2;
|
|
4828
|
-
if (node.kind === "literal") return node.value;
|
|
4829
|
-
if (node.kind === "name") {
|
|
4830
|
-
if (visiting.has(node.name) || visiting.size >= 64) throw new Error("Arithmetic variable recursion");
|
|
4831
|
-
visiting.add(node.name);
|
|
4832
|
-
try {
|
|
4833
|
-
return evaluate(parseArithmetic(variables[node.name] ?? "0"));
|
|
4834
|
-
} finally {
|
|
4835
|
-
visiting.delete(node.name);
|
|
4836
|
-
}
|
|
4837
|
-
}
|
|
4838
|
-
if (node.kind === "conditional") return evaluate(evaluate(node.condition) ? node.yes : node.no);
|
|
4839
|
-
if (node.kind === "unary") {
|
|
4840
|
-
const operand = evaluate(node.operand);
|
|
4841
|
-
if (node.operator === "+") value2 = operand;
|
|
4842
|
-
else if (node.operator === "-") value2 = -operand;
|
|
4843
|
-
else if (node.operator === "!") value2 = BigInt(!operand);
|
|
4844
|
-
else if (node.operator === "~") value2 = ~operand;
|
|
4845
|
-
else {
|
|
4846
|
-
value2 = BigInt.asIntN(64, operand + (node.operator === "++" ? 1n : -1n));
|
|
4847
|
-
variables[node.operand.name] = String(value2);
|
|
4848
|
-
if (node.postfix) value2 = operand;
|
|
4849
|
-
}
|
|
4850
|
-
} else {
|
|
4851
|
-
if (node.operator === "=") value2 = evaluate(node.right);
|
|
4852
|
-
else {
|
|
4853
|
-
const left = evaluate(node.left);
|
|
4854
|
-
if (node.operator === "&&") return left ? BigInt(evaluate(node.right) !== 0n) : 0n;
|
|
4855
|
-
if (node.operator === "||") return left ? 1n : BigInt(evaluate(node.right) !== 0n);
|
|
4856
|
-
if (node.operator === ",") return evaluate(node.right);
|
|
4857
|
-
value2 = binary(precedence[node.operator] === 2 ? node.operator.slice(0, -1) : node.operator, left, evaluate(node.right), node.right.start ?? 0);
|
|
4858
|
-
}
|
|
4859
|
-
if (precedence[node.operator] === 2) variables[node.left.name] = String(BigInt.asIntN(64, value2));
|
|
4860
|
-
}
|
|
4861
|
-
return BigInt.asIntN(64, value2);
|
|
4862
|
-
};
|
|
4863
4825
|
try {
|
|
4864
4826
|
if (program.error) throw program.error;
|
|
4865
|
-
|
|
4827
|
+
const pending = [{ kind: "evaluate", node: program.tree }];
|
|
4828
|
+
let value2 = 0n;
|
|
4829
|
+
while (pending.length) {
|
|
4830
|
+
const frame = pending.pop();
|
|
4831
|
+
if (frame.kind === "evaluate") {
|
|
4832
|
+
if (++steps > 1e4) throw new Error("Arithmetic operation limit exceeded");
|
|
4833
|
+
const node = frame.node;
|
|
4834
|
+
if (node.kind === "literal") value2 = node.value;
|
|
4835
|
+
else if (node.kind === "name") {
|
|
4836
|
+
if (visiting.has(node.name) || visiting.size >= 64) throw new Error("Arithmetic variable recursion");
|
|
4837
|
+
visiting.add(node.name);
|
|
4838
|
+
pending.push({ kind: "variable", name: node.name }, { kind: "evaluate", node: parseArithmetic(variables[node.name] ?? "0") });
|
|
4839
|
+
} else if (node.kind === "conditional") {
|
|
4840
|
+
pending.push({ kind: "conditional", node }, { kind: "evaluate", node: node.condition });
|
|
4841
|
+
} else if (node.kind === "unary") {
|
|
4842
|
+
pending.push({ kind: "unary", node }, { kind: "evaluate", node: node.operand });
|
|
4843
|
+
} else if (node.operator === "=") {
|
|
4844
|
+
pending.push({ kind: "right", node }, { kind: "evaluate", node: node.right });
|
|
4845
|
+
} else {
|
|
4846
|
+
pending.push({ kind: "left", node }, { kind: "evaluate", node: node.left });
|
|
4847
|
+
}
|
|
4848
|
+
} else if (frame.kind === "variable") visiting.delete(frame.name);
|
|
4849
|
+
else if (frame.kind === "conditional") {
|
|
4850
|
+
pending.push({ kind: "evaluate", node: value2 ? frame.node.yes : frame.node.no });
|
|
4851
|
+
} else if (frame.kind === "unary") {
|
|
4852
|
+
const { node } = frame;
|
|
4853
|
+
const operand = value2;
|
|
4854
|
+
if (node.operator === "+") value2 = operand;
|
|
4855
|
+
else if (node.operator === "-") value2 = -operand;
|
|
4856
|
+
else if (node.operator === "!") value2 = BigInt(!operand);
|
|
4857
|
+
else if (node.operator === "~") value2 = ~operand;
|
|
4858
|
+
else {
|
|
4859
|
+
value2 = BigInt.asIntN(64, operand + (node.operator === "++" ? 1n : -1n));
|
|
4860
|
+
variables[node.operand.name] = String(value2);
|
|
4861
|
+
if (node.postfix) value2 = operand;
|
|
4862
|
+
}
|
|
4863
|
+
value2 = BigInt.asIntN(64, value2);
|
|
4864
|
+
} else if (frame.kind === "left") {
|
|
4865
|
+
const { node } = frame;
|
|
4866
|
+
if (node.operator === "&&" || node.operator === "||") {
|
|
4867
|
+
if (node.operator === "&&" ? value2 === 0n : value2 !== 0n) value2 = BigInt(value2 !== 0n);
|
|
4868
|
+
else pending.push({ kind: "logical" }, { kind: "evaluate", node: node.right });
|
|
4869
|
+
} else {
|
|
4870
|
+
if (node.operator !== ",") pending.push({ kind: "right", node, left: value2 });
|
|
4871
|
+
pending.push({ kind: "evaluate", node: node.right });
|
|
4872
|
+
}
|
|
4873
|
+
} else if (frame.kind === "right") {
|
|
4874
|
+
const { node } = frame;
|
|
4875
|
+
if (node.operator !== "=") value2 = binary(precedence[node.operator] === 2 ? node.operator.slice(0, -1) : node.operator, frame.left, value2, node.right.start ?? 0);
|
|
4876
|
+
if (precedence[node.operator] === 2) variables[node.left.name] = String(BigInt.asIntN(64, value2));
|
|
4877
|
+
value2 = BigInt.asIntN(64, value2);
|
|
4878
|
+
} else value2 = BigInt(value2 !== 0n);
|
|
4879
|
+
}
|
|
4880
|
+
return value2;
|
|
4866
4881
|
} catch (error) {
|
|
4867
4882
|
if (error instanceof ArithmeticFailure) throw new Error(`${program.source.trimStart()}: ${error.message} (error token is "${program.source.slice(error.offset)}")`);
|
|
4868
4883
|
if (error instanceof ShellSyntaxError) {
|
|
@@ -13801,21 +13816,31 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
13801
13816
|
this.writeVariable(state, "REPLY", line.value);
|
|
13802
13817
|
} else {
|
|
13803
13818
|
const separators = exact ? "" : state.variables.IFS ?? " \n";
|
|
13804
|
-
|
|
13805
|
-
|
|
13806
|
-
|
|
13807
|
-
|
|
13808
|
-
|
|
13819
|
+
let end = 0;
|
|
13820
|
+
let offset = 0;
|
|
13821
|
+
let point = 0;
|
|
13822
|
+
for (const character of line.value) {
|
|
13823
|
+
offset += character.length;
|
|
13824
|
+
if (line.escaped.has(point) || !separators.includes(character) || !" \n".includes(character)) end = offset;
|
|
13825
|
+
point++;
|
|
13826
|
+
}
|
|
13809
13827
|
let position = 0;
|
|
13810
|
-
|
|
13828
|
+
point = 0;
|
|
13829
|
+
const separator = () => position < end && !line.escaped.has(point) && separators.includes(String.fromCodePoint(line.value.codePointAt(position)));
|
|
13830
|
+
const whitespace = () => separator() && " \n".includes(line.value[position]);
|
|
13831
|
+
const advance = () => {
|
|
13832
|
+
position += line.value.codePointAt(position) > 65535 ? 2 : 1;
|
|
13833
|
+
point++;
|
|
13834
|
+
};
|
|
13835
|
+
while (position < end && whitespace()) advance();
|
|
13811
13836
|
const fields = [];
|
|
13812
|
-
while (position < end) {
|
|
13837
|
+
while (position < end && fields.length < names.length) {
|
|
13813
13838
|
const start = position;
|
|
13814
|
-
while (position < end && !separator(
|
|
13839
|
+
while (position < end && !separator()) advance();
|
|
13815
13840
|
fields.push({ start, end: position });
|
|
13816
|
-
while (position < end && whitespace(
|
|
13817
|
-
if (position < end && separator(
|
|
13818
|
-
while (position < end && whitespace(
|
|
13841
|
+
while (position < end && whitespace()) advance();
|
|
13842
|
+
if (position < end && separator()) advance();
|
|
13843
|
+
while (position < end && whitespace()) advance();
|
|
13819
13844
|
}
|
|
13820
13845
|
for (let index = 0; index < names.length; index++) {
|
|
13821
13846
|
if (state.readonlyVariables?.has(names[index])) {
|
|
@@ -13823,7 +13848,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
13823
13848
|
return index === names.length - 1 ? 1 : 2;
|
|
13824
13849
|
}
|
|
13825
13850
|
const field = fields[index];
|
|
13826
|
-
await this.assignVariable(state, names[index], field ?
|
|
13851
|
+
await this.assignVariable(state, names[index], field ? line.value.slice(field.start, index === names.length - 1 && position < end ? end : field.end) : "");
|
|
13827
13852
|
}
|
|
13828
13853
|
}
|
|
13829
13854
|
return line.terminated ? 0 : 1;
|
|
@@ -14575,6 +14600,21 @@ var InputCursor = class {
|
|
|
14575
14600
|
signal.throwIfAborted();
|
|
14576
14601
|
}
|
|
14577
14602
|
};
|
|
14603
|
+
var ReadText = class {
|
|
14604
|
+
#chunks = [];
|
|
14605
|
+
#pending = [];
|
|
14606
|
+
append(value2) {
|
|
14607
|
+
if (!value2) return;
|
|
14608
|
+
this.#pending.push(value2);
|
|
14609
|
+
if (this.#pending.length === 1024) {
|
|
14610
|
+
this.#chunks.push(this.#pending.join(""));
|
|
14611
|
+
this.#pending.length = 0;
|
|
14612
|
+
}
|
|
14613
|
+
}
|
|
14614
|
+
finish() {
|
|
14615
|
+
return this.#chunks.join("") + this.#pending.join("");
|
|
14616
|
+
}
|
|
14617
|
+
};
|
|
14578
14618
|
var ShellInput = class _ShellInput {
|
|
14579
14619
|
constructor(source, budget, signal = budget.signal) {
|
|
14580
14620
|
this.budget = budget;
|
|
@@ -14631,7 +14671,8 @@ var ShellInput = class _ShellInput {
|
|
|
14631
14671
|
return this.#cursor.consume(this.signal, () => options2 ? this.readBounded(raw, options2) : this.readLine(raw));
|
|
14632
14672
|
}
|
|
14633
14673
|
async readBounded(raw, options2) {
|
|
14634
|
-
const
|
|
14674
|
+
const text = new ReadText();
|
|
14675
|
+
let characters = 0;
|
|
14635
14676
|
const escaped = /* @__PURE__ */ new Set();
|
|
14636
14677
|
const decoder3 = new TextDecoder("utf-8", { fatal: true });
|
|
14637
14678
|
const delimiter = options2.delimiter ?? 10;
|
|
@@ -14676,18 +14717,21 @@ var ShellInput = class _ShellInput {
|
|
|
14676
14717
|
escapedCharacter = true;
|
|
14677
14718
|
}
|
|
14678
14719
|
const decoded = decoder3.decode(Uint8Array.of(byte), { stream: true });
|
|
14720
|
+
let decodedCharacters = 0;
|
|
14679
14721
|
for (const character of decoded) {
|
|
14680
14722
|
if (escapedCharacter) {
|
|
14681
14723
|
escapedCharacter = false;
|
|
14682
|
-
escaped.add(characters
|
|
14724
|
+
escaped.add(characters);
|
|
14683
14725
|
}
|
|
14684
|
-
|
|
14726
|
+
text.append(character);
|
|
14727
|
+
characters++;
|
|
14728
|
+
decodedCharacters++;
|
|
14685
14729
|
}
|
|
14686
|
-
units += options2.byteCount ? 1 :
|
|
14730
|
+
units += options2.byteCount ? 1 : decodedCharacters;
|
|
14687
14731
|
if (units === options2.count) terminated = true;
|
|
14688
14732
|
}
|
|
14689
14733
|
decoder3.decode();
|
|
14690
|
-
return { value:
|
|
14734
|
+
return { value: text.finish(), escaped, terminated };
|
|
14691
14735
|
} catch (error) {
|
|
14692
14736
|
if (error instanceof TypeError && error.message.includes("encoded data")) throw new Error("read: unsupported non-UTF-8 text boundary");
|
|
14693
14737
|
throw error;
|
|
@@ -14739,17 +14783,21 @@ var ShellInput = class _ShellInput {
|
|
|
14739
14783
|
}
|
|
14740
14784
|
const value2 = new TextDecoder().decode(bytes).replace(/\0/gu, "");
|
|
14741
14785
|
const escaped = /* @__PURE__ */ new Set();
|
|
14742
|
-
if (raw) return { value: value2, escaped, terminated };
|
|
14743
|
-
const
|
|
14744
|
-
|
|
14745
|
-
for (let index = 0; index <
|
|
14746
|
-
|
|
14747
|
-
|
|
14748
|
-
|
|
14749
|
-
|
|
14750
|
-
|
|
14751
|
-
|
|
14752
|
-
|
|
14786
|
+
if (raw || !value2.includes("\\")) return { value: value2, escaped, terminated };
|
|
14787
|
+
const text = new ReadText();
|
|
14788
|
+
let characters = 0;
|
|
14789
|
+
for (let index = 0; index < value2.length; ) {
|
|
14790
|
+
const slash = value2.indexOf("\\", index);
|
|
14791
|
+
const span = value2.slice(index, slash < 0 ? value2.length : slash);
|
|
14792
|
+
text.append(span);
|
|
14793
|
+
for (let pointOffset = 0; pointOffset < span.length; pointOffset += span.codePointAt(pointOffset) > 65535 ? 2 : 1) characters++;
|
|
14794
|
+
if (slash < 0 || slash + 1 === value2.length) break;
|
|
14795
|
+
const character = String.fromCodePoint(value2.codePointAt(slash + 1));
|
|
14796
|
+
escaped.add(characters++);
|
|
14797
|
+
text.append(character);
|
|
14798
|
+
index = slash + 1 + character.length;
|
|
14799
|
+
}
|
|
14800
|
+
return { value: text.finish(), escaped, terminated };
|
|
14753
14801
|
}
|
|
14754
14802
|
close() {
|
|
14755
14803
|
if (!this.#closing) {
|