wpd-codec 3.5.0 → 3.5.2
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/container/container.cjs +2 -3
- package/dist/container/container.js +2 -3
- package/dist/container/encryption.cjs +7 -3
- package/dist/container/encryption.d.cts +2 -1
- package/dist/container/encryption.d.ts +2 -1
- package/dist/container/encryption.js +7 -4
- package/dist/container/header.cjs +0 -1
- package/dist/container/header.js +0 -1
- package/dist/container/prefix.cjs +19 -16
- package/dist/container/prefix.js +19 -16
- package/dist/container/summary.cjs +10 -4
- package/dist/container/summary.js +10 -4
- package/dist/read.cjs +10 -17
- package/dist/read.d.cts +3 -1
- package/dist/read.d.ts +3 -1
- package/dist/read.js +9 -18
- package/dist/stream/box.cjs +61 -70
- package/dist/stream/box.js +61 -70
- package/dist/stream/characters.cjs +2 -0
- package/dist/stream/characters.d.cts +2 -1
- package/dist/stream/characters.d.ts +2 -1
- package/dist/stream/characters.js +2 -1
- package/dist/stream/formula.cjs +14 -16
- package/dist/stream/formula.js +15 -17
- package/dist/stream/image.cjs +55 -41
- package/dist/stream/image.d.cts +3 -1
- package/dist/stream/image.d.ts +3 -1
- package/dist/stream/image.js +55 -43
- package/dist/stream/ole.cjs +1 -1
- package/dist/stream/ole.js +2 -2
- package/dist/stream/style.cjs +15 -13
- package/dist/stream/style.js +15 -13
- package/dist/stream/table.cjs +47 -33
- package/dist/stream/table.d.cts +3 -2
- package/dist/stream/table.d.ts +3 -2
- package/dist/stream/table.js +48 -35
- package/dist/stream/wpg.cjs +38 -40
- package/dist/stream/wpg.js +38 -40
- package/package.json +4 -4
|
@@ -39,14 +39,13 @@ function unwrapContainer(bytes) {
|
|
|
39
39
|
}
|
|
40
40
|
function documentAreaEnd(bytes, header) {
|
|
41
41
|
const { fileSize, documentAreaOffset } = header;
|
|
42
|
-
if (fileSize > documentAreaOffset
|
|
42
|
+
if (fileSize > documentAreaOffset) return Math.min(fileSize, bytes.length);
|
|
43
43
|
return bytes.length;
|
|
44
44
|
}
|
|
45
45
|
function openWpdDocument(input, options = {}) {
|
|
46
46
|
const { bytes: wrapped, compound, oleObjectStreams } = unwrapContainer(toArrayBufferBacked(input));
|
|
47
47
|
const header = require_container_header.readFileHeader(wrapped, options);
|
|
48
|
-
const
|
|
49
|
-
const bytes = header.encryption !== 0 && suppliedPassword !== void 0 ? require_container_encryption.decryptWpdDocument(wrapped, header, suppliedPassword) : wrapped;
|
|
48
|
+
const bytes = header.encryption !== 0 && options.password !== void 0 ? require_container_encryption.decryptWpdDocument(wrapped, header, options.password) : wrapped;
|
|
50
49
|
return {
|
|
51
50
|
header,
|
|
52
51
|
packets: require_container_prefix.readPrefixPackets(bytes, header),
|
|
@@ -38,14 +38,13 @@ function unwrapContainer(bytes) {
|
|
|
38
38
|
}
|
|
39
39
|
function documentAreaEnd(bytes, header) {
|
|
40
40
|
const { fileSize, documentAreaOffset } = header;
|
|
41
|
-
if (fileSize > documentAreaOffset
|
|
41
|
+
if (fileSize > documentAreaOffset) return Math.min(fileSize, bytes.length);
|
|
42
42
|
return bytes.length;
|
|
43
43
|
}
|
|
44
44
|
function openWpdDocument(input, options = {}) {
|
|
45
45
|
const { bytes: wrapped, compound, oleObjectStreams } = unwrapContainer(toArrayBufferBacked(input));
|
|
46
46
|
const header = readFileHeader(wrapped, options);
|
|
47
|
-
const
|
|
48
|
-
const bytes = header.encryption !== 0 && suppliedPassword !== void 0 ? decryptWpdDocument(wrapped, header, suppliedPassword) : wrapped;
|
|
47
|
+
const bytes = header.encryption !== 0 && options.password !== void 0 ? decryptWpdDocument(wrapped, header, options.password) : wrapped;
|
|
49
48
|
return {
|
|
50
49
|
header,
|
|
51
50
|
packets: readPrefixPackets(bytes, header),
|
|
@@ -20,6 +20,11 @@ function wpdPasswordChecksum16(normalised) {
|
|
|
20
20
|
}
|
|
21
21
|
return checksum;
|
|
22
22
|
}
|
|
23
|
+
function passwordByteAt(normalised, relative) {
|
|
24
|
+
const value = normalised[relative % normalised.length];
|
|
25
|
+
if (value === void 0) throw new require_errors.WpdFormatError("The password normalised to no bytes, which the cipher cannot key with.");
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
23
28
|
function applyWpdStandardEncryption(bytes, normalised, startOffset) {
|
|
24
29
|
if (normalised.length === 0) throw new require_errors.WpdFormatError("The WordPerfect cipher is keyed by the password's own bytes, so an empty password decrypts nothing.");
|
|
25
30
|
const maskBase = normalised.length + 1 & 255;
|
|
@@ -27,10 +32,8 @@ function applyWpdStandardEncryption(bytes, normalised, startOffset) {
|
|
|
27
32
|
output.set(bytes.subarray(0, startOffset));
|
|
28
33
|
for (let pos = startOffset; pos < bytes.length; pos++) {
|
|
29
34
|
const relative = pos - startOffset;
|
|
30
|
-
const passwordByte = normalised[relative % normalised.length];
|
|
31
|
-
if (passwordByte === void 0) throw new require_errors.WpdFormatError("The password normalised to no bytes, which the cipher cannot key with.");
|
|
32
35
|
const mask = maskBase + relative & 255;
|
|
33
|
-
output[pos] = require_bytes_view.byteAt(bytes, pos) ^
|
|
36
|
+
output[pos] = require_bytes_view.byteAt(bytes, pos) ^ passwordByteAt(normalised, relative) ^ mask;
|
|
34
37
|
}
|
|
35
38
|
return output;
|
|
36
39
|
}
|
|
@@ -56,4 +59,5 @@ exports.applyWpdStandardEncryption = applyWpdStandardEncryption;
|
|
|
56
59
|
exports.decryptWpdDocument = decryptWpdDocument;
|
|
57
60
|
exports.encryptWpdDocumentForTests = encryptWpdDocumentForTests;
|
|
58
61
|
exports.normaliseWpdPassword = normaliseWpdPassword;
|
|
62
|
+
exports.passwordByteAt = passwordByteAt;
|
|
59
63
|
exports.wpdPasswordChecksum16 = wpdPasswordChecksum16;
|
|
@@ -2,8 +2,9 @@ import { i as WpdFileHeader } from "../header-Ca8QZVe3.cjs";
|
|
|
2
2
|
//#region src/container/encryption.d.ts
|
|
3
3
|
declare function normaliseWpdPassword(password: string): number[];
|
|
4
4
|
declare function wpdPasswordChecksum16(normalised: readonly number[]): number;
|
|
5
|
+
declare function passwordByteAt(normalised: readonly number[], relative: number): number;
|
|
5
6
|
declare function applyWpdStandardEncryption(bytes: Uint8Array, normalised: readonly number[], startOffset: number): Uint8Array<ArrayBuffer>;
|
|
6
7
|
declare function decryptWpdDocument(bytes: Uint8Array<ArrayBuffer>, header: WpdFileHeader, password: string): Uint8Array<ArrayBuffer>;
|
|
7
8
|
declare function encryptWpdDocumentForTests(bytes: Uint8Array, password: string): Uint8Array<ArrayBuffer>;
|
|
8
9
|
//#endregion
|
|
9
|
-
export { applyWpdStandardEncryption, decryptWpdDocument, encryptWpdDocumentForTests, normaliseWpdPassword, wpdPasswordChecksum16 };
|
|
10
|
+
export { applyWpdStandardEncryption, decryptWpdDocument, encryptWpdDocumentForTests, normaliseWpdPassword, passwordByteAt, wpdPasswordChecksum16 };
|
|
@@ -2,8 +2,9 @@ import { i as WpdFileHeader } from "../header-Ca8QZVe3.js";
|
|
|
2
2
|
//#region src/container/encryption.d.ts
|
|
3
3
|
declare function normaliseWpdPassword(password: string): number[];
|
|
4
4
|
declare function wpdPasswordChecksum16(normalised: readonly number[]): number;
|
|
5
|
+
declare function passwordByteAt(normalised: readonly number[], relative: number): number;
|
|
5
6
|
declare function applyWpdStandardEncryption(bytes: Uint8Array, normalised: readonly number[], startOffset: number): Uint8Array<ArrayBuffer>;
|
|
6
7
|
declare function decryptWpdDocument(bytes: Uint8Array<ArrayBuffer>, header: WpdFileHeader, password: string): Uint8Array<ArrayBuffer>;
|
|
7
8
|
declare function encryptWpdDocumentForTests(bytes: Uint8Array, password: string): Uint8Array<ArrayBuffer>;
|
|
8
9
|
//#endregion
|
|
9
|
-
export { applyWpdStandardEncryption, decryptWpdDocument, encryptWpdDocumentForTests, normaliseWpdPassword, wpdPasswordChecksum16 };
|
|
10
|
+
export { applyWpdStandardEncryption, decryptWpdDocument, encryptWpdDocumentForTests, normaliseWpdPassword, passwordByteAt, wpdPasswordChecksum16 };
|
|
@@ -19,6 +19,11 @@ function wpdPasswordChecksum16(normalised) {
|
|
|
19
19
|
}
|
|
20
20
|
return checksum;
|
|
21
21
|
}
|
|
22
|
+
function passwordByteAt(normalised, relative) {
|
|
23
|
+
const value = normalised[relative % normalised.length];
|
|
24
|
+
if (value === void 0) throw new WpdFormatError("The password normalised to no bytes, which the cipher cannot key with.");
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
22
27
|
function applyWpdStandardEncryption(bytes, normalised, startOffset) {
|
|
23
28
|
if (normalised.length === 0) throw new WpdFormatError("The WordPerfect cipher is keyed by the password's own bytes, so an empty password decrypts nothing.");
|
|
24
29
|
const maskBase = normalised.length + 1 & 255;
|
|
@@ -26,10 +31,8 @@ function applyWpdStandardEncryption(bytes, normalised, startOffset) {
|
|
|
26
31
|
output.set(bytes.subarray(0, startOffset));
|
|
27
32
|
for (let pos = startOffset; pos < bytes.length; pos++) {
|
|
28
33
|
const relative = pos - startOffset;
|
|
29
|
-
const passwordByte = normalised[relative % normalised.length];
|
|
30
|
-
if (passwordByte === void 0) throw new WpdFormatError("The password normalised to no bytes, which the cipher cannot key with.");
|
|
31
34
|
const mask = maskBase + relative & 255;
|
|
32
|
-
output[pos] = byteAt(bytes, pos) ^
|
|
35
|
+
output[pos] = byteAt(bytes, pos) ^ passwordByteAt(normalised, relative) ^ mask;
|
|
33
36
|
}
|
|
34
37
|
return output;
|
|
35
38
|
}
|
|
@@ -51,4 +54,4 @@ function encryptWpdDocumentForTests(bytes, password) {
|
|
|
51
54
|
return output;
|
|
52
55
|
}
|
|
53
56
|
//#endregion
|
|
54
|
-
export { applyWpdStandardEncryption, decryptWpdDocument, encryptWpdDocumentForTests, normaliseWpdPassword, wpdPasswordChecksum16 };
|
|
57
|
+
export { applyWpdStandardEncryption, decryptWpdDocument, encryptWpdDocumentForTests, normaliseWpdPassword, passwordByteAt, wpdPasswordChecksum16 };
|
|
@@ -13,7 +13,6 @@ const PRODUCT_TYPE_WORDPERFECT = 1;
|
|
|
13
13
|
const DOCUMENT_FILE_TYPES = [10, 36];
|
|
14
14
|
const MAJOR_VERSION_WP6_THROUGH_X6 = 2;
|
|
15
15
|
function hasWordPerfectFileId(bytes) {
|
|
16
|
-
if (bytes.length < WPD_FILE_ID.length) return false;
|
|
17
16
|
return WPD_FILE_ID.every((expected, index) => bytes[index] === expected);
|
|
18
17
|
}
|
|
19
18
|
function readFileHeader(bytes, options = {}) {
|
package/dist/container/header.js
CHANGED
|
@@ -12,7 +12,6 @@ const PRODUCT_TYPE_WORDPERFECT = 1;
|
|
|
12
12
|
const DOCUMENT_FILE_TYPES = [10, 36];
|
|
13
13
|
const MAJOR_VERSION_WP6_THROUGH_X6 = 2;
|
|
14
14
|
function hasWordPerfectFileId(bytes) {
|
|
15
|
-
if (bytes.length < WPD_FILE_ID.length) return false;
|
|
16
15
|
return WPD_FILE_ID.every((expected, index) => bytes[index] === expected);
|
|
17
16
|
}
|
|
18
17
|
function readFileHeader(bytes, options = {}) {
|
|
@@ -52,24 +52,27 @@ const TYPEFACE_NAME_LENGTH_OFFSET = 22;
|
|
|
52
52
|
const TYPEFACE_NAME_OFFSET = 24;
|
|
53
53
|
const PACKET_TYPE_GENERAL_WP_TEXT = 8;
|
|
54
54
|
function readGeneralWpTextBlocks(bytes) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
55
|
+
try {
|
|
56
|
+
const blockCount = require_bytes_view.uint16At(bytes, 0);
|
|
57
|
+
const firstBlockOffset = require_bytes_view.uint16At(bytes, 2);
|
|
58
|
+
if (blockCount === 0) return;
|
|
59
|
+
let totalSize = 0;
|
|
60
|
+
for (let index = 0; index < blockCount; index += 1) totalSize += require_bytes_view.uint16At(bytes, 4 + index * 2);
|
|
61
|
+
const end = firstBlockOffset + totalSize;
|
|
62
|
+
if (end > bytes.length) return;
|
|
63
|
+
return bytes.subarray(firstBlockOffset, end);
|
|
64
|
+
} catch {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
65
67
|
}
|
|
66
68
|
function readTypefaceName(packet) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
try {
|
|
70
|
+
const nameLength = require_bytes_view.uint16At(packet, TYPEFACE_NAME_LENGTH_OFFSET);
|
|
71
|
+
const { text } = require_stream_characters.decodeWordString(packet, TYPEFACE_NAME_OFFSET, Math.floor(nameLength / 2));
|
|
72
|
+
return text.length > 0 ? text : void 0;
|
|
73
|
+
} catch {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
73
76
|
}
|
|
74
77
|
//#endregion
|
|
75
78
|
exports.PACKET_TYPE_DESIRED_FONT_DESCRIPTOR = PACKET_TYPE_DESIRED_FONT_DESCRIPTOR;
|
package/dist/container/prefix.js
CHANGED
|
@@ -51,24 +51,27 @@ const TYPEFACE_NAME_LENGTH_OFFSET = 22;
|
|
|
51
51
|
const TYPEFACE_NAME_OFFSET = 24;
|
|
52
52
|
const PACKET_TYPE_GENERAL_WP_TEXT = 8;
|
|
53
53
|
function readGeneralWpTextBlocks(bytes) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
try {
|
|
55
|
+
const blockCount = uint16At(bytes, 0);
|
|
56
|
+
const firstBlockOffset = uint16At(bytes, 2);
|
|
57
|
+
if (blockCount === 0) return;
|
|
58
|
+
let totalSize = 0;
|
|
59
|
+
for (let index = 0; index < blockCount; index += 1) totalSize += uint16At(bytes, 4 + index * 2);
|
|
60
|
+
const end = firstBlockOffset + totalSize;
|
|
61
|
+
if (end > bytes.length) return;
|
|
62
|
+
return bytes.subarray(firstBlockOffset, end);
|
|
63
|
+
} catch {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
64
66
|
}
|
|
65
67
|
function readTypefaceName(packet) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
try {
|
|
69
|
+
const nameLength = uint16At(packet, TYPEFACE_NAME_LENGTH_OFFSET);
|
|
70
|
+
const { text } = decodeWordString(packet, TYPEFACE_NAME_OFFSET, Math.floor(nameLength / 2));
|
|
71
|
+
return text.length > 0 ? text : void 0;
|
|
72
|
+
} catch {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
72
75
|
}
|
|
73
76
|
//#endregion
|
|
74
77
|
export { PACKET_TYPE_DESIRED_FONT_DESCRIPTOR, PACKET_TYPE_GENERAL_WP_TEXT, WPD_INDEX_RECORD_SIZE, packetByPrefixId, readGeneralWpTextBlocks, readPrefixPackets, readTypefaceName };
|
|
@@ -35,10 +35,16 @@ function readDocumentSummary(packet) {
|
|
|
35
35
|
const metadata = {};
|
|
36
36
|
let cursor = 0;
|
|
37
37
|
for (let group = 0; group < MAX_SUMMARY_GROUPS; group += 1) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
let size;
|
|
39
|
+
let tag;
|
|
40
|
+
let type;
|
|
41
|
+
try {
|
|
42
|
+
size = require_bytes_view.uint16At(packet, cursor);
|
|
43
|
+
tag = require_bytes_view.uint16At(packet, cursor + 2);
|
|
44
|
+
type = require_bytes_view.uint16At(packet, cursor + 4);
|
|
45
|
+
} catch {
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
42
48
|
if (size < GROUP_HEADER_SIZE || cursor + size > packet.length) break;
|
|
43
49
|
const availableWords = Math.floor((size - GROUP_HEADER_SIZE) / 2);
|
|
44
50
|
const name = require_stream_characters.decodeWordString(packet, cursor + GROUP_HEADER_SIZE, availableWords);
|
|
@@ -34,10 +34,16 @@ function readDocumentSummary(packet) {
|
|
|
34
34
|
const metadata = {};
|
|
35
35
|
let cursor = 0;
|
|
36
36
|
for (let group = 0; group < MAX_SUMMARY_GROUPS; group += 1) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
let size;
|
|
38
|
+
let tag;
|
|
39
|
+
let type;
|
|
40
|
+
try {
|
|
41
|
+
size = uint16At(packet, cursor);
|
|
42
|
+
tag = uint16At(packet, cursor + 2);
|
|
43
|
+
type = uint16At(packet, cursor + 4);
|
|
44
|
+
} catch {
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
41
47
|
if (size < GROUP_HEADER_SIZE || cursor + size > packet.length) break;
|
|
42
48
|
const availableWords = Math.floor((size - GROUP_HEADER_SIZE) / 2);
|
|
43
49
|
const name = decodeWordString(packet, cursor + GROUP_HEADER_SIZE, availableWords);
|
package/dist/read.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_errors = require("./errors.cjs");
|
|
2
3
|
const require_bytes_view = require("./bytes/view.cjs");
|
|
3
4
|
const require_bytes_base64 = require("./bytes/base64.cjs");
|
|
4
5
|
const require_stream_furniture = require("./stream/furniture.cjs");
|
|
@@ -87,6 +88,10 @@ function flushRun(state) {
|
|
|
87
88
|
state.runs.push(buildRun(state));
|
|
88
89
|
state.text = "";
|
|
89
90
|
}
|
|
91
|
+
const UNREACHABLE_CHARACTER_MAPPING_MESSAGE = "A single-byte document-area character had no character mapping, which the tokeniser's own byte range should make unreachable.";
|
|
92
|
+
function assertDefined(value, message) {
|
|
93
|
+
if (value === void 0) throw new require_errors.WpdFormatError(message);
|
|
94
|
+
}
|
|
90
95
|
function targetBlocks(state) {
|
|
91
96
|
return state.table === void 0 ? state.blocks : state.table.cellBlocks;
|
|
92
97
|
}
|
|
@@ -120,10 +125,7 @@ function flushParagraphIfContent(state, sink) {
|
|
|
120
125
|
flushParagraph(state, sink);
|
|
121
126
|
}
|
|
122
127
|
function effectiveStyle(state) {
|
|
123
|
-
|
|
124
|
-
const semantics = state.styleScopes[index]?.semantics;
|
|
125
|
-
if (semantics !== void 0) return semantics;
|
|
126
|
-
}
|
|
128
|
+
return state.styleScopes.findLast((scope) => scope.semantics !== void 0)?.semantics;
|
|
127
129
|
}
|
|
128
130
|
function appendText(state, text) {
|
|
129
131
|
if (state.skipDepth > 0 || state.numberDisplayDepth > 0) return;
|
|
@@ -272,7 +274,6 @@ function applySingleByteFunction(state, code, sink) {
|
|
|
272
274
|
case END_OF_TEXT_TO_SKIP:
|
|
273
275
|
state.skipDepth = Math.max(0, state.skipDepth - 1);
|
|
274
276
|
return;
|
|
275
|
-
default: return;
|
|
276
277
|
}
|
|
277
278
|
}
|
|
278
279
|
function applyFontFaceChange(state, prefixIds, container, sink) {
|
|
@@ -380,7 +381,7 @@ function applyStyleGroup(state, token, container, sink) {
|
|
|
380
381
|
function applyDisplayNumberGroup(state, token, sink) {
|
|
381
382
|
if (require_stream_style.isParagraphNumberDisplayOn(token.subgroup)) {
|
|
382
383
|
const level = require_stream_style.readDisplayNumberLevel(token.nonDeletable);
|
|
383
|
-
|
|
384
|
+
state.pendingListLevel ??= level;
|
|
384
385
|
state.numberDisplayDepth += 1;
|
|
385
386
|
reportOnce(state, sink, require_diagnostics.WpdDiagnosticCodes.OutlineNumberRegenerated, "An outline number's rendered digits were replaced by the list membership that regenerates them.");
|
|
386
387
|
return;
|
|
@@ -433,7 +434,6 @@ function applyCharacterGroup(state, token, container, sink) {
|
|
|
433
434
|
};
|
|
434
435
|
return;
|
|
435
436
|
}
|
|
436
|
-
default: return;
|
|
437
437
|
}
|
|
438
438
|
}
|
|
439
439
|
function applyHeaderFooterGroup(state, token, container, sink) {
|
|
@@ -749,7 +749,6 @@ function applyVariableFunction(state, token, container, sink) {
|
|
|
749
749
|
case BOX_GROUP:
|
|
750
750
|
applyBoxGroup(state, token, container, sink);
|
|
751
751
|
return;
|
|
752
|
-
default: return;
|
|
753
752
|
}
|
|
754
753
|
}
|
|
755
754
|
function applyFixedFunction(state, token, sink) {
|
|
@@ -785,14 +784,7 @@ function applyToken(state, token, container, sink) {
|
|
|
785
784
|
switch (token.kind) {
|
|
786
785
|
case "character": {
|
|
787
786
|
const character = require_stream_characters.decodeSingleByteCharacter(token.byte);
|
|
788
|
-
|
|
789
|
-
sink({
|
|
790
|
-
code: require_diagnostics.WpdDiagnosticCodes.UnmappedCharacter,
|
|
791
|
-
message: `Byte ${token.byte} in the document area has no character mapping and was rendered as U+FFFD.`
|
|
792
|
-
});
|
|
793
|
-
appendText(state, "�");
|
|
794
|
-
return;
|
|
795
|
-
}
|
|
787
|
+
assertDefined(character, UNREACHABLE_CHARACTER_MAPPING_MESSAGE);
|
|
796
788
|
appendText(state, character);
|
|
797
789
|
return;
|
|
798
790
|
}
|
|
@@ -934,7 +926,6 @@ function readWpd(bytes, options = {}) {
|
|
|
934
926
|
marker: note.marker,
|
|
935
927
|
blocks: note.blocks
|
|
936
928
|
}]));
|
|
937
|
-
if (Object.keys(attachments).length === 0 && notes.length === 0) return assembled;
|
|
938
929
|
return {
|
|
939
930
|
...assembled,
|
|
940
931
|
...Object.keys(attachments).length > 0 ? { attachments: {
|
|
@@ -948,5 +939,7 @@ function readWpd(bytes, options = {}) {
|
|
|
948
939
|
};
|
|
949
940
|
}
|
|
950
941
|
//#endregion
|
|
942
|
+
exports.UNREACHABLE_CHARACTER_MAPPING_MESSAGE = UNREACHABLE_CHARACTER_MAPPING_MESSAGE;
|
|
943
|
+
exports.assertDefined = assertDefined;
|
|
951
944
|
exports.readWpd = readWpd;
|
|
952
945
|
exports.readWpdContent = readWpdContent;
|
package/dist/read.d.cts
CHANGED
|
@@ -10,7 +10,9 @@ interface WpdNoteDefinition {
|
|
|
10
10
|
readonly marker: string;
|
|
11
11
|
readonly blocks: readonly ContentBlock[];
|
|
12
12
|
}
|
|
13
|
+
declare const UNREACHABLE_CHARACTER_MAPPING_MESSAGE = "A single-byte document-area character had no character mapping, which the tokeniser's own byte range should make unreachable.";
|
|
14
|
+
declare function assertDefined<T>(value: T | undefined, message: string): asserts value is T;
|
|
13
15
|
declare function readWpdContent(bytes: Uint8Array, options?: ReadWpdOptions): ContentDocument;
|
|
14
16
|
declare function readWpd(bytes: Uint8Array, options?: ReadWpdOptions): DocumentTree;
|
|
15
17
|
//#endregion
|
|
16
|
-
export { ReadWpdOptions, WpdNoteDefinition, readWpd, readWpdContent };
|
|
18
|
+
export { ReadWpdOptions, UNREACHABLE_CHARACTER_MAPPING_MESSAGE, WpdNoteDefinition, assertDefined, readWpd, readWpdContent };
|
package/dist/read.d.ts
CHANGED
|
@@ -10,7 +10,9 @@ interface WpdNoteDefinition {
|
|
|
10
10
|
readonly marker: string;
|
|
11
11
|
readonly blocks: readonly ContentBlock[];
|
|
12
12
|
}
|
|
13
|
+
declare const UNREACHABLE_CHARACTER_MAPPING_MESSAGE = "A single-byte document-area character had no character mapping, which the tokeniser's own byte range should make unreachable.";
|
|
14
|
+
declare function assertDefined<T>(value: T | undefined, message: string): asserts value is T;
|
|
13
15
|
declare function readWpdContent(bytes: Uint8Array, options?: ReadWpdOptions): ContentDocument;
|
|
14
16
|
declare function readWpd(bytes: Uint8Array, options?: ReadWpdOptions): DocumentTree;
|
|
15
17
|
//#endregion
|
|
16
|
-
export { ReadWpdOptions, WpdNoteDefinition, readWpd, readWpdContent };
|
|
18
|
+
export { ReadWpdOptions, UNREACHABLE_CHARACTER_MAPPING_MESSAGE, WpdNoteDefinition, assertDefined, readWpd, readWpdContent };
|
package/dist/read.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { WpdFormatError } from "./errors.js";
|
|
1
2
|
import { uint16At } from "./bytes/view.js";
|
|
2
3
|
import { bytesToBase64 } from "./bytes/base64.js";
|
|
3
4
|
import { readFurnitureClaim } from "./stream/furniture.js";
|
|
@@ -86,6 +87,10 @@ function flushRun(state) {
|
|
|
86
87
|
state.runs.push(buildRun(state));
|
|
87
88
|
state.text = "";
|
|
88
89
|
}
|
|
90
|
+
const UNREACHABLE_CHARACTER_MAPPING_MESSAGE = "A single-byte document-area character had no character mapping, which the tokeniser's own byte range should make unreachable.";
|
|
91
|
+
function assertDefined(value, message) {
|
|
92
|
+
if (value === void 0) throw new WpdFormatError(message);
|
|
93
|
+
}
|
|
89
94
|
function targetBlocks(state) {
|
|
90
95
|
return state.table === void 0 ? state.blocks : state.table.cellBlocks;
|
|
91
96
|
}
|
|
@@ -119,10 +124,7 @@ function flushParagraphIfContent(state, sink) {
|
|
|
119
124
|
flushParagraph(state, sink);
|
|
120
125
|
}
|
|
121
126
|
function effectiveStyle(state) {
|
|
122
|
-
|
|
123
|
-
const semantics = state.styleScopes[index]?.semantics;
|
|
124
|
-
if (semantics !== void 0) return semantics;
|
|
125
|
-
}
|
|
127
|
+
return state.styleScopes.findLast((scope) => scope.semantics !== void 0)?.semantics;
|
|
126
128
|
}
|
|
127
129
|
function appendText(state, text) {
|
|
128
130
|
if (state.skipDepth > 0 || state.numberDisplayDepth > 0) return;
|
|
@@ -271,7 +273,6 @@ function applySingleByteFunction(state, code, sink) {
|
|
|
271
273
|
case END_OF_TEXT_TO_SKIP:
|
|
272
274
|
state.skipDepth = Math.max(0, state.skipDepth - 1);
|
|
273
275
|
return;
|
|
274
|
-
default: return;
|
|
275
276
|
}
|
|
276
277
|
}
|
|
277
278
|
function applyFontFaceChange(state, prefixIds, container, sink) {
|
|
@@ -379,7 +380,7 @@ function applyStyleGroup(state, token, container, sink) {
|
|
|
379
380
|
function applyDisplayNumberGroup(state, token, sink) {
|
|
380
381
|
if (isParagraphNumberDisplayOn(token.subgroup)) {
|
|
381
382
|
const level = readDisplayNumberLevel(token.nonDeletable);
|
|
382
|
-
|
|
383
|
+
state.pendingListLevel ??= level;
|
|
383
384
|
state.numberDisplayDepth += 1;
|
|
384
385
|
reportOnce(state, sink, WpdDiagnosticCodes.OutlineNumberRegenerated, "An outline number's rendered digits were replaced by the list membership that regenerates them.");
|
|
385
386
|
return;
|
|
@@ -432,7 +433,6 @@ function applyCharacterGroup(state, token, container, sink) {
|
|
|
432
433
|
};
|
|
433
434
|
return;
|
|
434
435
|
}
|
|
435
|
-
default: return;
|
|
436
436
|
}
|
|
437
437
|
}
|
|
438
438
|
function applyHeaderFooterGroup(state, token, container, sink) {
|
|
@@ -748,7 +748,6 @@ function applyVariableFunction(state, token, container, sink) {
|
|
|
748
748
|
case BOX_GROUP:
|
|
749
749
|
applyBoxGroup(state, token, container, sink);
|
|
750
750
|
return;
|
|
751
|
-
default: return;
|
|
752
751
|
}
|
|
753
752
|
}
|
|
754
753
|
function applyFixedFunction(state, token, sink) {
|
|
@@ -784,14 +783,7 @@ function applyToken(state, token, container, sink) {
|
|
|
784
783
|
switch (token.kind) {
|
|
785
784
|
case "character": {
|
|
786
785
|
const character = decodeSingleByteCharacter(token.byte);
|
|
787
|
-
|
|
788
|
-
sink({
|
|
789
|
-
code: WpdDiagnosticCodes.UnmappedCharacter,
|
|
790
|
-
message: `Byte ${token.byte} in the document area has no character mapping and was rendered as U+FFFD.`
|
|
791
|
-
});
|
|
792
|
-
appendText(state, "�");
|
|
793
|
-
return;
|
|
794
|
-
}
|
|
786
|
+
assertDefined(character, UNREACHABLE_CHARACTER_MAPPING_MESSAGE);
|
|
795
787
|
appendText(state, character);
|
|
796
788
|
return;
|
|
797
789
|
}
|
|
@@ -933,7 +925,6 @@ function readWpd(bytes, options = {}) {
|
|
|
933
925
|
marker: note.marker,
|
|
934
926
|
blocks: note.blocks
|
|
935
927
|
}]));
|
|
936
|
-
if (Object.keys(attachments).length === 0 && notes.length === 0) return assembled;
|
|
937
928
|
return {
|
|
938
929
|
...assembled,
|
|
939
930
|
...Object.keys(attachments).length > 0 ? { attachments: {
|
|
@@ -947,4 +938,4 @@ function readWpd(bytes, options = {}) {
|
|
|
947
938
|
};
|
|
948
939
|
}
|
|
949
940
|
//#endregion
|
|
950
|
-
export { readWpd, readWpdContent };
|
|
941
|
+
export { UNREACHABLE_CHARACTER_MAPPING_MESSAGE, assertDefined, readWpd, readWpdContent };
|
package/dist/stream/box.cjs
CHANGED
|
@@ -8,83 +8,74 @@ const OVERRIDE_BIT_HTML = 7;
|
|
|
8
8
|
const OVERRIDE_FLAGS_OFFSET = 18;
|
|
9
9
|
const FIRST_OVERRIDE_BLOCK_OFFSET = 20;
|
|
10
10
|
function walkOverrideBlocks(nonDeletable) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
11
|
+
try {
|
|
12
|
+
const flags = require_bytes_view.uint16At(nonDeletable, OVERRIDE_FLAGS_OFFSET);
|
|
13
|
+
const blocks = /* @__PURE__ */ new Map();
|
|
14
|
+
let cursor = FIRST_OVERRIDE_BLOCK_OFFSET;
|
|
15
|
+
for (let bit = 15; bit >= 5; bit -= 1) {
|
|
16
|
+
if ((flags & 1 << bit) === 0) continue;
|
|
17
|
+
if (bit === OVERRIDE_BIT_HTML) continue;
|
|
18
|
+
const size = require_bytes_view.uint16At(nonDeletable, cursor);
|
|
19
|
+
cursor += 2;
|
|
20
|
+
if (cursor + size > nonDeletable.length) return;
|
|
21
|
+
blocks.set(bit, nonDeletable.subarray(cursor, cursor + size));
|
|
22
|
+
cursor += size;
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
flags,
|
|
26
|
+
blocks
|
|
27
|
+
};
|
|
28
|
+
} catch {
|
|
29
|
+
return;
|
|
24
30
|
}
|
|
25
|
-
return {
|
|
26
|
-
flags,
|
|
27
|
-
blocks
|
|
28
|
-
};
|
|
29
31
|
}
|
|
30
32
|
function readContentType(contentBlock) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
cursor
|
|
33
|
+
try {
|
|
34
|
+
const flags = require_bytes_view.uint16At(contentBlock, 0);
|
|
35
|
+
let cursor = 2;
|
|
36
|
+
if ((flags & 32768) !== 0) cursor += 2;
|
|
37
|
+
if ((flags & 16384) === 0) return;
|
|
38
|
+
return contentBlock[cursor];
|
|
39
|
+
} catch {
|
|
40
|
+
return;
|
|
37
41
|
}
|
|
38
|
-
if ((flags & 16384) === 0) return;
|
|
39
|
-
return contentBlock[cursor];
|
|
40
42
|
}
|
|
41
43
|
function readPositionOverride(positionBlock) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
if ((flags & 1024) !== 0) {
|
|
78
|
-
if (!need(3)) return void 0;
|
|
79
|
-
heightWpu = require_bytes_view.uint16At(positionBlock, cursor + 1);
|
|
80
|
-
cursor += 3;
|
|
44
|
+
try {
|
|
45
|
+
const flags = require_bytes_view.uint16At(positionBlock, 0);
|
|
46
|
+
let cursor = 2;
|
|
47
|
+
let widthWpu;
|
|
48
|
+
let heightWpu;
|
|
49
|
+
let xWpu;
|
|
50
|
+
let yWpu;
|
|
51
|
+
if ((flags & 32768) !== 0) cursor += 2;
|
|
52
|
+
if ((flags & 16384) !== 0) cursor += 2;
|
|
53
|
+
if ((flags & 8192) !== 0) {
|
|
54
|
+
const horizontalFlags = positionBlock[cursor];
|
|
55
|
+
const offset = require_bytes_view.uint16At(positionBlock, cursor + 1);
|
|
56
|
+
if (horizontalFlags !== void 0 && (horizontalFlags & 3) === 0) xWpu = offset;
|
|
57
|
+
cursor += 5;
|
|
58
|
+
}
|
|
59
|
+
if ((flags & 4096) !== 0) {
|
|
60
|
+
const verticalFlags = positionBlock[cursor];
|
|
61
|
+
const offset = require_bytes_view.uint16At(positionBlock, cursor + 1);
|
|
62
|
+
if (verticalFlags !== void 0 && (verticalFlags & 3) === 0) yWpu = offset;
|
|
63
|
+
cursor += 3;
|
|
64
|
+
}
|
|
65
|
+
if ((flags & 2048) !== 0) {
|
|
66
|
+
widthWpu = require_bytes_view.uint16At(positionBlock, cursor + 1);
|
|
67
|
+
cursor += 3;
|
|
68
|
+
}
|
|
69
|
+
if ((flags & 1024) !== 0) heightWpu = require_bytes_view.uint16At(positionBlock, cursor + 1);
|
|
70
|
+
return {
|
|
71
|
+
widthWpu,
|
|
72
|
+
heightWpu,
|
|
73
|
+
xWpu,
|
|
74
|
+
yWpu
|
|
75
|
+
};
|
|
76
|
+
} catch {
|
|
77
|
+
return;
|
|
81
78
|
}
|
|
82
|
-
return {
|
|
83
|
-
widthWpu,
|
|
84
|
-
heightWpu,
|
|
85
|
-
xWpu,
|
|
86
|
-
yWpu
|
|
87
|
-
};
|
|
88
79
|
}
|
|
89
80
|
const BOX_CONTENT_TYPE_TEXT = 1;
|
|
90
81
|
const BOX_CONTENT_TYPE_LINKED_TEXT = 2;
|