@poe-platform/safe-bash 0.1.505 → 0.1.506

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.
@@ -34177,6 +34177,8 @@ function printedSimpleLines(lists, separators, budget) {
34177
34177
  }
34178
34178
  var IncompleteShellInput = class extends Error {
34179
34179
  };
34180
+ var CompoundListEofError = class extends ShellSyntaxError {
34181
+ };
34180
34182
  var Lexer2 = class {
34181
34183
  constructor(budget, source2, depth, warnings = [], lineOffset = 0, byteLocale2 = false, documentLine, partial = false, lineIndex = new SourceLineIndex(source2, budget), sourceOffset = 0, ordinaryBacktick = false) {
34182
34184
  this.budget = budget;
@@ -34757,8 +34759,10 @@ var Parser4 = class {
34757
34759
  lookahead;
34758
34760
  nesting = 0;
34759
34761
  openCommands = [];
34760
- error(message3) {
34762
+ completedInput;
34763
+ error(message3, compoundList = false) {
34761
34764
  const command7 = this.current.kind === "end" ? this.openCommands.findLast((command8) => ["{", "if", "while", "until", "for", "case"].includes(command8.name)) : void 0;
34765
+ if (compoundList && command7 && this.lexer.ordinaryBacktick) throw new CompoundListEofError(message3, this.current.offset, 2, command7);
34762
34766
  throw new ShellSyntaxError(message3, this.current.offset, 2, command7);
34763
34767
  }
34764
34768
  advance() {
@@ -34776,19 +34780,20 @@ var Parser4 = class {
34776
34780
  isEnd() {
34777
34781
  return this.current.kind === "end";
34778
34782
  }
34779
- expect(value2) {
34780
- if (!this.is(value2)) this.error(`Expected ${value2}`);
34783
+ expect(value2, compoundList = false) {
34784
+ if (!this.is(value2)) this.error(`Expected ${value2}`, compoundList);
34781
34785
  this.advance();
34782
34786
  }
34783
34787
  newlines() {
34784
34788
  while (this.is("\n")) this.advance();
34785
34789
  }
34786
- script(stops = /* @__PURE__ */ new Set(), inputUnit = false) {
34790
+ script(stops = /* @__PURE__ */ new Set(), inputUnit = false, captureInputUnits = false) {
34787
34791
  this.budget.admit();
34788
34792
  const lists = [];
34789
34793
  const separators = [];
34790
34794
  this.newlines();
34791
34795
  const line = this.lexer.lineAt(this.current.offset);
34796
+ if (captureInputUnits) this.completedInput = { lists, count: 0, line };
34792
34797
  while (this.current.kind !== "end" && !stops.has(this.current.value)) {
34793
34798
  this.budget.admit();
34794
34799
  const pipelines = [this.pipeline()];
@@ -34800,9 +34805,11 @@ var Parser4 = class {
34800
34805
  }
34801
34806
  lists.push({ pipelines, operators });
34802
34807
  separators.push(this.is("\n"));
34808
+ if (captureInputUnits && this.is("\n")) this.completedInput.count = lists.length;
34803
34809
  if (inputUnit && this.is("\n")) break;
34804
34810
  if (this.is(";") || this.is("\n")) {
34805
34811
  this.advance();
34812
+ if (captureInputUnits && this.is("\n")) this.completedInput.count = lists.length;
34806
34813
  if (inputUnit && this.is("\n")) break;
34807
34814
  this.newlines();
34808
34815
  } else if (!this.isEnd() && !this.is(")") && !(stops.has(this.current.value) && [";;", ";&", ";;&"].includes(this.current.value))) this.error("Expected command separator");
@@ -34930,15 +34937,15 @@ var Parser4 = class {
34930
34937
  const subshell = this.is("(");
34931
34938
  this.advance();
34932
34939
  const body = this.script(/* @__PURE__ */ new Set([subshell ? ")" : "}"]));
34933
- if (!body.lists.length) this.error("Empty compound command");
34934
- this.expect(subshell ? ")" : "}");
34940
+ if (!body.lists.length) this.error("Empty compound command", !subshell);
34941
+ this.expect(subshell ? ")" : "}", !subshell);
34935
34942
  command7 = { kind: subshell ? "subshell" : "group", body, redirects: [] };
34936
34943
  } else if (this.is("if")) {
34937
34944
  this.advance();
34938
34945
  const branches = [];
34939
34946
  while (true) {
34940
34947
  const condition = this.nonemptyScript(/* @__PURE__ */ new Set(["then"]));
34941
- this.expect("then");
34948
+ this.expect("then", true);
34942
34949
  const body = this.nonemptyScript(/* @__PURE__ */ new Set(["elif", "else", "fi"]));
34943
34950
  this.budget.admit();
34944
34951
  branches.push({ condition, body });
@@ -34950,17 +34957,18 @@ var Parser4 = class {
34950
34957
  this.advance();
34951
34958
  otherwise = this.nonemptyScript(/* @__PURE__ */ new Set(["fi"]));
34952
34959
  }
34953
- this.expect("fi");
34960
+ this.expect("fi", true);
34954
34961
  command7 = { kind: "if", branches, ...otherwise ? { otherwise } : {}, redirects: [] };
34955
34962
  } else if (this.is("case")) {
34956
34963
  this.advance();
34957
34964
  if (!this.current.word) this.error("Expected case subject");
34958
34965
  const subject = this.advance().word;
34959
34966
  this.newlines();
34960
- this.expect("in");
34967
+ this.expect("in", true);
34961
34968
  this.newlines();
34962
34969
  const clauses = [];
34963
34970
  while (!this.is("esac")) {
34971
+ if (this.isEnd()) this.error("Expected case pattern", true);
34964
34972
  if (this.is("(")) this.advance();
34965
34973
  const patterns2 = [];
34966
34974
  while (true) {
@@ -34971,7 +34979,7 @@ var Parser4 = class {
34971
34979
  }
34972
34980
  this.expect(")");
34973
34981
  const body = this.script(/* @__PURE__ */ new Set([";;", ";&", ";;&", "esac"]));
34974
- if (![";;", ";&", ";;&", "esac"].includes(this.current.value)) this.error("Expected case terminator");
34982
+ if (![";;", ";&", ";;&", "esac"].includes(this.current.value)) this.error("Expected case terminator", true);
34975
34983
  const terminator = this.current.value;
34976
34984
  this.budget.admit();
34977
34985
  clauses.push({ patterns: patterns2, body, terminator });
@@ -34979,14 +34987,14 @@ var Parser4 = class {
34979
34987
  this.advance();
34980
34988
  this.newlines();
34981
34989
  }
34982
- this.expect("esac");
34990
+ this.expect("esac", true);
34983
34991
  command7 = { kind: "case", subject, clauses, redirects: [] };
34984
34992
  } else if (this.is("while") || this.is("until")) {
34985
34993
  const kind = this.advance().value;
34986
34994
  const condition = this.nonemptyScript(/* @__PURE__ */ new Set(["do"]));
34987
- this.expect("do");
34995
+ this.expect("do", true);
34988
34996
  const body = this.nonemptyScript(/* @__PURE__ */ new Set(["done"]));
34989
- this.expect("done");
34997
+ this.expect("done", true);
34990
34998
  command7 = { kind, condition, body, redirects: [] };
34991
34999
  } else if (this.is("for")) {
34992
35000
  this.advance();
@@ -35000,11 +35008,11 @@ var Parser4 = class {
35000
35008
  while (this.current.kind === "word") words.push(this.advance().word);
35001
35009
  }
35002
35010
  if (this.is(";") || this.is("\n")) this.advance();
35003
- else if (words) this.error("Expected for separator");
35011
+ else if (words) this.error("Expected for separator", true);
35004
35012
  this.newlines();
35005
- this.expect("do");
35013
+ this.expect("do", true);
35006
35014
  const body = this.nonemptyScript(/* @__PURE__ */ new Set(["done"]));
35007
- this.expect("done");
35015
+ this.expect("done", true);
35008
35016
  command7 = { kind: "for", name: name2, ...words ? { words } : {}, body, redirects: [] };
35009
35017
  } else if (this.is("function")) {
35010
35018
  this.advance();
@@ -35076,7 +35084,7 @@ var Parser4 = class {
35076
35084
  }
35077
35085
  nonemptyScript(stops) {
35078
35086
  const script = this.script(stops);
35079
- if (!script.lists.length) this.error("Expected nonempty compound list");
35087
+ if (!script.lists.length) this.error("Expected nonempty compound list", true);
35080
35088
  return script;
35081
35089
  }
35082
35090
  redirect() {
@@ -35146,10 +35154,21 @@ function parseShellInputUnit(source2, byteLocale2 = false, budget = new ParseBud
35146
35154
  }
35147
35155
  function parseSource(source2, depth, warnings, lineOffset, byteLocale2, budget, ordinaryBacktick = false) {
35148
35156
  budget.admit();
35157
+ const warningCount = warnings.length;
35149
35158
  const parser = new Parser4(budget, source2, depth, warnings, lineOffset, void 0, byteLocale2, false, void 0, 0, ordinaryBacktick);
35150
- const script = parser.script();
35151
- if (parser.current.kind !== "end") parser.error("Unexpected token");
35152
- return script;
35159
+ try {
35160
+ const script = parser.script(/* @__PURE__ */ new Set(), false, ordinaryBacktick);
35161
+ if (parser.current.kind !== "end") parser.error("Unexpected token");
35162
+ return script;
35163
+ } catch (error) {
35164
+ if (!(error instanceof CompoundListEofError) || warnings.length !== warningCount) throw error;
35165
+ const prefix3 = parser.completedInput;
35166
+ budget.admit(6 + (prefix3?.count ?? 0));
35167
+ const lists = prefix3?.lists.slice(0, prefix3.count) ?? [];
35168
+ const line = lineOffset + source2.split("\n").length + Number(!source2.endsWith("\n"));
35169
+ lists.push({ pipelines: [{ negate: false, commands: [{ kind: "simple", line, redirects: [], words: [{ offset: source2.length, parts: [{ kind: "compound-substitution-eof", line, quoted: true }] }] }] }], operators: [] });
35170
+ return { lists, line: prefix3?.line ?? lineOffset + 1 };
35171
+ }
35153
35172
  }
35154
35173
 
35155
35174
  // packages/safe-bash/src/shell/input.ts
@@ -42710,6 +42729,11 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
42710
42729
  }
42711
42730
  async partValue(part, state, io, hereString) {
42712
42731
  this.signal.throwIfAborted();
42732
+ if (part.kind === "compound-substitution-eof") {
42733
+ await writeDiagnostic(io.stderr, `${io.scriptName ?? "shell"}: command substitution: line ${io.diagnosticLine ?? part.line}: syntax error: unexpected end of file
42734
+ `);
42735
+ throw completedExit(2);
42736
+ }
42713
42737
  if (part.kind === "failed-parameter") throw new ExpansionFailure(`${part.source}: bad substitution`, io.diagnosticLine ?? part.line);
42714
42738
  if (part.kind === "failed-substitution") {
42715
42739
  if (state.depth >= this.budget.limits.maxSubstitutionDepth) this.budget.fail("maxSubstitutionDepth");