@ni-c/imap-mcp 0.2.0 → 0.4.0
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/README.md +142 -35
- package/dist/analyze.d.ts +54 -6
- package/dist/analyze.js +295 -27
- package/dist/analyze.js.map +1 -1
- package/dist/attachments.d.ts +36 -0
- package/dist/attachments.js +21 -3
- package/dist/attachments.js.map +1 -1
- package/dist/audit.d.ts +7 -0
- package/dist/audit.js +11 -3
- package/dist/audit.js.map +1 -1
- package/dist/config.d.ts +32 -0
- package/dist/config.js +65 -6
- package/dist/config.js.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/extract/child.d.ts +1 -0
- package/dist/extract/child.js +83 -0
- package/dist/extract/child.js.map +1 -0
- package/dist/extract/index.d.ts +41 -0
- package/dist/extract/index.js +183 -0
- package/dist/extract/index.js.map +1 -0
- package/dist/extract/ooxml.d.ts +35 -0
- package/dist/extract/ooxml.js +627 -0
- package/dist/extract/ooxml.js.map +1 -0
- package/dist/extract/pdf.d.ts +62 -0
- package/dist/extract/pdf.js +539 -0
- package/dist/extract/pdf.js.map +1 -0
- package/dist/extract/types.d.ts +56 -0
- package/dist/extract/types.js +13 -0
- package/dist/extract/types.js.map +1 -0
- package/dist/imap.js.map +1 -1
- package/dist/index.js +32 -5
- package/dist/index.js.map +1 -1
- package/dist/output-schema.d.ts +63 -0
- package/dist/output-schema.js +87 -0
- package/dist/output-schema.js.map +1 -0
- package/dist/resources.d.ts +1 -1
- package/dist/resources.js +5 -2
- package/dist/resources.js.map +1 -1
- package/dist/result.d.ts +39 -6
- package/dist/result.js +142 -29
- package/dist/result.js.map +1 -1
- package/dist/schema.d.ts +13 -1
- package/dist/schema.js +20 -2
- package/dist/schema.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +30 -5
- package/dist/server.js.map +1 -1
- package/dist/tools/annotations.d.ts +32 -0
- package/dist/tools/annotations.js +33 -0
- package/dist/tools/annotations.js.map +1 -0
- package/dist/tools/catalogue.d.ts +2 -2
- package/dist/tools/read.d.ts +1 -1
- package/dist/tools/read.js +743 -87
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/write.d.ts +3 -3
- package/dist/tools/write.js +174 -39
- package/dist/tools/write.js.map +1 -1
- package/package.json +17 -11
- package/dist/approval.d.ts +0 -45
- package/dist/approval.js +0 -69
- package/dist/approval.js.map +0 -1
- package/dist/confirm.d.ts +0 -59
- package/dist/confirm.js +0 -92
- package/dist/confirm.js.map +0 -1
- package/dist/tool-filter.d.ts +0 -45
- package/dist/tool-filter.js +0 -171
- package/dist/tool-filter.js.map +0 -1
|
@@ -0,0 +1,627 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entries this reader will inflate from one container. Counted on the entries
|
|
3
|
+
* the allowlist below admits, not on everything the archive lists: a report
|
|
4
|
+
* with six hundred embedded pictures is a report, not an attack, and the
|
|
5
|
+
* pictures are never read anyway.
|
|
6
|
+
*/
|
|
7
|
+
const MAX_ZIP_ENTRIES = 512;
|
|
8
|
+
/**
|
|
9
|
+
* How large one admitted entry may declare itself, and how large all of them
|
|
10
|
+
* may together.
|
|
11
|
+
*
|
|
12
|
+
* Separate from `maxChars`, which used to be the per-entry budget — and a long
|
|
13
|
+
* contract with tracked changes writes a `document.xml` of several megabytes,
|
|
14
|
+
* far past the million characters that will ever be read from it. The reader
|
|
15
|
+
* slices what it inflates to `maxChars` anyway; these numbers bound the
|
|
16
|
+
* allocation, not the answer.
|
|
17
|
+
*/
|
|
18
|
+
const MAX_ENTRY_BYTES = 16 * 1024 * 1024;
|
|
19
|
+
const MAX_INFLATED_BYTES = 48 * 1024 * 1024;
|
|
20
|
+
/**
|
|
21
|
+
* How far the cell walk may scan for a closing tag it never finds, per sheet.
|
|
22
|
+
* Same reasoning as the closer budget in `htmlToText`: bound the product, not
|
|
23
|
+
* each scan.
|
|
24
|
+
*/
|
|
25
|
+
const CLOSER_SCAN_BUDGET_FACTOR = 4;
|
|
26
|
+
const MAX_SHEETS = 32;
|
|
27
|
+
const MAX_ROWS = 5_000;
|
|
28
|
+
const MAX_COLS = 128;
|
|
29
|
+
const MAX_SLIDES = 200;
|
|
30
|
+
/**
|
|
31
|
+
* Ceiling on a `number-columns-repeated` count.
|
|
32
|
+
*
|
|
33
|
+
* LibreOffice writes `16384` on the trailing empty cell of every single row.
|
|
34
|
+
* Honouring that verbatim turns a 40 kB spreadsheet into hundreds of megabytes
|
|
35
|
+
* of tab characters, which is a denial of service written by a well-behaved
|
|
36
|
+
* office suite rather than by an attacker.
|
|
37
|
+
*/
|
|
38
|
+
const MAX_REPEAT = 256;
|
|
39
|
+
/**
|
|
40
|
+
* A spreadsheet cell holds a value, not a chapter.
|
|
41
|
+
*
|
|
42
|
+
* Applied to every cell, shared strings included. A shared string is written
|
|
43
|
+
* once and referenced by index, so one long string behind sixty thousand
|
|
44
|
+
* cells is a kilobyte of archive standing for gigabytes of output — and the
|
|
45
|
+
* per-row budget below only helps if a single row cannot be that large.
|
|
46
|
+
*/
|
|
47
|
+
const MAX_CELL_CHARS = 4_096;
|
|
48
|
+
/**
|
|
49
|
+
* Reads the text of an OOXML or OpenDocument container.
|
|
50
|
+
*
|
|
51
|
+
* The whole defence lives in the `filter` callback below, and it is worth
|
|
52
|
+
* saying why that specific place. `unzipSync` inflates an entry into a buffer
|
|
53
|
+
* sized by the *declared* uncompressed size out of the central directory — a
|
|
54
|
+
* number the sender chose, checked against nothing. The filter is the last
|
|
55
|
+
* point before that allocation, and returning `false` there means the entry is
|
|
56
|
+
* never inflated and never sized.
|
|
57
|
+
*
|
|
58
|
+
* Measured on fflate 0.8.3: a declared size far past the real one does not blow
|
|
59
|
+
* up resident memory on Linux, because the allocation is virtual and untouched
|
|
60
|
+
* pages cost nothing; and a declared size *below* the real one truncates the
|
|
61
|
+
* output to what was declared, because fflate does not grow a caller-sized
|
|
62
|
+
* buffer. The guard stays regardless — it is free, it is the only thing
|
|
63
|
+
* standing between an *honest* high-ratio entry and its real expansion, and a
|
|
64
|
+
* host that does not overcommit would pay the full price.
|
|
65
|
+
*
|
|
66
|
+
* This never recurses. An entry that is itself an archive is not in the name
|
|
67
|
+
* allowlist, so a nested bomb is not descended into; that is a property to keep
|
|
68
|
+
* rather than an omission to fix.
|
|
69
|
+
*/
|
|
70
|
+
export async function extractZipDocument(kind, bytes, maxChars, toText) {
|
|
71
|
+
const { unzipSync, strFromU8 } = await import('fflate');
|
|
72
|
+
let admitted = 0;
|
|
73
|
+
let bytesLeft = MAX_INFLATED_BYTES;
|
|
74
|
+
let tooManyParts = false;
|
|
75
|
+
let entries;
|
|
76
|
+
try {
|
|
77
|
+
entries = unzipSync(bytes, {
|
|
78
|
+
filter: (file) => {
|
|
79
|
+
if (tooManyParts)
|
|
80
|
+
return false;
|
|
81
|
+
// Nothing here writes to disk, so this is not a traversal fix. The
|
|
82
|
+
// paths below are matched by prefix, and `xl/worksheets/../../x.xml`
|
|
83
|
+
// would match one of them; refusing the name is cheaper than reasoning
|
|
84
|
+
// about what it would mean.
|
|
85
|
+
if (!isSafeName(file.name))
|
|
86
|
+
return false;
|
|
87
|
+
// The allowlist. It is also what disposes of an entry called
|
|
88
|
+
// `__proto__`, which fflate would otherwise use as an object key: no
|
|
89
|
+
// document part is called that, so it is never admitted.
|
|
90
|
+
if (!wanted(kind, file.name))
|
|
91
|
+
return false;
|
|
92
|
+
admitted += 1;
|
|
93
|
+
if (admitted > MAX_ZIP_ENTRIES) {
|
|
94
|
+
tooManyParts = true;
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
// Deflate and stored only. fflate throws on any other method once the
|
|
98
|
+
// filter has said yes, and an error is a worse answer than a skip.
|
|
99
|
+
if (file.compression !== 0 && file.compression !== 8)
|
|
100
|
+
return false;
|
|
101
|
+
if (file.originalSize > MAX_ENTRY_BYTES)
|
|
102
|
+
return false;
|
|
103
|
+
if (file.originalSize > bytesLeft)
|
|
104
|
+
return false;
|
|
105
|
+
bytesLeft -= file.originalSize;
|
|
106
|
+
return true;
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Truncated archive, bad signature, unsupported method. The exception text
|
|
112
|
+
// quotes the file and is never passed on.
|
|
113
|
+
return { ok: false, reason: 'corrupt' };
|
|
114
|
+
}
|
|
115
|
+
if (tooManyParts)
|
|
116
|
+
return { ok: false, reason: 'too-many-parts' };
|
|
117
|
+
const read = (name) => {
|
|
118
|
+
const raw = entries[name];
|
|
119
|
+
return raw === undefined ? undefined : strFromU8(raw);
|
|
120
|
+
};
|
|
121
|
+
if (kind === 'xlsx') {
|
|
122
|
+
return sheetsResult(readXlsx(entries, strFromU8, maxChars), maxChars);
|
|
123
|
+
}
|
|
124
|
+
if (kind === 'ods') {
|
|
125
|
+
const content = read('content.xml');
|
|
126
|
+
if (content === undefined)
|
|
127
|
+
return { ok: false, reason: 'not-a-document' };
|
|
128
|
+
return sheetsResult(readOds(content, maxChars, toText), maxChars);
|
|
129
|
+
}
|
|
130
|
+
const parts = [];
|
|
131
|
+
let units = 0;
|
|
132
|
+
let declared;
|
|
133
|
+
let clipped = false;
|
|
134
|
+
let runs;
|
|
135
|
+
if (kind === 'docx') {
|
|
136
|
+
const document = read('word/document.xml');
|
|
137
|
+
if (document === undefined)
|
|
138
|
+
return { ok: false, reason: 'not-a-document' };
|
|
139
|
+
clipped = document.length > maxChars;
|
|
140
|
+
runs = wordRuns(document.slice(0, maxChars));
|
|
141
|
+
parts.push(toText(document, maxChars));
|
|
142
|
+
}
|
|
143
|
+
else if (kind === 'odt') {
|
|
144
|
+
const content = read('content.xml');
|
|
145
|
+
if (content === undefined)
|
|
146
|
+
return { ok: false, reason: 'not-a-document' };
|
|
147
|
+
clipped = content.length > maxChars;
|
|
148
|
+
parts.push(toText(content, maxChars));
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// pptx: one heading per slide, in slide order rather than in whatever order
|
|
152
|
+
// the archive happens to list them.
|
|
153
|
+
const all = Object.keys(entries)
|
|
154
|
+
.filter((name) => /^ppt\/slides\/slide\d+\.xml$/.test(name))
|
|
155
|
+
.sort((a, b) => slideNumber(a) - slideNumber(b));
|
|
156
|
+
if (all.length === 0)
|
|
157
|
+
return { ok: false, reason: 'not-a-document' };
|
|
158
|
+
const slides = all.slice(0, MAX_SLIDES);
|
|
159
|
+
if (all.length > slides.length)
|
|
160
|
+
declared = all.length;
|
|
161
|
+
for (const name of slides) {
|
|
162
|
+
units += 1;
|
|
163
|
+
parts.push(`== Slide ${units} ==\n${toText(read(name) ?? '', maxChars)}\n`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const joined = parts.join('');
|
|
167
|
+
const text = joined.slice(0, maxChars);
|
|
168
|
+
if (text.trim() === '')
|
|
169
|
+
return { ok: false, reason: 'no-text-layer' };
|
|
170
|
+
return {
|
|
171
|
+
ok: true,
|
|
172
|
+
text,
|
|
173
|
+
...(kind === 'pptx'
|
|
174
|
+
? {
|
|
175
|
+
unitLabel: 'slides',
|
|
176
|
+
unitCount: units,
|
|
177
|
+
...(declared === undefined ? {} : { declaredUnitCount: declared }),
|
|
178
|
+
}
|
|
179
|
+
: {}),
|
|
180
|
+
...(runs === undefined
|
|
181
|
+
? {}
|
|
182
|
+
: { hiddenRuns: runs.hidden, totalRuns: runs.total }),
|
|
183
|
+
clipped: clipped || joined.length > text.length,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function sheetsResult(result, maxChars) {
|
|
187
|
+
if (result === undefined)
|
|
188
|
+
return { ok: false, reason: 'not-a-document' };
|
|
189
|
+
const joined = result.sheets
|
|
190
|
+
.map((sheet) => `== Sheet: ${sheet.name} ==\n` +
|
|
191
|
+
sheet.rows.map((row) => row.join('\t')).join('\n'))
|
|
192
|
+
.join('\n\n');
|
|
193
|
+
// The row budget keeps this within a heading or two of `maxChars`; the slice
|
|
194
|
+
// is what makes the contract exact rather than approximate.
|
|
195
|
+
const text = joined.slice(0, maxChars);
|
|
196
|
+
if (text.trim() === '')
|
|
197
|
+
return { ok: false, reason: 'no-text-layer' };
|
|
198
|
+
return {
|
|
199
|
+
ok: true,
|
|
200
|
+
text,
|
|
201
|
+
unitLabel: 'sheets',
|
|
202
|
+
unitCount: result.sheets.length,
|
|
203
|
+
clipped: result.clipped || joined.length > text.length,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
/* ------------------------------------------------------------------ xlsx -- */
|
|
207
|
+
function readXlsx(entries, strFromU8, maxChars) {
|
|
208
|
+
const at = (name) => {
|
|
209
|
+
const raw = entries[name];
|
|
210
|
+
return raw === undefined ? undefined : strFromU8(raw);
|
|
211
|
+
};
|
|
212
|
+
const shared = sharedStrings(at('xl/sharedStrings.xml'));
|
|
213
|
+
const order = sheetOrder(at('xl/workbook.xml'), at('xl/_rels/workbook.xml.rels'));
|
|
214
|
+
const available = Object.keys(entries)
|
|
215
|
+
.filter((name) => /^xl\/worksheets\/[^/]+\.xml$/.test(name))
|
|
216
|
+
.sort();
|
|
217
|
+
if (available.length === 0)
|
|
218
|
+
return undefined;
|
|
219
|
+
// The rels file is how a tab's name is tied to its file, and `sheet1.xml` is
|
|
220
|
+
// a convention rather than a rule — it is not necessarily the first tab. When
|
|
221
|
+
// the mapping is missing or does not resolve, fall back to archive order with
|
|
222
|
+
// generated names rather than presenting a guess as a fact.
|
|
223
|
+
const planned = order.length > 0
|
|
224
|
+
? order.filter((entry) => available.includes(entry.path))
|
|
225
|
+
: [];
|
|
226
|
+
const plan = planned.length > 0
|
|
227
|
+
? planned
|
|
228
|
+
: available.map((path, index) => ({ name: `Sheet ${index + 1}`, path }));
|
|
229
|
+
const budget = { left: maxChars, clipped: false };
|
|
230
|
+
const sheets = [];
|
|
231
|
+
for (const entry of plan.slice(0, MAX_SHEETS)) {
|
|
232
|
+
if (budget.left <= 0) {
|
|
233
|
+
budget.clipped = true;
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
const xml = at(entry.path);
|
|
237
|
+
if (xml === undefined)
|
|
238
|
+
continue;
|
|
239
|
+
sheets.push({ name: entry.name, rows: worksheetRows(xml, shared, budget) });
|
|
240
|
+
}
|
|
241
|
+
return { sheets, clipped: budget.clipped };
|
|
242
|
+
}
|
|
243
|
+
/** `<si>` entries in document order; a run-split string is its `<t>` pieces. */
|
|
244
|
+
function sharedStrings(xml) {
|
|
245
|
+
if (xml === undefined)
|
|
246
|
+
return [];
|
|
247
|
+
const out = [];
|
|
248
|
+
let i = 0;
|
|
249
|
+
while (out.length < 200_000) {
|
|
250
|
+
const open = xml.indexOf('<si>', i);
|
|
251
|
+
if (open < 0)
|
|
252
|
+
break;
|
|
253
|
+
const close = xml.indexOf('</si>', open);
|
|
254
|
+
if (close < 0)
|
|
255
|
+
break;
|
|
256
|
+
out.push(cell(textRuns(xml.slice(open, close))));
|
|
257
|
+
i = close + 5;
|
|
258
|
+
}
|
|
259
|
+
return out;
|
|
260
|
+
}
|
|
261
|
+
/** Concatenates every `<t>…</t>` in a fragment. Forward-only. */
|
|
262
|
+
function textRuns(fragment) {
|
|
263
|
+
const parts = [];
|
|
264
|
+
let i = 0;
|
|
265
|
+
for (;;) {
|
|
266
|
+
const open = fragment.indexOf('<t', i);
|
|
267
|
+
if (open < 0)
|
|
268
|
+
break;
|
|
269
|
+
const gt = fragment.indexOf('>', open);
|
|
270
|
+
if (gt < 0)
|
|
271
|
+
break;
|
|
272
|
+
// `<t>` and `<t xml:space="preserve">`, but not `<tab/>` or another element
|
|
273
|
+
// whose name merely starts with a t.
|
|
274
|
+
const head = fragment.slice(open + 2, gt);
|
|
275
|
+
if (head !== '' && !head.startsWith(' ') && !head.startsWith('/')) {
|
|
276
|
+
i = gt + 1;
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
if (fragment[gt - 1] === '/') {
|
|
280
|
+
i = gt + 1;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
const close = fragment.indexOf('</t>', gt);
|
|
284
|
+
if (close < 0)
|
|
285
|
+
break;
|
|
286
|
+
parts.push(decodeEntities(fragment.slice(gt + 1, close)));
|
|
287
|
+
i = close + 4;
|
|
288
|
+
}
|
|
289
|
+
return parts.join('');
|
|
290
|
+
}
|
|
291
|
+
function sheetOrder(workbook, rels) {
|
|
292
|
+
if (workbook === undefined)
|
|
293
|
+
return [];
|
|
294
|
+
const targets = new Map();
|
|
295
|
+
if (rels !== undefined) {
|
|
296
|
+
const pattern = /<Relationship\b[^>]*>/g;
|
|
297
|
+
for (let match = pattern.exec(rels); match !== null && targets.size < MAX_SHEETS * 4; match = pattern.exec(rels)) {
|
|
298
|
+
const id = attribute(match[0], 'Id');
|
|
299
|
+
const target = attribute(match[0], 'Target');
|
|
300
|
+
if (id !== undefined && target !== undefined)
|
|
301
|
+
targets.set(id, target);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
const out = [];
|
|
305
|
+
const pattern = /<sheet\b[^>]*>/g;
|
|
306
|
+
for (let match = pattern.exec(workbook); match !== null && out.length < MAX_SHEETS; match = pattern.exec(workbook)) {
|
|
307
|
+
const name = attribute(match[0], 'name');
|
|
308
|
+
const id = attribute(match[0], 'r:id') ?? attribute(match[0], 'id');
|
|
309
|
+
if (name === undefined || id === undefined)
|
|
310
|
+
continue;
|
|
311
|
+
const target = targets.get(id);
|
|
312
|
+
if (target === undefined)
|
|
313
|
+
continue;
|
|
314
|
+
const path = `xl/${target.replace(/^\/?xl\//, '').replace(/^\.\//, '')}`;
|
|
315
|
+
out.push({ name: decodeEntities(name), path });
|
|
316
|
+
}
|
|
317
|
+
return out;
|
|
318
|
+
}
|
|
319
|
+
function worksheetRows(xml, shared, budget) {
|
|
320
|
+
const rows = [];
|
|
321
|
+
let scan = xml.length * CLOSER_SCAN_BUDGET_FACTOR;
|
|
322
|
+
let i = 0;
|
|
323
|
+
let row;
|
|
324
|
+
const finish = (cells) => {
|
|
325
|
+
rows.push(cells);
|
|
326
|
+
budget.left -= cells.reduce((sum, value) => sum + value.length + 1, 0);
|
|
327
|
+
if (budget.left > 0)
|
|
328
|
+
return true;
|
|
329
|
+
budget.clipped = true;
|
|
330
|
+
return false;
|
|
331
|
+
};
|
|
332
|
+
while (i < xml.length && rows.length < MAX_ROWS) {
|
|
333
|
+
const lt = xml.indexOf('<', i);
|
|
334
|
+
if (lt < 0)
|
|
335
|
+
break;
|
|
336
|
+
const gt = xml.indexOf('>', lt);
|
|
337
|
+
if (gt < 0)
|
|
338
|
+
break;
|
|
339
|
+
const tag = xml.slice(lt, gt + 1);
|
|
340
|
+
// `<row>` and `<row r="3">`, not `<rowBreaks>`.
|
|
341
|
+
if (tag === '<row>' || tag.startsWith('<row ')) {
|
|
342
|
+
row = [];
|
|
343
|
+
i = gt + 1;
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
if (tag === '</row>') {
|
|
347
|
+
if (row !== undefined && !finish(row))
|
|
348
|
+
return rows;
|
|
349
|
+
row = undefined;
|
|
350
|
+
i = gt + 1;
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
if (!tag.startsWith('<c ') && tag !== '<c>') {
|
|
354
|
+
i = gt + 1;
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
const selfClosing = tag.endsWith('/>');
|
|
358
|
+
let end = gt + 1;
|
|
359
|
+
let body = '';
|
|
360
|
+
if (!selfClosing) {
|
|
361
|
+
const close = xml.indexOf('</c>', gt);
|
|
362
|
+
if (close < 0 || scan <= 0)
|
|
363
|
+
break;
|
|
364
|
+
scan -= close - gt;
|
|
365
|
+
body = xml.slice(gt + 1, close);
|
|
366
|
+
end = close + 4;
|
|
367
|
+
}
|
|
368
|
+
if (row !== undefined && row.length < MAX_COLS) {
|
|
369
|
+
const column = columnIndex(attribute(tag, 'r'));
|
|
370
|
+
// A cell reference places the value, so a gap in the row stays a gap
|
|
371
|
+
// rather than shifting every later column one to the left.
|
|
372
|
+
if (column !== undefined) {
|
|
373
|
+
while (row.length < Math.min(column, MAX_COLS))
|
|
374
|
+
row.push('');
|
|
375
|
+
}
|
|
376
|
+
row.push(cellValue(tag, body, shared));
|
|
377
|
+
}
|
|
378
|
+
i = end;
|
|
379
|
+
}
|
|
380
|
+
if (row !== undefined)
|
|
381
|
+
finish(row);
|
|
382
|
+
return rows;
|
|
383
|
+
}
|
|
384
|
+
function cellValue(tag, body, shared) {
|
|
385
|
+
const type = attribute(tag, 't');
|
|
386
|
+
if (type === 'inlineStr')
|
|
387
|
+
return cell(textRuns(body));
|
|
388
|
+
if (type === 's') {
|
|
389
|
+
const index = Number(between(body, '<v>', '</v>') ?? '');
|
|
390
|
+
return Number.isInteger(index) ? (shared[index] ?? '') : '';
|
|
391
|
+
}
|
|
392
|
+
const value = between(body, '<v>', '</v>');
|
|
393
|
+
if (value !== undefined)
|
|
394
|
+
return cell(decodeEntities(value));
|
|
395
|
+
return cell(textRuns(body));
|
|
396
|
+
}
|
|
397
|
+
/** `B` → 1, `AA4` → 26. The row part is ignored; the walk supplies it. */
|
|
398
|
+
function columnIndex(reference) {
|
|
399
|
+
if (reference === undefined)
|
|
400
|
+
return undefined;
|
|
401
|
+
const letters = /^([A-Za-z]+)/.exec(reference)?.[1];
|
|
402
|
+
if (letters === undefined || letters.length > 3)
|
|
403
|
+
return undefined;
|
|
404
|
+
let index = 0;
|
|
405
|
+
for (const character of letters.toUpperCase()) {
|
|
406
|
+
index = index * 26 + (character.charCodeAt(0) - 64);
|
|
407
|
+
}
|
|
408
|
+
return index - 1;
|
|
409
|
+
}
|
|
410
|
+
/* -------------------------------------------------------------------- ods -- */
|
|
411
|
+
function readOds(xml, maxChars, toText) {
|
|
412
|
+
const sheets = [];
|
|
413
|
+
const budget = { left: maxChars, clipped: false };
|
|
414
|
+
let i = 0;
|
|
415
|
+
while (sheets.length < MAX_SHEETS) {
|
|
416
|
+
if (budget.left <= 0) {
|
|
417
|
+
budget.clipped = true;
|
|
418
|
+
break;
|
|
419
|
+
}
|
|
420
|
+
const open = xml.indexOf('<table:table ', i);
|
|
421
|
+
if (open < 0)
|
|
422
|
+
break;
|
|
423
|
+
const gt = xml.indexOf('>', open);
|
|
424
|
+
if (gt < 0)
|
|
425
|
+
break;
|
|
426
|
+
const name = decodeEntities(attribute(xml.slice(open, gt + 1), 'table:name') ??
|
|
427
|
+
`Sheet ${sheets.length + 1}`);
|
|
428
|
+
const close = xml.indexOf('</table:table>', gt);
|
|
429
|
+
const body = xml.slice(gt + 1, close < 0 ? xml.length : close);
|
|
430
|
+
sheets.push({ name, rows: odsRows(body, toText, budget) });
|
|
431
|
+
if (close < 0)
|
|
432
|
+
break;
|
|
433
|
+
i = close + 14;
|
|
434
|
+
}
|
|
435
|
+
return { sheets, clipped: budget.clipped };
|
|
436
|
+
}
|
|
437
|
+
function odsRows(xml, toText, budget) {
|
|
438
|
+
const rows = [];
|
|
439
|
+
let i = 0;
|
|
440
|
+
while (i < xml.length && rows.length < MAX_ROWS) {
|
|
441
|
+
const open = xml.indexOf('<table:table-row', i);
|
|
442
|
+
if (open < 0)
|
|
443
|
+
break;
|
|
444
|
+
const close = xml.indexOf('</table:table-row>', open);
|
|
445
|
+
const body = xml.slice(open, close < 0 ? xml.length : close);
|
|
446
|
+
const row = [];
|
|
447
|
+
let j = 0;
|
|
448
|
+
while (row.length < MAX_COLS) {
|
|
449
|
+
const at = body.indexOf('<table:table-cell', j);
|
|
450
|
+
if (at < 0)
|
|
451
|
+
break;
|
|
452
|
+
const gt = body.indexOf('>', at);
|
|
453
|
+
if (gt < 0)
|
|
454
|
+
break;
|
|
455
|
+
const tag = body.slice(at, gt + 1);
|
|
456
|
+
const cellClose = tag.endsWith('/>')
|
|
457
|
+
? -1
|
|
458
|
+
: body.indexOf('</table:table-cell>', gt);
|
|
459
|
+
// An OpenDocument cell holds `<text:p>`, not the `<t>` of OOXML, so the
|
|
460
|
+
// markup walk does the reading here rather than the run collector.
|
|
461
|
+
// Trimmed, because the markup walk emits a space for every tag it drops
|
|
462
|
+
// and a cell padded with them stops lining up as a column.
|
|
463
|
+
const value = cellClose < 0
|
|
464
|
+
? ''
|
|
465
|
+
: cell(toText(body.slice(gt + 1, cellClose), MAX_CELL_CHARS)).trim();
|
|
466
|
+
// Clamped, and this is the guard that matters most in this file: every
|
|
467
|
+
// row an office suite writes ends in a cell repeated 16 384 times.
|
|
468
|
+
const repeat = Math.min(Math.max(Number(attribute(tag, 'table:number-columns-repeated') ?? '1') || 1, 1), MAX_REPEAT);
|
|
469
|
+
for (let n = 0; n < repeat && row.length < MAX_COLS; n += 1)
|
|
470
|
+
row.push(value);
|
|
471
|
+
j = cellClose < 0 ? gt + 1 : cellClose + 19;
|
|
472
|
+
}
|
|
473
|
+
// Trailing empty cells are padding, not data.
|
|
474
|
+
while (row.length > 0 && row[row.length - 1] === '')
|
|
475
|
+
row.pop();
|
|
476
|
+
rows.push(row);
|
|
477
|
+
budget.left -= row.reduce((sum, value) => sum + value.length + 1, 0);
|
|
478
|
+
if (budget.left <= 0) {
|
|
479
|
+
budget.clipped = true;
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
if (close < 0)
|
|
483
|
+
break;
|
|
484
|
+
i = close + 18;
|
|
485
|
+
}
|
|
486
|
+
// The same padding, one dimension up.
|
|
487
|
+
while (rows.length > 0 && rows[rows.length - 1].length === 0)
|
|
488
|
+
rows.pop();
|
|
489
|
+
return rows;
|
|
490
|
+
}
|
|
491
|
+
/* ------------------------------------------------------------------- docx -- */
|
|
492
|
+
/**
|
|
493
|
+
* Counts the runs of a Word document, and how many of them a reader would not
|
|
494
|
+
* see: marked hidden, set at two points or below, or coloured white.
|
|
495
|
+
*
|
|
496
|
+
* The same signal the PDF reader reports, for the same reason — the text
|
|
497
|
+
* still goes to the model, and the header says that some of it was placed
|
|
498
|
+
* where a person would not have found it. Forward-only cursors, so a document
|
|
499
|
+
* of a hundred thousand runs with no closing tags costs one pass, not one pass
|
|
500
|
+
* per run.
|
|
501
|
+
*/
|
|
502
|
+
function wordRuns(xml) {
|
|
503
|
+
let total = 0;
|
|
504
|
+
let hidden = 0;
|
|
505
|
+
let i = 0;
|
|
506
|
+
let nextProps = xml.indexOf('<w:rPr>');
|
|
507
|
+
let nextPropsEnd = xml.indexOf('</w:rPr>');
|
|
508
|
+
let nextClose = xml.indexOf('</w:r>');
|
|
509
|
+
const advance = (cursor, needle, from) => {
|
|
510
|
+
let at = cursor;
|
|
511
|
+
while (at >= 0 && at < from)
|
|
512
|
+
at = xml.indexOf(needle, at + 1);
|
|
513
|
+
return at;
|
|
514
|
+
};
|
|
515
|
+
for (;;) {
|
|
516
|
+
const open = xml.indexOf('<w:r', i);
|
|
517
|
+
if (open < 0)
|
|
518
|
+
break;
|
|
519
|
+
i = open + 4;
|
|
520
|
+
const next = xml[open + 4];
|
|
521
|
+
// `<w:r>` and `<w:r w:rsidR="…">`, not `<w:rPr>` or `<w:rFonts>`.
|
|
522
|
+
if (next !== '>' && next !== ' ')
|
|
523
|
+
continue;
|
|
524
|
+
total += 1;
|
|
525
|
+
nextProps = advance(nextProps, '<w:rPr>', open);
|
|
526
|
+
nextClose = advance(nextClose, '</w:r>', open);
|
|
527
|
+
if (nextProps < 0 || (nextClose >= 0 && nextClose < nextProps))
|
|
528
|
+
continue;
|
|
529
|
+
nextPropsEnd = advance(nextPropsEnd, '</w:rPr>', nextProps);
|
|
530
|
+
if (nextPropsEnd < 0)
|
|
531
|
+
break;
|
|
532
|
+
if (isHiddenRun(xml.slice(nextProps, nextPropsEnd)))
|
|
533
|
+
hidden += 1;
|
|
534
|
+
}
|
|
535
|
+
return { total, hidden };
|
|
536
|
+
}
|
|
537
|
+
function isHiddenRun(properties) {
|
|
538
|
+
return (properties.includes('<w:vanish') ||
|
|
539
|
+
properties.includes('<w:webHidden') ||
|
|
540
|
+
/<w:color\b[^>]*w:val="(?:ffffff|white)"/i.test(properties) ||
|
|
541
|
+
/<w:sz\b[^>]*w:val="[1-4]"/.test(properties));
|
|
542
|
+
}
|
|
543
|
+
/* ------------------------------------------------------------------ misc -- */
|
|
544
|
+
/**
|
|
545
|
+
* Entries this server will inflate, by kind.
|
|
546
|
+
*
|
|
547
|
+
* An allowlist rather than a denylist, checked before anything is decompressed.
|
|
548
|
+
* Everything an attacker could add to a container — a second archive, a font, a
|
|
549
|
+
* media file, an entry with a hostile name — is simply never read.
|
|
550
|
+
*/
|
|
551
|
+
function wanted(kind, name) {
|
|
552
|
+
if (kind === 'docx')
|
|
553
|
+
return name === 'word/document.xml';
|
|
554
|
+
if (kind === 'odt' || kind === 'ods')
|
|
555
|
+
return name === 'content.xml';
|
|
556
|
+
if (kind === 'pptx')
|
|
557
|
+
return /^ppt\/slides\/slide\d+\.xml$/.test(name);
|
|
558
|
+
return (name === 'xl/workbook.xml' ||
|
|
559
|
+
name === 'xl/_rels/workbook.xml.rels' ||
|
|
560
|
+
name === 'xl/sharedStrings.xml' ||
|
|
561
|
+
/^xl\/worksheets\/[^/]+\.xml$/.test(name));
|
|
562
|
+
}
|
|
563
|
+
function isSafeName(name) {
|
|
564
|
+
if (name.startsWith('/') || name.includes('\\'))
|
|
565
|
+
return false;
|
|
566
|
+
if (/^[A-Za-z]:/.test(name))
|
|
567
|
+
return false;
|
|
568
|
+
return !name.split('/').includes('..');
|
|
569
|
+
}
|
|
570
|
+
function slideNumber(name) {
|
|
571
|
+
return Number(/(\d+)\.xml$/.exec(name)?.[1] ?? 0);
|
|
572
|
+
}
|
|
573
|
+
function attribute(tag, name) {
|
|
574
|
+
const pattern = new RegExp(`\\b${name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s*=\\s*"([^"]*)"`);
|
|
575
|
+
return pattern.exec(tag)?.[1];
|
|
576
|
+
}
|
|
577
|
+
function between(source, open, close) {
|
|
578
|
+
const start = source.indexOf(open);
|
|
579
|
+
if (start < 0)
|
|
580
|
+
return undefined;
|
|
581
|
+
const end = source.indexOf(close, start + open.length);
|
|
582
|
+
if (end < 0)
|
|
583
|
+
return undefined;
|
|
584
|
+
return source.slice(start + open.length, end);
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* A cell value: no tab or newline, because either would end the column or the
|
|
588
|
+
* row it is in and the reader has no way to tell that from real structure; and
|
|
589
|
+
* no more than {@link MAX_CELL_CHARS}, because a cell is a value.
|
|
590
|
+
*/
|
|
591
|
+
function cell(value) {
|
|
592
|
+
const flat = value.replace(/[\t\r\n]+/g, ' ');
|
|
593
|
+
return flat.length > MAX_CELL_CHARS ? flat.slice(0, MAX_CELL_CHARS) : flat;
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* The five predefined XML entities and bounded numeric references.
|
|
597
|
+
*
|
|
598
|
+
* Deliberately nothing else. There is no entity table here, so a document that
|
|
599
|
+
* declares `<!ENTITY lol …>` gets its `&lol;` back as five literal characters —
|
|
600
|
+
* which is what makes billion-laughs and `SYSTEM "file:///etc/passwd"` non-events
|
|
601
|
+
* rather than defended-against attacks.
|
|
602
|
+
*/
|
|
603
|
+
function decodeEntities(value) {
|
|
604
|
+
return value
|
|
605
|
+
.replace(/</g, '<')
|
|
606
|
+
.replace(/>/g, '>')
|
|
607
|
+
.replace(/"/g, '"')
|
|
608
|
+
.replace(/'/g, "'")
|
|
609
|
+
.replace(/&#x([0-9a-fA-F]{1,6});/g, (match, hex) => codePoint(parseInt(hex, 16), match))
|
|
610
|
+
.replace(/&#(\d{1,7});/g, (match, digits) => codePoint(Number(digits), match))
|
|
611
|
+
.replace(/&/g, '&');
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Same rule as `fromCodePoint` in `../analyze.ts`, and deliberately the same
|
|
615
|
+
* answer: a reference nobody can render stays visible rather than becoming a
|
|
616
|
+
* replacement character that reads as content. Duplicated rather than shared
|
|
617
|
+
* because this module is reached from the child, where a relative import of
|
|
618
|
+
* `../analyze.js` does not resolve.
|
|
619
|
+
*/
|
|
620
|
+
function codePoint(value, original) {
|
|
621
|
+
if (!Number.isInteger(value) || value < 1 || value > 0x10ffff)
|
|
622
|
+
return original;
|
|
623
|
+
if (value >= 0xd800 && value <= 0xdfff)
|
|
624
|
+
return original;
|
|
625
|
+
return String.fromCodePoint(value);
|
|
626
|
+
}
|
|
627
|
+
//# sourceMappingURL=ooxml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ooxml.js","sourceRoot":"","sources":["../../src/extract/ooxml.ts"],"names":[],"mappings":"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"}
|