@poe-platform/safe-bash 0.1.749 → 0.1.750

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.
@@ -116237,6 +116237,40 @@ var BiffOutput = class {
116237
116237
  this.length += bytes.length;
116238
116238
  return at;
116239
116239
  }
116240
+ /** Keep tokens/elements intact; oversized UTF-16 array strings carry width flags. */
116241
+ continuedRecord(opcode, payload, boundaries, strings = []) {
116242
+ const at = this.length;
116243
+ let offset = 0, next = 0, stringIndex = 0;
116244
+ do {
116245
+ while (strings[stringIndex] && strings[stringIndex].end <= offset) stringIndex++;
116246
+ const continuedString = strings[stringIndex] && strings[stringIndex].start < offset;
116247
+ const prefix = continuedString ? 1 : 0;
116248
+ const maximum = Math.min(payload.length, offset + this.maximumRecord - prefix);
116249
+ let end2 = maximum;
116250
+ if (boundaries && maximum < payload.length) {
116251
+ end2 = offset;
116252
+ while (next < boundaries.length && boundaries[next] <= maximum) end2 = boundaries[next++];
116253
+ let candidate = stringIndex;
116254
+ while (strings[candidate] && strings[candidate].end <= maximum) candidate++;
116255
+ const string = strings[candidate];
116256
+ if (string && string.end - string.start + 4 > this.maximumRecord && string.start < maximum && maximum < string.end) {
116257
+ const characterEnd = maximum - (maximum - string.start) % 2;
116258
+ if (characterEnd > string.start) end2 = Math.max(end2, characterEnd);
116259
+ }
116260
+ if (end2 <= offset) throw new SsconvertError("unsupported-feature", "Excel BIFF formula token is too large");
116261
+ }
116262
+ let part = payload.subarray(offset, end2);
116263
+ if (prefix) {
116264
+ const continued = new Uint8Array(part.length + 1);
116265
+ continued[0] = 1;
116266
+ continued.set(part, 1);
116267
+ part = continued;
116268
+ }
116269
+ this.record(offset === 0 ? opcode : 60, part);
116270
+ offset = end2;
116271
+ } while (offset < payload.length);
116272
+ return at;
116273
+ }
116240
116274
  finish() {
116241
116275
  this.context.signal.throwIfAborted();
116242
116276
  const bytes = new Uint8Array(this.length);
@@ -128336,7 +128370,6 @@ var BiffFormulaWriter = class {
128336
128370
  macroNames = [];
128337
128371
  workbookIndices = /* @__PURE__ */ new Map();
128338
128372
  linkIndices = /* @__PURE__ */ new Map();
128339
- uniqueNameId = 0;
128340
128373
  relocations = [];
128341
128374
  externalBook(workbook) {
128342
128375
  let index2 = this.workbookIndices.get(workbook);
@@ -128457,6 +128490,11 @@ var BiffFormulaWriter = class {
128457
128490
  const relative = definition !== void 0;
128458
128491
  const root = definition ? parseNamedExpression(definition, this.book, parse2, () => this.context.signal.throwIfAborted()) : parse2(source, { sheet, row, column });
128459
128492
  const bytes = [], arrays = [], diagnostics = [];
128493
+ const tokenBoundaries = [], arrayBoundaries = [];
128494
+ const arrayStrings = [];
128495
+ const boundary = () => {
128496
+ if (bytes.length && tokenBoundaries.at(-1) !== bytes.length) tokenBoundaries.push(bytes.length);
128497
+ };
128460
128498
  let sheetLossReported = false;
128461
128499
  const relocations = [];
128462
128500
  const push = (part, target = bytes) => {
@@ -128499,12 +128537,14 @@ var BiffFormulaWriter = class {
128499
128537
  push([23]);
128500
128538
  push(biffString(text2, this.revision, this.context, 1));
128501
128539
  if (index2) push([8]);
128540
+ boundary();
128502
128541
  });
128503
128542
  if (chunks.length > 1) push([21]);
128504
128543
  }
128505
128544
  };
128506
128545
  const visit = (node3) => {
128507
128546
  this.context.signal.throwIfAborted();
128547
+ boundary();
128508
128548
  if (node3.kind === "literal") literal2(node3.value);
128509
128549
  else if (node3.kind === "omitted") push([22]);
128510
128550
  else if (node3.kind === "parentheses") {
@@ -128657,24 +128697,15 @@ var BiffFormulaWriter = class {
128657
128697
  push([28, 29]);
128658
128698
  return;
128659
128699
  }
128660
- if (node3.sheet !== void 0 && scope !== void 0) {
128661
- const data3 = new Uint8Array(this.revision === 8 ? 7 : 25), view2 = new DataView(data3.buffer);
128700
+ if (node3.sheet !== void 0 && scope !== void 0 && this.revision === 8) {
128701
+ const data3 = new Uint8Array(7), view2 = new DataView(data3.buffer);
128662
128702
  data3[0] = 89;
128663
128703
  const scopeIndex = this.book.sheets.indexOf(scope);
128664
- if (this.revision === 8) {
128665
- const externalIndex = this.sheetLink(void 0, scopeIndex, scopeIndex);
128666
- relocations.push({ offset: bytes.length + 1, index: externalIndex, kind: "sheet" });
128667
- view2.setUint16(1, externalIndex, true);
128668
- view2.setUint16(3, index2 + 1, true);
128669
- } else {
128670
- const externalIndex = current === scope ? this.book.sheets.length + 1 : scopeIndex;
128671
- view2.setInt16(1, -(externalIndex + 1), true);
128672
- view2.setUint16(9, 1, true);
128673
- view2.setUint16(11, index2 + 1, true);
128674
- view2.setUint16(19, 15, true);
128675
- view2.setUint32(21, ++this.uniqueNameId, true);
128676
- }
128677
- relocations.push({ offset: bytes.length + (this.revision === 8 ? 3 : 11), index: index2, kind: "name" });
128704
+ const externalIndex = this.sheetLink(void 0, scopeIndex, scopeIndex);
128705
+ relocations.push({ offset: bytes.length + 1, index: externalIndex, kind: "sheet" });
128706
+ view2.setUint16(1, externalIndex, true);
128707
+ view2.setUint16(3, index2 + 1, true);
128708
+ relocations.push({ offset: bytes.length + 3, index: index2, kind: "name" });
128678
128709
  push(data3);
128679
128710
  } else {
128680
128711
  const data3 = new Uint8Array(this.revision === 8 ? 5 : 15);
@@ -128732,12 +128763,15 @@ var BiffFormulaWriter = class {
128732
128763
  if (!columns || columns > 256 || node3.rows.length > 65536) throw new SsconvertError("unsupported-feature", "Excel BIFF array dimensions exceed limits");
128733
128764
  push([64, ...new Uint8Array(7)]);
128734
128765
  push([this.revision === 8 ? columns - 1 : columns & 255, ...words(node3.rows.length - (this.revision === 8 ? 1 : 0))], arrays);
128766
+ arrayBoundaries.push(arrays.length);
128735
128767
  for (const arrayRow of node3.rows) for (const item of arrayRow) {
128736
128768
  if (item.kind !== "literal") throw new SsconvertError("unsupported-feature", "Excel BIFF array requires literals");
128737
128769
  const value3 = item.value;
128738
128770
  if (value3.kind === "string") {
128771
+ const start = arrays.length + 4;
128739
128772
  push([2], arrays);
128740
128773
  push(biffString(value3.value, this.revision, this.context, this.revision === 8 ? 2 : 1), arrays);
128774
+ if (this.revision === 8 && arrays.length > start) arrayStrings.push({ start, end: arrays.length });
128741
128775
  } else {
128742
128776
  const data3 = new Uint8Array(9), view2 = new DataView(data3.buffer);
128743
128777
  data3[0] = value3.kind === "number" ? 1 : value3.kind === "boolean" ? 4 : value3.kind === "error" ? 16 : 0;
@@ -128746,15 +128780,23 @@ var BiffFormulaWriter = class {
128746
128780
  else if (value3.kind === "error") data3[1] = biffError(value3.value);
128747
128781
  push(data3, arrays);
128748
128782
  }
128783
+ arrayBoundaries.push(arrays.length);
128749
128784
  }
128750
128785
  }
128786
+ boundary();
128751
128787
  };
128752
128788
  visit(root);
128789
+ boundary();
128790
+ if (bytes.length > 65535)
128791
+ throw new SsconvertError("unsupported-feature", "Excel BIFF formula token length exceeds version limits");
128753
128792
  const tokens3 = new Uint8Array(bytes);
128754
128793
  for (const relocation of relocations) this.relocations.push({ ...relocation, tokens: tokens3 });
128755
128794
  return {
128756
128795
  tokens: tokens3,
128796
+ tokenBoundaries,
128757
128797
  arrays: new Uint8Array(arrays),
128798
+ arrayBoundaries,
128799
+ arrayStrings,
128758
128800
  diagnostics,
128759
128801
  nameDependencies: relocations.filter((relocation) => relocation.kind === "name").map((relocation) => relocation.index)
128760
128802
  };
@@ -129339,7 +129381,10 @@ async function writeBiffStream(book, revision2, dual, context, filepass) {
129339
129381
  if (group) {
129340
129382
  formulas.set(cell, {
129341
129383
  tokens: new Uint8Array([dataTables.has(group) ? 2 : 1, ...words(group.range.startRow, group.range.startColumn)]),
129384
+ tokenBoundaries: [5],
129342
129385
  arrays: new Uint8Array(),
129386
+ arrayBoundaries: [],
129387
+ arrayStrings: [],
129343
129388
  diagnostics: [],
129344
129389
  nameDependencies: []
129345
129390
  });
@@ -129429,8 +129474,22 @@ async function writeBiffStream(book, revision2, dual, context, filepass) {
129429
129474
  header4[3] = text2[0];
129430
129475
  view3.setUint16(4, formula3.tokens.length, true);
129431
129476
  const scope = name.sheet === void 0 ? 0 : book.sheets.findIndex((sheet) => sheet.id === name.sheet) + 1;
129432
- view3.setUint16(revision2 === 8 ? 8 : 6, scope, true);
129433
- output2.record(24, join(join(header4, text2.subarray(1)), join(formula3.tokens, formula3.arrays)));
129477
+ if (revision2 === 7 && scope) view3.setUint16(6, scope - 1, true);
129478
+ view3.setUint16(8, scope, true);
129479
+ const start = header4.length + text2.length - 1;
129480
+ output2.continuedRecord(
129481
+ 24,
129482
+ join(join(header4, text2.subarray(1)), join(formula3.tokens, formula3.arrays)),
129483
+ [
129484
+ start,
129485
+ ...formula3.tokenBoundaries.map((offset) => offset + start),
129486
+ ...formula3.arrayBoundaries.map((offset) => offset + start + formula3.tokens.length)
129487
+ ],
129488
+ formula3.arrayStrings.map((span2) => ({
129489
+ start: start + formula3.tokens.length + span2.start,
129490
+ end: start + formula3.tokens.length + span2.end
129491
+ }))
129492
+ );
129434
129493
  }
129435
129494
  if (revision2 === 8) {
129436
129495
  metadata3.global(output2);
@@ -129484,7 +129543,19 @@ async function writeBiffStream(book, revision2, dual, context, filepass) {
129484
129543
  view3.setUint16(12, formula3.tokens.length, true);
129485
129544
  data3.set(formula3.tokens, 14);
129486
129545
  data3.set(formula3.arrays, 14 + formula3.tokens.length);
129487
- output2.record(545, data3);
129546
+ output2.continuedRecord(
129547
+ 545,
129548
+ data3,
129549
+ [
129550
+ 14,
129551
+ ...formula3.tokenBoundaries.map((offset) => offset + 14),
129552
+ ...formula3.arrayBoundaries.map((offset) => offset + 14 + formula3.tokens.length)
129553
+ ],
129554
+ formula3.arrayStrings.map((span2) => ({
129555
+ start: 14 + formula3.tokens.length + span2.start,
129556
+ end: 14 + formula3.tokens.length + span2.end
129557
+ }))
129558
+ );
129488
129559
  }
129489
129560
  }
129490
129561
  const cached = cell.cachedResult ?? cell.value;
@@ -129566,7 +129637,19 @@ async function writeCell(output2, cell, xf, revision2, strings, context, formula
129566
129637
  view2.setUint16(20, formula3.tokens.length, true);
129567
129638
  data3.set(formula3.tokens, 22);
129568
129639
  data3.set(formula3.arrays, 22 + formula3.tokens.length);
129569
- output2.record(6, data3);
129640
+ output2.continuedRecord(
129641
+ 6,
129642
+ data3,
129643
+ [
129644
+ 22,
129645
+ ...formula3.tokenBoundaries.map((offset) => offset + 22),
129646
+ ...formula3.arrayBoundaries.map((offset) => offset + 22 + formula3.tokens.length)
129647
+ ],
129648
+ formula3.arrayStrings.map((span2) => ({
129649
+ start: 22 + formula3.tokens.length + span2.start,
129650
+ end: 22 + formula3.tokens.length + span2.end
129651
+ }))
129652
+ );
129570
129653
  return;
129571
129654
  }
129572
129655
  if (value3.kind === "number") {
@@ -130487,6 +130570,33 @@ async function readBiff(borrowed, context, encoding) {
130487
130570
  while (records[index2 + 1]?.opcode === 60) parts.push(records[++index2].data);
130488
130571
  return { parts, next: index2 };
130489
130572
  };
130573
+ const formulaParts = (index2, offset, length) => {
130574
+ const first = records[index2].data;
130575
+ let tokens3;
130576
+ if (offset + length <= first.bytes.length) {
130577
+ tokens3 = first.slice(offset, length);
130578
+ offset += length;
130579
+ } else {
130580
+ accountFormulaWork(length);
130581
+ tokens3 = new Uint8Array(length);
130582
+ let written = 0;
130583
+ while (written < length) {
130584
+ context.signal.throwIfAborted();
130585
+ const part = records[index2].data;
130586
+ const count = Math.min(length - written, part.bytes.length - offset);
130587
+ tokens3.set(part.slice(offset, count), written);
130588
+ written += count;
130589
+ offset += count;
130590
+ if (written < length) {
130591
+ if (records[index2 + 1]?.opcode !== 60) invalidBiff("truncated formula tokens/CONTINUE");
130592
+ index2++;
130593
+ offset = 0;
130594
+ }
130595
+ }
130596
+ }
130597
+ const extra = stringParts(index2, offset);
130598
+ return { tokens: tokens3, arrays: extra.parts, next: extra.next };
130599
+ };
130490
130600
  for (let index2 = 0; index2 < records.length; index2++) {
130491
130601
  context.signal.throwIfAborted();
130492
130602
  const record7 = records[index2], data3 = record7.data, opcode = record7.opcode;
@@ -130685,13 +130795,12 @@ async function readBiff(borrowed, context, encoding) {
130685
130795
  const name = accountText(ver >= 8 ? cursor.unicode(length).text : cursor.legacy(length));
130686
130796
  const end2 = 7 + cursor.consumedBytes;
130687
130797
  const tokenLength = end2 + 2 <= data3.bytes.length ? data3.u16(end2) : 0;
130688
- const tokens3 = tokenLength ? data3.slice(end2 + 2, tokenLength) : new Uint8Array();
130798
+ const formula4 = tokenLength ? formulaParts(index2, end2 + 2, tokenLength) : { tokens: new Uint8Array(), arrays: [], next: index2 };
130689
130799
  const legacyLink = (sheet?.legacyExternalLinks ?? legacyExternalLinks).get((sheet?.legacyExternalSheets ?? legacyExternalSheets).length - 1);
130690
130800
  const table2 = ver >= 8 ? supbooks.at(-1)?.names : legacyLink?.names;
130691
130801
  if (!table2) invalidBiff("EXTERNNAME without workbook link");
130692
- const arrays = tokenLength ? stringParts(index2, end2 + 2 + tokenLength) : { parts: [], next: index2 };
130693
- index2 = arrays.next;
130694
- table2.push({ name, sheetIndex: data3.u16(2), tokens: tokens3, arrays: arrays.parts, revision: ver, codepage, supported: flags === 0, record: record7 });
130802
+ index2 = formula4.next;
130803
+ table2.push({ name, sheetIndex: data3.u16(2), tokens: formula4.tokens, arrays: formula4.arrays, revision: ver, codepage, supported: flags === 0, record: record7 });
130695
130804
  const addin = ver >= 8 ? supbooks.at(-1)?.kind === "addin" : legacyLink?.addin;
130696
130805
  const externalIdentity = (ver >= 8 ? supbooks.at(-1)?.workbook : legacyLink?.workbook) !== void 0 && flags === 0;
130697
130806
  if (!addin || flags !== 0) await retain(record7, sheet?.unsupportedRecords ?? unsupported9, !externalIdentity);
@@ -130721,7 +130830,9 @@ async function readBiff(borrowed, context, encoding) {
130721
130830
  }
130722
130831
  if (opcode === 24 || opcode === 536) {
130723
130832
  const flags = data3.u16(0), length = data3.u8(3), tokenLength = ver === 2 ? data3.u8(4) : data3.u16(4);
130724
- const start = ver >= 7 ? 14 : ver >= 3 ? 6 : 5, sheetIndex = ver >= 8 ? data3.u16(8) : ver >= 7 ? data3.u16(6) : 0;
130833
+ const start = ver >= 7 ? 14 : ver >= 3 ? 6 : 5;
130834
+ const scopeIsWorksheet = ver >= 8 || ver >= 7 && data3.u16(8) !== 0;
130835
+ const sheetIndex = scopeIsWorksheet ? data3.u16(8) : ver >= 7 ? data3.u16(6) : 0;
130725
130836
  const cursor = new BiffStrings([new Binary(data3.slice(start, data3.bytes.length - start))], context, codepage);
130726
130837
  let name;
130727
130838
  if (flags & 32 && length) {
@@ -130745,10 +130856,20 @@ async function readBiff(borrowed, context, encoding) {
130745
130856
  ][builtin];
130746
130857
  name = (base ?? `_BIFF_BUILTIN_${builtin}`) + text2.slice(1);
130747
130858
  } else name = ver >= 8 ? cursor.unicode(length).text : cursor.legacy(length);
130748
- const tokens3 = data3.slice(start + cursor.consumedBytes, tokenLength);
130749
- const arrays = stringParts(index2, start + cursor.consumedBytes + tokenLength);
130750
- index2 = arrays.next;
130751
- names2.push({ name: accountText(name), flags, tokens: tokens3, arrays: arrays.parts, sheetIndex, revision: ver, codepage, record: record7, ...sheet ? { owner: sheet } : {} });
130859
+ const formula4 = formulaParts(index2, start + cursor.consumedBytes, tokenLength);
130860
+ index2 = formula4.next;
130861
+ names2.push({
130862
+ name: accountText(name),
130863
+ flags,
130864
+ tokens: formula4.tokens,
130865
+ arrays: formula4.arrays,
130866
+ sheetIndex,
130867
+ scopeIsWorksheet,
130868
+ revision: ver,
130869
+ codepage,
130870
+ record: record7,
130871
+ ...sheet ? { owner: sheet } : {}
130872
+ });
130752
130873
  continue;
130753
130874
  }
130754
130875
  if (ignoredOpcodes.has(opcode)) continue;
@@ -130822,13 +130943,15 @@ async function readBiff(borrowed, context, encoding) {
130822
130943
  if (kind > 3) invalidBiff("invalid formula cache tag");
130823
130944
  }
130824
130945
  lastFormula = addCell(sheet, data3, value3, { cachedResult: value3, formulaDirty: !!(data3.u16(14) & 3) });
130825
- lastFormula.tokens = data3.slice(tokenStart, tokenLength);
130826
- const arrays = stringParts(index2, tokenStart + tokenLength);
130827
- index2 = arrays.next;
130828
- lastFormula.arrays = arrays.parts;
130946
+ const formula4 = formulaParts(index2, tokenStart, tokenLength);
130947
+ index2 = formula4.next;
130948
+ lastFormula.tokens = formula4.tokens;
130949
+ lastFormula.arrays = formula4.arrays;
130829
130950
  const nextOpcode = records[index2 + 1]?.opcode;
130830
130951
  const groupFollows = nextOpcode === 1212 || nextOpcode === 33 || nextOpcode === 545 || nextOpcode === 54 || nextOpcode === 55 || nextOpcode === 566;
130831
- const stringOpcode = records[index2 + (groupFollows ? 2 : 1)]?.opcode;
130952
+ let stringIndex = index2 + (groupFollows ? 2 : 1);
130953
+ if (groupFollows) while (records[stringIndex]?.opcode === 60) stringIndex++;
130954
+ const stringOpcode = records[stringIndex]?.opcode;
130832
130955
  if (stringCache2 && stringOpcode !== 7 && stringOpcode !== 519) {
130833
130956
  const error2 = { kind: "error", value: "MISSING STRING" };
130834
130957
  lastFormula.cell = { ...lastFormula.cell, value: error2, cachedResult: error2 };
@@ -130868,10 +130991,17 @@ async function readBiff(borrowed, context, encoding) {
130868
130991
  }
130869
130992
  const kind = opcode === 1212 ? "shared" : "array";
130870
130993
  const start = kind === "shared" ? 10 : ver === 2 ? 8 : ver <= 4 ? 10 : 14;
130871
- const tokens3 = data3.slice(start, ver === 2 && kind === "array" ? data3.u8(start - 1) : data3.u16(start - 2));
130872
- const arrays = stringParts(index2, start + tokens3.length);
130873
- index2 = arrays.next;
130874
- sheet.groups.push({ id: `biff-${sheet.offset}-${record7.offset}`, kind, range: range3, tokens: tokens3, arrays: arrays.parts, keyRow: lastFormula.cell.row, keyColumn: lastFormula.cell.column });
130994
+ const formula4 = formulaParts(index2, start, ver === 2 && kind === "array" ? data3.u8(start - 1) : data3.u16(start - 2));
130995
+ index2 = formula4.next;
130996
+ sheet.groups.push({
130997
+ id: `biff-${sheet.offset}-${record7.offset}`,
130998
+ kind,
130999
+ range: range3,
131000
+ tokens: formula4.tokens,
131001
+ arrays: formula4.arrays,
131002
+ keyRow: lastFormula.cell.row,
131003
+ keyColumn: lastFormula.cell.column
131004
+ });
130875
131005
  continue;
130876
131006
  }
130877
131007
  if (opcode === 7 || opcode === 519) {
@@ -130979,7 +131109,7 @@ async function readBiff(borrowed, context, encoding) {
130979
131109
  const localSheets = sheets.map((sheet) => sheet.name);
130980
131110
  const nameSheets = names2.map((name) => {
130981
131111
  if (!name.sheetIndex) return void 0;
130982
- return (name.revision >= 8 ? sheets[name.sheetIndex - 1]?.name : (name.owner?.legacyExternalSheets ?? legacyExternalSheets)[name.sheetIndex - 1]) ?? void 0;
131112
+ return (name.scopeIsWorksheet ? sheets[name.sheetIndex - 1]?.name : (name.owner?.legacyExternalSheets ?? legacyExternalSheets)[name.sheetIndex - 1]) ?? void 0;
130983
131113
  });
130984
131114
  const externalNameTables = /* @__PURE__ */ new Map();
130985
131115
  const formulaNames = names2.map((name) => name.name);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poe-platform/safe-bash",
3
- "version": "0.1.749",
3
+ "version": "0.1.750",
4
4
  "description": "Extensible virtual shell with pluggable filesystems and streaming commands",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -645,7 +645,7 @@
645
645
  "access": "public"
646
646
  },
647
647
  "dependencies": {
648
- "@poe-platform/safe-fs": "0.1.749",
648
+ "@poe-platform/safe-fs": "0.1.750",
649
649
  "pdf-lib": "1.17.1",
650
650
  "@types/node": "^25.2.2",
651
651
  "pako": "3.0.1",