@poe-platform/safe-bash 0.1.816 → 0.1.817
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/pdf-ast/content/evaluator.d.ts +4 -0
- package/dist/pdf-ast/cos/value-parser.d.ts +2 -0
- package/dist/pdf-ast/fonts/resolve.d.ts +5 -1
- package/dist/pdf-ast/index.js +172 -165
- package/dist/safe-bash/command-chunks/biff-KLS4T7FP-UO3CXFFF.js +5581 -0
- package/dist/safe-bash/command-chunks/chunk-2J4OQT3F.js +153 -0
- package/dist/safe-bash/command-chunks/{chunk-K7VDCBXW.js → chunk-ABL2DPJI.js} +20 -20
- package/dist/safe-bash/command-chunks/{chunk-RINR7XPR.js → chunk-E64ZI2YB.js} +121 -4
- package/dist/safe-bash/command-chunks/{chunk-GEDO5V32.js → chunk-FSG6UC2N.js} +243 -105
- package/dist/safe-bash/command-chunks/{chunk-4QEJPP3K.js → chunk-S5X7PBO4.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-IHLZ6HNQ.js → chunk-TSKJNCKD.js} +3 -2
- package/dist/safe-bash/command-chunks/{chunk-DBZCTL7C.js → chunk-UYZ6EFZE.js} +20 -18
- package/dist/safe-bash/command-chunks/{chunk-B2C3UPJS.js → chunk-W42SUPD6.js} +13 -1
- package/dist/safe-bash/command-chunks/chunk-ZHHALBM7.js +398 -0
- package/dist/safe-bash/command-chunks/{command-engine-GHE6QUHU.js → command-engine-2QXVRRH3.js} +8 -4
- package/dist/safe-bash/command-chunks/{engine-RG6HQCCB-FXYZS264.js → engine-T4GP6QOK-ECFKMR5V.js} +1 -1
- package/dist/safe-bash/command-chunks/odf-SL5TG4B3-XI3FNOTN.js +3041 -0
- package/dist/safe-bash/command-chunks/{xlsx-RE54MFCS-IQ6OXXKK.js → xlsx-RE54MFCS-4UZ5W3U7.js} +1 -1
- package/dist/safe-bash-command-apply-patch/apply.js +1 -1
- package/dist/safe-bash-command-apply-patch/index.js +1 -1
- package/dist/safe-bash-command-csvkit/index.js +1 -1
- package/dist/safe-bash-command-diff/diff.js +1 -1
- package/dist/safe-bash-command-diff/index.js +1 -1
- package/dist/safe-bash-command-pptx/engine.js +1 -1
- package/dist/safe-bash-command-ssconvert/index.js +5 -5
- package/dist/safe-bash-presentation-engine/index.js +1 -1
- package/dist/safe-bash-presentation-engine/retained-tags.d.ts +20 -0
- package/dist/safe-bash-presentation-engine/tags.d.ts +2 -0
- package/dist/safe-bash-presentation-engine/tags.js +11 -3
- package/dist/safe-bash-xml-engine/document.js +2 -2
- package/dist/safe-bash-xml-engine/index.js +2 -2
- package/dist/safe-bash-xml-engine/stored-document.d.ts +2 -0
- package/dist/safe-bash-xml-engine/stored-document.js +1 -1
- package/dist/safe-bash-xml-engine/stored-evaluate.js +2 -2
- package/dist/safe-bash-xml-engine/stored-namespaces.d.ts +21 -0
- package/dist/safe-bash-zip-engine/zip/safety.js +1 -1
- package/dist/safe-bash-zip-engine/zip/volumes.js +1 -1
- package/dist/spreadsheet-format-xls/biff-properties-merge.js +3 -3
- package/dist/spreadsheet-format-xls/biff-properties.d.ts +4 -2
- package/dist/spreadsheet-format-xls/biff-properties.js +141 -122
- package/dist/spreadsheet-format-xls/biff-property-names.d.ts +24 -0
- package/dist/spreadsheet-format-xls/biff-property-names.js +167 -0
- package/dist/xlsx-ast/comment-geometry.js +1 -1
- package/package.json +3 -2
- package/dist/safe-bash/command-chunks/biff-UBP2BZLK-JPODPKS3.js +0 -5448
- package/dist/safe-bash/command-chunks/chunk-O2HNOQQG.js +0 -161
- package/dist/safe-bash/command-chunks/chunk-ZUP5TBRG.js +0 -99
- package/dist/safe-bash/command-chunks/odf-3EA3EVSD-7B5GVNTC.js +0 -3097
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
execute
|
|
3
|
-
} from "../safe-bash/command-chunks/chunk-
|
|
3
|
+
} from "../safe-bash/command-chunks/chunk-W42SUPD6.js";
|
|
4
4
|
import "../safe-bash/command-chunks/chunk-SU26FZLJ.js";
|
|
5
5
|
import "../safe-bash/command-chunks/chunk-66QPYWEF.js";
|
|
6
6
|
import "../safe-bash/command-chunks/chunk-5HUICAWD.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "../safe-bash/command-chunks/chunk-
|
|
1
|
+
import "../safe-bash/command-chunks/chunk-S5X7PBO4.js";
|
|
2
2
|
import "../safe-bash/command-chunks/chunk-ILRQMDY4.js";
|
|
3
3
|
import "../safe-bash/command-chunks/chunk-37XCUS43.js";
|
|
4
4
|
import "../safe-bash/command-chunks/chunk-XRIYRWLW.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
diffCommand
|
|
3
|
-
} from "../safe-bash/command-chunks/chunk-
|
|
3
|
+
} from "../safe-bash/command-chunks/chunk-FSG6UC2N.js";
|
|
4
4
|
import "../safe-bash/command-chunks/chunk-QFFJN22S.js";
|
|
5
5
|
import "../safe-bash/command-chunks/chunk-AHZ7UGNB.js";
|
|
6
6
|
import "../safe-bash/command-chunks/chunk-VXIC7SS3.js";
|
|
@@ -27,7 +27,7 @@ function createPptxCommandEngine(settings = {}) {
|
|
|
27
27
|
};
|
|
28
28
|
return Object.freeze({
|
|
29
29
|
async execute(request) {
|
|
30
|
-
const mod = await (cachedPptxEngineMod ??= import("../safe-bash/command-chunks/command-engine-
|
|
30
|
+
const mod = await (cachedPptxEngineMod ??= import("../safe-bash/command-chunks/command-engine-2QXVRRH3.js"));
|
|
31
31
|
return mod.createPptxCommandEngine(ownedSettings).execute(request);
|
|
32
32
|
}
|
|
33
33
|
});
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
gt,
|
|
11
11
|
j,
|
|
12
12
|
oe
|
|
13
|
-
} from "../safe-bash/command-chunks/chunk-
|
|
13
|
+
} from "../safe-bash/command-chunks/chunk-ABL2DPJI.js";
|
|
14
14
|
import {
|
|
15
15
|
n as n3,
|
|
16
16
|
o as o5
|
|
@@ -719,18 +719,18 @@ var le;
|
|
|
719
719
|
function wr(...u) {
|
|
720
720
|
return le ??= V({ read: readZipArchiveEntries, write: createStoredZipArchive }), le(...u);
|
|
721
721
|
}
|
|
722
|
-
var H = de(async (u) => (await import("../safe-bash/command-chunks/engine-
|
|
722
|
+
var H = de(async (u) => (await import("../safe-bash/command-chunks/engine-T4GP6QOK-ECFKMR5V.js")).createEngine(u), true, wr);
|
|
723
723
|
var Do = H.createSsconvertCommand;
|
|
724
724
|
var To = H.createSsconvertCommands;
|
|
725
725
|
var Uo = H.ssconvertCommands;
|
|
726
726
|
async function Lo(u, c2, i3) {
|
|
727
|
-
let x2 = await import("../safe-bash/command-chunks/xlsx-RE54MFCS-
|
|
727
|
+
let x2 = await import("../safe-bash/command-chunks/xlsx-RE54MFCS-4UZ5W3U7.js");
|
|
728
728
|
return i3 ? x2.readXlsx(u, c2, true) : x2.readXlsx(u, c2);
|
|
729
729
|
}
|
|
730
|
-
var zo = async (...u) => (await import("../safe-bash/command-chunks/xlsx-RE54MFCS-
|
|
730
|
+
var zo = async (...u) => (await import("../safe-bash/command-chunks/xlsx-RE54MFCS-4UZ5W3U7.js")).probeXlsx(...u);
|
|
731
731
|
var Mo = (u = "2006") => async (c2, i3, x2) => {
|
|
732
732
|
let g2 = (0, T.snapshotXlsxWorkbook)(c2, x2);
|
|
733
|
-
return (await import("../safe-bash/command-chunks/xlsx-RE54MFCS-
|
|
733
|
+
return (await import("../safe-bash/command-chunks/xlsx-RE54MFCS-4UZ5W3U7.js")).createXlsxWriter(u)(g2, i3, x2);
|
|
734
734
|
};
|
|
735
735
|
export {
|
|
736
736
|
r as DEFAULT_SHEET_SIZE,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type StagedOutput } from './retained-output.js';
|
|
2
|
+
import type { ByteSource } from './contracts.js';
|
|
3
|
+
import { type TagOptions, type TagRecord } from './tags.js';
|
|
4
|
+
import type { RetainedPackageArchive, RetainedPackageContext } from './retained-package.js';
|
|
5
|
+
export interface RetainedTagRecord extends Omit<TagRecord, 'name' | 'value'> {
|
|
6
|
+
name(): ByteSource;
|
|
7
|
+
value(): ByteSource;
|
|
8
|
+
}
|
|
9
|
+
/** Tag attributes and ordered records live in caller pages. ZIP-bounded owner
|
|
10
|
+
* and part names are the only strings retained in a record's selector schema. */
|
|
11
|
+
export declare function openRetainedTags(archive: Pick<RetainedPackageArchive, 'parts' | 'has' | 'read' | 'byteLength'>, fingerprint: string, options: TagOptions, settings: RetainedPackageContext): Promise<Readonly<{
|
|
12
|
+
close: () => Promise<void>;
|
|
13
|
+
records(): AsyncGenerator<RetainedTagRecord>;
|
|
14
|
+
}>>;
|
|
15
|
+
/** Stage complete responses before exposing output or retiring metadata. */
|
|
16
|
+
export declare function stageRetainedTags(archive: Pick<RetainedPackageArchive, 'parts' | 'has' | 'read' | 'byteLength'>, fingerprint: string, query: TagOptions, settings: RetainedPackageContext, output: {
|
|
17
|
+
readonly operation: 'tags.list' | 'tags.get';
|
|
18
|
+
readonly json: boolean;
|
|
19
|
+
readonly maxOutputBytes: number;
|
|
20
|
+
}): Promise<StagedOutput>;
|
|
@@ -16,9 +16,11 @@ export interface TagOptions {
|
|
|
16
16
|
readonly value?: string;
|
|
17
17
|
readonly allowEmpty?: boolean;
|
|
18
18
|
}
|
|
19
|
+
export declare function validateTagOptions(options: TagOptions, action?: string): void;
|
|
19
20
|
export declare function readTags(input: BinaryInput, options: TagOptions, context: SelectionContext): Promise<readonly TagRecord[]>;
|
|
20
21
|
export declare function mutateTags(input: BinaryInput, action: "add" | "set" | "remove", options: TagOptions, context: SelectionContext): Promise<{
|
|
21
22
|
bytes: Uint8Array;
|
|
22
23
|
affected: number;
|
|
23
24
|
locations: readonly Location[];
|
|
24
25
|
}>;
|
|
26
|
+
export { openRetainedTags, stageRetainedTags, type RetainedTagRecord } from './retained-tags.js';
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
mutateTags,
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
openRetainedTags,
|
|
4
|
+
readTags,
|
|
5
|
+
stageRetainedTags,
|
|
6
|
+
validateTagOptions
|
|
7
|
+
} from "../safe-bash/command-chunks/chunk-ZHHALBM7.js";
|
|
8
|
+
import "../safe-bash/command-chunks/chunk-FB2WPI3M.js";
|
|
9
|
+
import "../safe-bash/command-chunks/chunk-XVEI4HZL.js";
|
|
5
10
|
import "../safe-bash/command-chunks/chunk-A5SPMSKD.js";
|
|
6
11
|
import "../safe-bash/command-chunks/chunk-TG2RVQLP.js";
|
|
7
12
|
import "../safe-bash/command-chunks/chunk-NCNHJRIY.js";
|
|
@@ -25,5 +30,8 @@ import "../safe-bash/command-chunks/chunk-E6SK3OU2.js";
|
|
|
25
30
|
import "../safe-bash/command-chunks/chunk-65DS4IOB.js";
|
|
26
31
|
export {
|
|
27
32
|
mutateTags,
|
|
28
|
-
|
|
33
|
+
openRetainedTags,
|
|
34
|
+
readTags,
|
|
35
|
+
stageRetainedTags,
|
|
36
|
+
validateTagOptions
|
|
29
37
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
serializeDocument
|
|
3
|
-
} from "../safe-bash/command-chunks/chunk-
|
|
4
|
-
import "../safe-bash/command-chunks/chunk-
|
|
3
|
+
} from "../safe-bash/command-chunks/chunk-UYZ6EFZE.js";
|
|
4
|
+
import "../safe-bash/command-chunks/chunk-E64ZI2YB.js";
|
|
5
5
|
import "../safe-bash/command-chunks/chunk-IJE65P52.js";
|
|
6
6
|
import "../safe-bash/command-chunks/chunk-3I5WTVWZ.js";
|
|
7
7
|
import "../safe-bash/command-chunks/chunk-65DS4IOB.js";
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
} from "../safe-bash/command-chunks/chunk-LNKZVU5V.js";
|
|
4
4
|
import {
|
|
5
5
|
serializeDocument
|
|
6
|
-
} from "../safe-bash/command-chunks/chunk-
|
|
6
|
+
} from "../safe-bash/command-chunks/chunk-UYZ6EFZE.js";
|
|
7
7
|
import {
|
|
8
8
|
parseStoredXml
|
|
9
|
-
} from "../safe-bash/command-chunks/chunk-
|
|
9
|
+
} from "../safe-bash/command-chunks/chunk-E64ZI2YB.js";
|
|
10
10
|
import {
|
|
11
11
|
escape,
|
|
12
12
|
evaluate,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type XmlAttribute, type XmlContent } from "@poe-platform/safe-fs/core";
|
|
2
2
|
import { PagedStorage, type PagedStorageContext } from "@poe-platform/safe-fs/storage";
|
|
3
|
+
import { StoredNamespaces } from "./stored-namespaces.js";
|
|
3
4
|
import { XmlBudget } from "./limits.js";
|
|
4
5
|
export type StoredXmlAttribute = {
|
|
5
6
|
kind: "attribute";
|
|
@@ -24,6 +25,7 @@ export declare class StoredXmlDocument {
|
|
|
24
25
|
private append;
|
|
25
26
|
/** Buffering convenience API; engine traversal uses metadata and attribute links. */
|
|
26
27
|
node(reference: number): Promise<XmlContent | StoredXmlAttribute>;
|
|
28
|
+
namespaceScope(reference: number): Promise<StoredNamespaces>;
|
|
27
29
|
metadata(reference: number): Promise<XmlContent | StoredXmlAttribute>;
|
|
28
30
|
/** Content bodies may span parser fragments or coalesced text tokens.
|
|
29
31
|
* Replay them without making a concatenated node value. */
|
|
@@ -82,7 +82,7 @@ var StoredXPath = class {
|
|
|
82
82
|
} else yield* this.document.children(reference, attributes);
|
|
83
83
|
}
|
|
84
84
|
async select(query, context = this.document.document) {
|
|
85
|
-
const
|
|
85
|
+
const namespaces = await this.document.namespaceScope(this.document.root);
|
|
86
86
|
const union = new StoredSelection(this);
|
|
87
87
|
for (const path of query.paths) {
|
|
88
88
|
let contexts = new StoredSelection(this);
|
|
@@ -90,7 +90,7 @@ var StoredXPath = class {
|
|
|
90
90
|
for (const step of path) {
|
|
91
91
|
const colon = step.name.indexOf(":");
|
|
92
92
|
const prefix = colon < 0 ? "" : step.name.slice(0, colon);
|
|
93
|
-
const namespace = colon < 0 ? "" :
|
|
93
|
+
const namespace = colon < 0 ? "" : await namespaces.get(prefix);
|
|
94
94
|
if (namespace === void 0) throw new XmlQueryError(`undefined XPath namespace prefix: ${prefix}`, 10);
|
|
95
95
|
const localName = colon < 0 ? step.name : step.name.slice(colon + 1);
|
|
96
96
|
const parents = new StoredSelection(this);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PagedStorage } from "@poe-platform/safe-fs/storage";
|
|
2
|
+
import type { XmlBudget } from "./limits.js";
|
|
3
|
+
/** Immutable AVL scopes share unchanged subtrees in caller storage. AVL ancestry
|
|
4
|
+
* is bounded by safe-integer storage addresses (fewer than 80 levels), rather
|
|
5
|
+
* than XML depth or the number of declarations in a scope. Individual namespace
|
|
6
|
+
* names and URIs still have the parser's token cost. */
|
|
7
|
+
export declare class StoredNamespaces {
|
|
8
|
+
private readonly storage;
|
|
9
|
+
private readonly budget;
|
|
10
|
+
readonly reference: number;
|
|
11
|
+
constructor(storage: PagedStorage, budget: XmlBudget, reference?: number);
|
|
12
|
+
private read;
|
|
13
|
+
private write;
|
|
14
|
+
get(prefix: string): Promise<string | undefined>;
|
|
15
|
+
private height;
|
|
16
|
+
private updated;
|
|
17
|
+
private rotate;
|
|
18
|
+
private balance;
|
|
19
|
+
set(prefix: string, uri: string): Promise<StoredNamespaces>;
|
|
20
|
+
[Symbol.asyncIterator](): AsyncGenerator<readonly [string, string]>;
|
|
21
|
+
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
spoolZipSource,
|
|
9
9
|
stageZip,
|
|
10
10
|
unchangedZipSource
|
|
11
|
-
} from "../../safe-bash/command-chunks/chunk-
|
|
11
|
+
} from "../../safe-bash/command-chunks/chunk-TSKJNCKD.js";
|
|
12
12
|
import "../../safe-bash/command-chunks/chunk-65DS4IOB.js";
|
|
13
13
|
export {
|
|
14
14
|
ZipScope,
|
|
@@ -121,8 +121,8 @@ export async function mergeBiffProperties(book, streams, handled, context, charg
|
|
|
121
121
|
const identity = (property) => `${property.stream}:${property.section}:${property.id}`;
|
|
122
122
|
const readContext = { ...context, limits: { ...context.limits, inputBytes: context.limits.outputBytes } };
|
|
123
123
|
// Reuse scalar decoding, but do not create another retained hexadecimal copy.
|
|
124
|
-
await readBiffProperties(new Map([...snapshots].map(([name, value]) => [name, value.bytes])), readContext, accountText, charge, undefined, property => { admit(1); original.set(identity(property), property); });
|
|
125
|
-
await readBiffProperties(streams, readContext, accountText, charge, undefined, property => { admit(1); pending.set(property.key, property); });
|
|
124
|
+
await readBiffProperties(new Map([...snapshots].map(([name, value]) => [name, value.bytes])), readContext, accountText, charge, undefined, property => { admit(1); original.set(identity(property), property); }, false);
|
|
125
|
+
await readBiffProperties(streams, readContext, accountText, charge, undefined, property => { admit(1); pending.set(property.key, property); }, false);
|
|
126
126
|
const chunks = async function* (source) {
|
|
127
127
|
for (let at = 0; at < source.size;) {
|
|
128
128
|
const bytes = await source.read(at, source.size - at);
|
|
@@ -456,7 +456,7 @@ export async function mergeBiffProperties(book, streams, handled, context, charg
|
|
|
456
456
|
admit(1);
|
|
457
457
|
if (!Object.hasOwn(book.properties ?? {}, property.key))
|
|
458
458
|
exposed.add(property.key);
|
|
459
|
-
});
|
|
459
|
+
}, false);
|
|
460
460
|
for (const key of exposed)
|
|
461
461
|
await warn(key, "opaque property exposes a field absent from the model");
|
|
462
462
|
}
|
|
@@ -7,11 +7,13 @@ export declare const biffPropertyFormats: {
|
|
|
7
7
|
};
|
|
8
8
|
export declare const biffPropertyFields: Map<string, ReadonlyMap<number, string>>;
|
|
9
9
|
export declare function isBiffKeywordSpace(code: number): boolean;
|
|
10
|
-
/** Property offsets are section-relative; dictionaries have no variant header.
|
|
10
|
+
/** Property offsets are section-relative; dictionaries have no variant header.
|
|
11
|
+
* With collect=false, await observations without retaining a result record; exact
|
|
12
|
+
* duplicate-name checks use bounded caller storage when available. */
|
|
11
13
|
export declare function readBiffProperties(streams: ReadonlyMap<string, Uint8Array | RangeSource>, context: CapabilityContext, accountText: (text: string) => string, accountWork: (amount: number) => void, retained: UnsupportedRecord[] | undefined, observe?: (property: {
|
|
12
14
|
stream: string;
|
|
13
15
|
section: number;
|
|
14
16
|
id: number;
|
|
15
17
|
key: string;
|
|
16
18
|
value: ImportedValue;
|
|
17
|
-
}) => void): Promise<Readonly<Record<string, ImportedValue>>>;
|
|
19
|
+
}) => void | Promise<void>, collect?: boolean): Promise<Readonly<Record<string, ImportedValue>>>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BiffPropertyNames } from './biff-property-names.js';
|
|
1
2
|
import { visitBiffPropertyDictionary } from './biff-property-dictionary.js';
|
|
2
3
|
import { SsconvertError } from "../spreadsheet-engine/contracts.js";
|
|
3
4
|
import { invalidBiff } from "./biff-binary.js";
|
|
@@ -19,9 +20,12 @@ export const biffPropertyFields = new Map([
|
|
|
19
20
|
export function isBiffKeywordSpace(code) {
|
|
20
21
|
return code > 0 && code <= 32 || code >= 0x2000 && code <= 0x200b || code === 0x2028 || code === 0x2029;
|
|
21
22
|
}
|
|
22
|
-
/** Property offsets are section-relative; dictionaries have no variant header.
|
|
23
|
-
|
|
23
|
+
/** Property offsets are section-relative; dictionaries have no variant header.
|
|
24
|
+
* With collect=false, await observations without retaining a result record; exact
|
|
25
|
+
* duplicate-name checks use bounded caller storage when available. */
|
|
26
|
+
export async function readBiffProperties(streams, context, accountText, accountWork, retained, observe, collect = true) {
|
|
24
27
|
const properties = Object.create(null);
|
|
28
|
+
let names;
|
|
25
29
|
let nodes = 0;
|
|
26
30
|
const admit = (count) => {
|
|
27
31
|
accountWork(count);
|
|
@@ -29,138 +33,153 @@ export async function readBiffProperties(streams, context, accountText, accountW
|
|
|
29
33
|
if (nodes > (context.limits.workbookNodes ?? context.limits.inputBytes))
|
|
30
34
|
throw new SsconvertError("resource-limit", "ssconvert BIFF property node limit exceeded");
|
|
31
35
|
};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
try {
|
|
37
|
+
for (const target of ["\u0005SummaryInformation", "\u0005DocumentSummaryInformation"]) {
|
|
38
|
+
let streamName = target, bytes = streams.get(target);
|
|
39
|
+
if (!bytes)
|
|
40
|
+
for (const [name, data] of streams) {
|
|
41
|
+
accountWork(1);
|
|
42
|
+
if (name.toUpperCase() === target.toUpperCase()) {
|
|
43
|
+
streamName = name;
|
|
44
|
+
bytes = data;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
41
47
|
}
|
|
42
|
-
|
|
43
|
-
if (!bytes)
|
|
44
|
-
continue;
|
|
45
|
-
const file = propertyRange(bytes, context);
|
|
46
|
-
accountWork(file.size);
|
|
47
|
-
const sections = readPropertySectionRanges(file, admit, accountWork, context);
|
|
48
|
-
let unknown = false;
|
|
49
|
-
const modeled = retained ? [] : undefined;
|
|
50
|
-
for await (const { guid, offset, end } of sections) {
|
|
51
|
-
if (!biffPropertyFields.has(guid) && guid !== custom) {
|
|
52
|
-
unknown = true;
|
|
48
|
+
if (!bytes)
|
|
53
49
|
continue;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
50
|
+
const file = propertyRange(bytes, context);
|
|
51
|
+
accountWork(file.size);
|
|
52
|
+
const sections = readPropertySectionRanges(file, admit, accountWork, context);
|
|
53
|
+
let unknown = false;
|
|
54
|
+
const modeled = retained ? [] : undefined;
|
|
55
|
+
for await (const { guid, offset, end } of sections) {
|
|
56
|
+
if (!biffPropertyFields.has(guid) && guid !== custom) {
|
|
57
|
+
unknown = true;
|
|
58
|
+
continue;
|
|
62
59
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
else if (type === 5) {
|
|
82
|
-
value = await data.f64(4);
|
|
83
|
-
if (!Number.isFinite(value))
|
|
84
|
-
invalidBiff("nonfinite property value");
|
|
60
|
+
await withPropertyValueRanges(file.slice(offset, end - offset), admit, accountWork, context, async (values) => {
|
|
61
|
+
const cp = await values.get(1);
|
|
62
|
+
let codepage = 1252;
|
|
63
|
+
if (cp) {
|
|
64
|
+
if ((await cp.u32(0)) !== 2)
|
|
65
|
+
invalidBiff("invalid property codepage type");
|
|
66
|
+
codepage = await cp.u16(4);
|
|
67
|
+
}
|
|
68
|
+
const dictionary = guid === custom ? await values.get(0) : undefined;
|
|
69
|
+
const supported = await visitBiffPropertyDictionary(dictionary, codepage, context, admit, accountText, accountWork, async (getName) => {
|
|
70
|
+
for await (const [id, data] of values.entries()) {
|
|
71
|
+
context.signal.throwIfAborted();
|
|
72
|
+
if (id < 2)
|
|
73
|
+
continue;
|
|
74
|
+
const key = guid === custom ? await getName(id) : biffPropertyFields.get(guid)?.get(id);
|
|
75
|
+
if (key === undefined || (collect ? Object.hasOwn(properties, key) : await (names ??= new BiffPropertyNames(context, accountWork)).has(key))) {
|
|
76
|
+
unknown = true;
|
|
77
|
+
continue;
|
|
85
78
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
79
|
+
let value;
|
|
80
|
+
const type = await data.u32(0);
|
|
81
|
+
try {
|
|
82
|
+
if (type === 30 || type === 31)
|
|
83
|
+
value = (await readBiffPropertyText(data, 4, type === 31 ? 1200 : codepage, context, accountText, accountWork)).value;
|
|
84
|
+
else if (type === 3)
|
|
85
|
+
value = (await data.u32(4)) | 0;
|
|
86
|
+
else if (type === 5) {
|
|
87
|
+
value = await data.f64(4);
|
|
88
|
+
if (!Number.isFinite(value))
|
|
89
|
+
invalidBiff("nonfinite property value");
|
|
90
|
+
}
|
|
91
|
+
else if (type === 11)
|
|
92
|
+
value = (await data.u16(4)) !== 0;
|
|
93
|
+
else if (type === 64) {
|
|
94
|
+
const ticks = BigInt(await data.u32(4)) + (BigInt(await data.u32(8)) << 32n);
|
|
95
|
+
if (guid === summary && id === 10) {
|
|
96
|
+
const fraction = (ticks % 10000000n).toString().padStart(7, "0");
|
|
97
|
+
let end = fraction.length;
|
|
98
|
+
while (end && fraction[end - 1] === "0")
|
|
99
|
+
end--;
|
|
100
|
+
value = `PT${ticks / 600000000n}M${ticks / 10000000n % 60n}${end ? "." + fraction.slice(0, end) : ""}S`;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
value = new Date(Number(ticks / 10000n) - 11644473600000).toISOString();
|
|
104
|
+
// The workbook model stores timestamps as strings; retain the
|
|
105
|
+
// original property bytes when Date's millisecond precision loses ticks.
|
|
106
|
+
if (ticks % 10000n)
|
|
107
|
+
unknown = true;
|
|
108
|
+
}
|
|
109
|
+
accountText(value);
|
|
96
110
|
}
|
|
97
|
-
else {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
111
|
+
else if (type === 7) {
|
|
112
|
+
const days = await data.f64(4);
|
|
113
|
+
if (!Number.isFinite(days) || days <= -657435 || days >= 2958466)
|
|
114
|
+
invalidBiff("invalid OLE property date");
|
|
115
|
+
// OLE Automation uses 1899-12-30 and the absolute fractional day.
|
|
116
|
+
// LibreOffice's oleprops DATE path truncates it and uses 1899-12-31;
|
|
117
|
+
// the documented Automation representation governs the stored value.
|
|
118
|
+
value = new Date(-2209161600000 + Math.round((Math.trunc(days) + Math.abs(days % 1)) * 86400000)).toISOString();
|
|
119
|
+
accountText(value);
|
|
103
120
|
}
|
|
104
|
-
accountText(value);
|
|
105
121
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
invalidBiff("invalid OLE property date");
|
|
110
|
-
// OLE Automation uses 1899-12-30 and the absolute fractional day.
|
|
111
|
-
// LibreOffice's oleprops DATE path truncates it and uses 1899-12-31;
|
|
112
|
-
// the documented Automation representation governs the stored value.
|
|
113
|
-
value = new Date(-2209161600000 + Math.round((Math.trunc(days) + Math.abs(days % 1)) * 86400000)).toISOString();
|
|
114
|
-
accountText(value);
|
|
122
|
+
catch (error) {
|
|
123
|
+
if (!(error instanceof SsconvertError) || error.code !== "unsupported-feature")
|
|
124
|
+
throw error;
|
|
115
125
|
}
|
|
126
|
+
if (value === undefined) {
|
|
127
|
+
unknown = true;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (guid === summary && id === 5 && typeof value === "string") {
|
|
131
|
+
let count = 1;
|
|
132
|
+
for (const character of value)
|
|
133
|
+
if (character === ",")
|
|
134
|
+
count++;
|
|
135
|
+
admit(count);
|
|
136
|
+
accountWork(value.length);
|
|
137
|
+
value = value.split(",").map(keyword => {
|
|
138
|
+
let start = 0, end = keyword.length;
|
|
139
|
+
while (start < end && isBiffKeywordSpace(keyword.charCodeAt(start)))
|
|
140
|
+
start++;
|
|
141
|
+
while (end > start && isBiffKeywordSpace(keyword.charCodeAt(end - 1)))
|
|
142
|
+
end--;
|
|
143
|
+
return keyword.slice(start, end);
|
|
144
|
+
}).filter(Boolean);
|
|
145
|
+
}
|
|
146
|
+
accountText(key);
|
|
147
|
+
if (collect)
|
|
148
|
+
properties[key] = value;
|
|
149
|
+
else
|
|
150
|
+
await names.add(key);
|
|
151
|
+
modeled?.push([offset, id, key]);
|
|
152
|
+
await observe?.({ stream: streamName, section: offset, id, key, value });
|
|
116
153
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
if (value === undefined) {
|
|
122
|
-
unknown = true;
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
if (guid === summary && id === 5 && typeof value === "string") {
|
|
126
|
-
let count = 1;
|
|
127
|
-
for (const character of value)
|
|
128
|
-
if (character === ",")
|
|
129
|
-
count++;
|
|
130
|
-
admit(count);
|
|
131
|
-
accountWork(value.length);
|
|
132
|
-
value = value.split(",").map(keyword => {
|
|
133
|
-
let start = 0, end = keyword.length;
|
|
134
|
-
while (start < end && isBiffKeywordSpace(keyword.charCodeAt(start)))
|
|
135
|
-
start++;
|
|
136
|
-
while (end > start && isBiffKeywordSpace(keyword.charCodeAt(end - 1)))
|
|
137
|
-
end--;
|
|
138
|
-
return keyword.slice(start, end);
|
|
139
|
-
}).filter(Boolean);
|
|
140
|
-
}
|
|
141
|
-
accountText(key);
|
|
142
|
-
properties[key] = value;
|
|
143
|
-
modeled?.push([offset, id, key]);
|
|
144
|
-
observe?.({ stream: streamName, section: offset, id, key, value });
|
|
145
|
-
}
|
|
154
|
+
});
|
|
155
|
+
if (!supported)
|
|
156
|
+
unknown = true;
|
|
146
157
|
});
|
|
147
|
-
if (!supported)
|
|
148
|
-
unknown = true;
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
if (unknown && retained && modeled) {
|
|
152
|
-
if (file.size * 2 > (context.limits.workbookTextBytes ?? context.limits.inputBytes * 2))
|
|
153
|
-
throw new SsconvertError("resource-limit", "ssconvert BIFF property retention limit exceeded");
|
|
154
|
-
let encoded = "";
|
|
155
|
-
for (let at = 0; at < file.size;) {
|
|
156
|
-
const chunk = await file.read(at, Math.min(16384, file.size - at));
|
|
157
|
-
encoded += Array.from(chunk, byte => byte.toString(16).padStart(2, "0")).join("");
|
|
158
|
-
at += chunk.length;
|
|
159
158
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
159
|
+
if (unknown && retained && modeled) {
|
|
160
|
+
if (file.size * 2 > (context.limits.workbookTextBytes ?? context.limits.inputBytes * 2))
|
|
161
|
+
throw new SsconvertError("resource-limit", "ssconvert BIFF property retention limit exceeded");
|
|
162
|
+
let encoded = "";
|
|
163
|
+
for (let at = 0; at < file.size;) {
|
|
164
|
+
const chunk = await file.read(at, Math.min(16384, file.size - at));
|
|
165
|
+
encoded += Array.from(chunk, byte => byte.toString(16).padStart(2, "0")).join("");
|
|
166
|
+
at += chunk.length;
|
|
167
|
+
}
|
|
168
|
+
const hex = accountText(encoded);
|
|
169
|
+
retained.push({ source: "biff", kind: "ole-properties", disposition: "retained", data: { stream: streamName, bytes: hex, modeled } });
|
|
170
|
+
await context.diagnostic?.({ code: "biff-loss-warning", severity: "warning", message: `BIFF property stream ${streamName.slice(1)} retained with uninterpreted values` });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
try {
|
|
176
|
+
await names?.close();
|
|
177
|
+
}
|
|
178
|
+
catch (cleanup) {
|
|
179
|
+
throw new AggregateError([error, cleanup], 'BIFF property observation cleanup failed');
|
|
163
180
|
}
|
|
181
|
+
throw error;
|
|
164
182
|
}
|
|
183
|
+
await names?.close();
|
|
165
184
|
return properties;
|
|
166
185
|
}
|