@poe-platform/safe-bash 0.1.93 → 0.1.95
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 +72 -25
- package/dist/safe-bash/browser.js.map +3 -3
- package/dist/safe-bash/shell/parser.d.ts +3 -2
- package/dist/safe-bash/shell/parser.d.ts.map +1 -1
- package/dist/safe-bash/shell/parser.js +18 -21
- package/dist/safe-bash/shell/parser.js.map +1 -1
- package/dist/safe-bash/shell/runtime.d.ts.map +1 -1
- package/dist/safe-bash/shell/runtime.js +14 -6
- 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 +4 -2
- package/dist/safe-bash/shell/shell.js.map +1 -1
- package/dist/safe-bash/shell/source-line-index.d.ts +10 -0
- package/dist/safe-bash/shell/source-line-index.d.ts.map +1 -0
- package/dist/safe-bash/shell/source-line-index.js +41 -0
- package/dist/safe-bash/shell/source-line-index.js.map +1 -0
- package/package.json +2 -2
|
@@ -5398,6 +5398,47 @@ var ParseBudget = class {
|
|
|
5398
5398
|
}
|
|
5399
5399
|
};
|
|
5400
5400
|
|
|
5401
|
+
// packages/safe-bash/src/shell/source-line-index.ts
|
|
5402
|
+
init_platform();
|
|
5403
|
+
var SourceLineIndex = class {
|
|
5404
|
+
constructor(source, budget) {
|
|
5405
|
+
this.budget = budget;
|
|
5406
|
+
this.#source = source;
|
|
5407
|
+
}
|
|
5408
|
+
budget;
|
|
5409
|
+
#source;
|
|
5410
|
+
#scanned = 0;
|
|
5411
|
+
#newlines;
|
|
5412
|
+
get source() {
|
|
5413
|
+
return this.#source;
|
|
5414
|
+
}
|
|
5415
|
+
append(source) {
|
|
5416
|
+
this.#source += source;
|
|
5417
|
+
}
|
|
5418
|
+
lineAt(position) {
|
|
5419
|
+
this.budget.admit(0);
|
|
5420
|
+
if (!Number.isSafeInteger(position) || position < 0 || position > this.#source.length) throw new RangeError("Invalid source line position");
|
|
5421
|
+
if (position === 0 || position === 1 && this.#source[0] !== "\n") return 1;
|
|
5422
|
+
while (this.#scanned < position) {
|
|
5423
|
+
if (this.#scanned % 1024 === 0) this.budget.admit();
|
|
5424
|
+
if (this.#source.charCodeAt(this.#scanned) === 10) {
|
|
5425
|
+
this.budget.admit();
|
|
5426
|
+
(this.#newlines ??= []).push(this.#scanned);
|
|
5427
|
+
}
|
|
5428
|
+
this.#scanned++;
|
|
5429
|
+
}
|
|
5430
|
+
this.budget.admit(0);
|
|
5431
|
+
let low = 0;
|
|
5432
|
+
let high = this.#newlines?.length ?? 0;
|
|
5433
|
+
while (low < high) {
|
|
5434
|
+
const middle = low + Math.floor((high - low) / 2);
|
|
5435
|
+
if (this.#newlines[middle] < position) low = middle + 1;
|
|
5436
|
+
else high = middle;
|
|
5437
|
+
}
|
|
5438
|
+
return low + 1;
|
|
5439
|
+
}
|
|
5440
|
+
};
|
|
5441
|
+
|
|
5401
5442
|
// packages/safe-bash/src/shell/arithmetic.ts
|
|
5402
5443
|
init_platform();
|
|
5403
5444
|
var ArithmeticFailure = class extends Error {
|
|
@@ -6169,7 +6210,7 @@ function printedSimpleLines(lists, separators, budget) {
|
|
|
6169
6210
|
var IncompleteShellInput = class extends Error {
|
|
6170
6211
|
};
|
|
6171
6212
|
var Lexer = class {
|
|
6172
|
-
constructor(budget, source, depth, warnings = [], lineOffset = 0, byteLocale2 = false, documentLine, partial = false) {
|
|
6213
|
+
constructor(budget, source, depth, warnings = [], lineOffset = 0, byteLocale2 = false, documentLine, partial = false, lineIndex = new SourceLineIndex(source, budget), sourceOffset = 0) {
|
|
6173
6214
|
this.budget = budget;
|
|
6174
6215
|
this.source = source;
|
|
6175
6216
|
this.depth = depth;
|
|
@@ -6178,8 +6219,9 @@ var Lexer = class {
|
|
|
6178
6219
|
this.byteLocale = byteLocale2;
|
|
6179
6220
|
this.documentLine = documentLine;
|
|
6180
6221
|
this.partial = partial;
|
|
6222
|
+
this.lineIndex = lineIndex;
|
|
6223
|
+
this.sourceOffset = sourceOffset;
|
|
6181
6224
|
if (depth > 64) throw new ShellSyntaxError("Syntax nesting exceeds 64", 0);
|
|
6182
|
-
for (let offset = source.indexOf("\n"); offset !== -1; offset = source.indexOf("\n", offset + 1)) this.newlineOffsets.push(offset);
|
|
6183
6225
|
}
|
|
6184
6226
|
budget;
|
|
6185
6227
|
source;
|
|
@@ -6189,6 +6231,8 @@ var Lexer = class {
|
|
|
6189
6231
|
byteLocale;
|
|
6190
6232
|
documentLine;
|
|
6191
6233
|
partial;
|
|
6234
|
+
lineIndex;
|
|
6235
|
+
sourceOffset;
|
|
6192
6236
|
position = 0;
|
|
6193
6237
|
operandDepth = 0;
|
|
6194
6238
|
printedNewlineReduction = 0;
|
|
@@ -6197,16 +6241,8 @@ var Lexer = class {
|
|
|
6197
6241
|
conditional = false;
|
|
6198
6242
|
conditionalPattern;
|
|
6199
6243
|
documents = [];
|
|
6200
|
-
newlineOffsets = [];
|
|
6201
6244
|
lineAt(position) {
|
|
6202
|
-
|
|
6203
|
-
let high = this.newlineOffsets.length;
|
|
6204
|
-
while (low < high) {
|
|
6205
|
-
const middle = low + Math.floor((high - low) / 2);
|
|
6206
|
-
if (this.newlineOffsets[middle] < position) low = middle + 1;
|
|
6207
|
-
else high = middle;
|
|
6208
|
-
}
|
|
6209
|
-
return this.lineOffset + low + 1;
|
|
6245
|
+
return this.lineOffset + this.lineIndex.lineAt(this.sourceOffset + position) - this.lineIndex.lineAt(this.sourceOffset) + 1;
|
|
6210
6246
|
}
|
|
6211
6247
|
error(message2, unclosedQuote) {
|
|
6212
6248
|
throw new ShellSyntaxError(message2, this.position, 2, void 0, unclosedQuote);
|
|
@@ -6595,7 +6631,7 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
6595
6631
|
let script;
|
|
6596
6632
|
try {
|
|
6597
6633
|
this.budget.admit();
|
|
6598
|
-
nested = new Parser(this.budget, this.source.slice(start), this.depth + this.operandDepth + 1, this.warnings, this.lineAt(start) - 1, void 0, this.byteLocale);
|
|
6634
|
+
nested = new Parser(this.budget, this.source.slice(start), this.depth + this.operandDepth + 1, this.warnings, this.lineAt(start) - 1, void 0, this.byteLocale, false, this.lineIndex, this.sourceOffset + start);
|
|
6599
6635
|
script = nested.script(/* @__PURE__ */ new Set([")"]));
|
|
6600
6636
|
} catch (error) {
|
|
6601
6637
|
if (this.documentLine !== void 0 && error instanceof ShellSyntaxError && !/nesting|exceeds/u.test(error.reason)) throw this.documentSubstitutionError(this.source.slice(start), error);
|
|
@@ -6676,11 +6712,11 @@ shell: command substitution: line ${line}: \`${sourceLine}'
|
|
|
6676
6712
|
}
|
|
6677
6713
|
};
|
|
6678
6714
|
var Parser = class {
|
|
6679
|
-
constructor(budget, source, depth, warnings = [], lineOffset = 0, position, byteLocale2 = false, partial = false) {
|
|
6715
|
+
constructor(budget, source, depth, warnings = [], lineOffset = 0, position, byteLocale2 = false, partial = false, lineIndex = new SourceLineIndex(source, budget), sourceOffset = 0) {
|
|
6680
6716
|
this.budget = budget;
|
|
6681
6717
|
if (position === void 0 && depth === 0 && source.includes("\0")) throw new ShellSyntaxError("NUL bytes are not valid shell source", source.indexOf("\0"));
|
|
6682
6718
|
budget.admit();
|
|
6683
|
-
this.lexer = new Lexer(budget, source, depth, warnings, lineOffset, byteLocale2, void 0, partial);
|
|
6719
|
+
this.lexer = new Lexer(budget, source, depth, warnings, lineOffset, byteLocale2, void 0, partial, lineIndex, sourceOffset);
|
|
6684
6720
|
this.lexer.position = position ?? 0;
|
|
6685
6721
|
this.current = this.lexer.next();
|
|
6686
6722
|
}
|
|
@@ -7038,10 +7074,11 @@ function* hereDocumentWords(document, line, byteLocale2, warnings, budget = new
|
|
|
7038
7074
|
yield* new Lexer(budget, document.body, document.depth, warnings, line - 1, byteLocale2, line).documentWords();
|
|
7039
7075
|
}
|
|
7040
7076
|
}
|
|
7041
|
-
function parseShellUnit(source, position = 0, byteLocale2 = false, budget = new ParseBudget()) {
|
|
7077
|
+
function parseShellUnit(source, position = 0, byteLocale2 = false, budget = new ParseBudget(), lineIndex = new SourceLineIndex(source, budget)) {
|
|
7042
7078
|
const warnings = [];
|
|
7043
7079
|
budget.admit();
|
|
7044
|
-
|
|
7080
|
+
if (lineIndex.source !== source || lineIndex.budget !== budget) throw new TypeError("Source line index belongs to a different source or parse budget");
|
|
7081
|
+
const parser = new Parser(budget, source, 0, warnings, 0, position, byteLocale2, false, lineIndex);
|
|
7045
7082
|
const script = parser.script(/* @__PURE__ */ new Set(), true);
|
|
7046
7083
|
const next = parser.current.end;
|
|
7047
7084
|
const nul = source.indexOf("\0", position);
|
|
@@ -7049,11 +7086,12 @@ function parseShellUnit(source, position = 0, byteLocale2 = false, budget = new
|
|
|
7049
7086
|
budget.admit(2);
|
|
7050
7087
|
return { script: { ...script, ...warnings.length ? { warnings } : {} }, next };
|
|
7051
7088
|
}
|
|
7052
|
-
function parseShellInputUnit(source, byteLocale2 = false, budget = new ParseBudget()) {
|
|
7089
|
+
function parseShellInputUnit(source, byteLocale2 = false, budget = new ParseBudget(), lineIndex = new SourceLineIndex(source, budget)) {
|
|
7053
7090
|
const warnings = [];
|
|
7054
7091
|
try {
|
|
7055
7092
|
budget.admit();
|
|
7056
|
-
|
|
7093
|
+
if (lineIndex.source !== source || lineIndex.budget !== budget) throw new TypeError("Source line index belongs to a different source or parse budget");
|
|
7094
|
+
const parser = new Parser(budget, source, 0, warnings, 0, 0, byteLocale2, true, lineIndex);
|
|
7057
7095
|
const script = parser.script(/* @__PURE__ */ new Set(), true);
|
|
7058
7096
|
budget.admit(2);
|
|
7059
7097
|
return { script: { ...script, ...warnings.length ? { warnings } : {} }, next: parser.current.end };
|
|
@@ -13424,12 +13462,13 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
13424
13462
|
return error.exitCode;
|
|
13425
13463
|
}
|
|
13426
13464
|
async runCommandString(source, state, io) {
|
|
13465
|
+
const lineIndex = new SourceLineIndex(source, this.budget.parsing);
|
|
13427
13466
|
let position = 0;
|
|
13428
13467
|
let status = 0;
|
|
13429
13468
|
try {
|
|
13430
13469
|
do {
|
|
13431
13470
|
this.signal.throwIfAborted();
|
|
13432
|
-
const unit = parseShellUnit(source, position, byteLocale(state.variables), this.budget.parsing);
|
|
13471
|
+
const unit = parseShellUnit(source, position, byteLocale(state.variables), this.budget.parsing, lineIndex);
|
|
13433
13472
|
for (const warning of unit.script.warnings ?? []) await writeText(io.stderr, `${io.scriptName}: warning: ${warning}
|
|
13434
13473
|
`);
|
|
13435
13474
|
if (unit.script.lists.length) {
|
|
@@ -13455,6 +13494,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
13455
13494
|
}
|
|
13456
13495
|
async runStandardInput(input3, state, io) {
|
|
13457
13496
|
let source = "";
|
|
13497
|
+
let lineIndex = new SourceLineIndex(source, this.budget.parsing);
|
|
13458
13498
|
let offset = 0;
|
|
13459
13499
|
let status = 0;
|
|
13460
13500
|
let lines3 = 0;
|
|
@@ -13463,10 +13503,13 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
13463
13503
|
this.signal.throwIfAborted();
|
|
13464
13504
|
const bytes2 = await input3.sourceLine();
|
|
13465
13505
|
const eof = bytes2 === void 0;
|
|
13466
|
-
if (bytes2)
|
|
13506
|
+
if (bytes2) {
|
|
13507
|
+
lineIndex.append(this.sourceText(bytes2, io.scriptName ?? "shell"));
|
|
13508
|
+
source = lineIndex.source;
|
|
13509
|
+
}
|
|
13467
13510
|
const unitIO = { ...io, diagnosticOffset: offset };
|
|
13468
13511
|
try {
|
|
13469
|
-
const unit = eof ? parseShellUnit(source, 0, byteLocale(state.variables), this.budget.parsing) : parseShellInputUnit(source, byteLocale(state.variables), this.budget.parsing);
|
|
13512
|
+
const unit = eof ? parseShellUnit(source, 0, byteLocale(state.variables), this.budget.parsing, lineIndex) : parseShellInputUnit(source, byteLocale(state.variables), this.budget.parsing, lineIndex);
|
|
13470
13513
|
if (unit) {
|
|
13471
13514
|
for (const warning of unit.script.warnings ?? []) await writeText(io.stderr, `${io.scriptName}: warning: ${warning}
|
|
13472
13515
|
`);
|
|
@@ -13477,6 +13520,7 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
13477
13520
|
}
|
|
13478
13521
|
offset += source.slice(0, unit.next).split("\n").length - 1;
|
|
13479
13522
|
source = source.slice(unit.next);
|
|
13523
|
+
lineIndex = new SourceLineIndex(source, this.budget.parsing);
|
|
13480
13524
|
}
|
|
13481
13525
|
} catch (error) {
|
|
13482
13526
|
if (!(error instanceof ShellSyntaxError)) throw error;
|
|
@@ -13726,11 +13770,12 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
13726
13770
|
}
|
|
13727
13771
|
if (direct && environmentInterpreter) return this.envShebang(context, state, io, environmentInterpreter[1], target, args, { path, source });
|
|
13728
13772
|
const units = [];
|
|
13773
|
+
const lineIndex = new SourceLineIndex(source, this.budget.parsing);
|
|
13729
13774
|
try {
|
|
13730
13775
|
let position = 0;
|
|
13731
13776
|
do {
|
|
13732
13777
|
this.signal.throwIfAborted();
|
|
13733
|
-
const unit = parseShellUnit(source, position, byteLocale(context.env), this.budget.parsing);
|
|
13778
|
+
const unit = parseShellUnit(source, position, byteLocale(context.env), this.budget.parsing, lineIndex);
|
|
13734
13779
|
units.push(unit.script);
|
|
13735
13780
|
position = unit.next;
|
|
13736
13781
|
} while (position < source.length);
|
|
@@ -13757,13 +13802,14 @@ ${prefix2} line ${offset + line}: \`${source.split("\n")[line - 1] ?? ""}'
|
|
|
13757
13802
|
return status;
|
|
13758
13803
|
}
|
|
13759
13804
|
async runCurrentText(source, state, io, fatalSyntax, syntaxName) {
|
|
13805
|
+
const lineIndex = new SourceLineIndex(source, this.budget.parsing);
|
|
13760
13806
|
let position = 0;
|
|
13761
13807
|
let status = 0;
|
|
13762
13808
|
let executed = false;
|
|
13763
13809
|
try {
|
|
13764
13810
|
do {
|
|
13765
13811
|
this.signal.throwIfAborted();
|
|
13766
|
-
const unit = parseShellUnit(source, position, byteLocale(state.variables), this.budget.parsing);
|
|
13812
|
+
const unit = parseShellUnit(source, position, byteLocale(state.variables), this.budget.parsing, lineIndex);
|
|
13767
13813
|
for (const warning of unit.script.warnings ?? []) await writeText(io.stderr, `${io.scriptName ?? "shell"}: warning: ${warning}
|
|
13768
13814
|
`);
|
|
13769
13815
|
if (unit.script.lists.length) {
|
|
@@ -16160,7 +16206,8 @@ var Shell = class {
|
|
|
16160
16206
|
let failed = false;
|
|
16161
16207
|
try {
|
|
16162
16208
|
try {
|
|
16163
|
-
|
|
16209
|
+
const lineIndex = new SourceLineIndex(source, budget.parsing);
|
|
16210
|
+
let unit = parseShellUnit(source, 0, byteLocale({ ...this.#options.env, ...options3.env }), budget.parsing, lineIndex);
|
|
16164
16211
|
stdin = new ShellInput(typeof options3.stdin === "string" || options3.stdin instanceof Uint8Array ? toByteSource(options3.stdin) : options3.stdin ?? toByteSource(""), budget);
|
|
16165
16212
|
io.stdin = stdin;
|
|
16166
16213
|
await interruptible(this.#ready, budget.signal);
|
|
@@ -16217,7 +16264,7 @@ var Shell = class {
|
|
|
16217
16264
|
}
|
|
16218
16265
|
if (unit.next >= source.length) break;
|
|
16219
16266
|
budget.signal.throwIfAborted();
|
|
16220
|
-
unit = parseShellUnit(source, unit.next, byteLocale(state.variables), budget.parsing);
|
|
16267
|
+
unit = parseShellUnit(source, unit.next, byteLocale(state.variables), budget.parsing, lineIndex);
|
|
16221
16268
|
}
|
|
16222
16269
|
} catch (error) {
|
|
16223
16270
|
if (!(error instanceof ShellSyntaxError)) throw error;
|