@patrickdk77/office-defuse 0.0.0-stage → 0.1.1

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.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +317 -2
  3. package/dist/biff.d.ts +62 -0
  4. package/dist/biff.js +95 -0
  5. package/dist/cfb.d.ts +58 -0
  6. package/dist/cfb.js +456 -0
  7. package/dist/context.d.ts +66 -0
  8. package/dist/context.js +121 -0
  9. package/dist/crc32.d.ts +8 -0
  10. package/dist/crc32.js +58 -0
  11. package/dist/engine.d.ts +5 -0
  12. package/dist/engine.js +200 -0
  13. package/dist/errors.d.ts +19 -0
  14. package/dist/errors.js +33 -0
  15. package/dist/fields.d.ts +29 -0
  16. package/dist/fields.js +97 -0
  17. package/dist/findings.d.ts +25 -0
  18. package/dist/findings.js +188 -0
  19. package/dist/formats.d.ts +10 -0
  20. package/dist/formats.js +46 -0
  21. package/dist/formulas.d.ts +22 -0
  22. package/dist/formulas.js +77 -0
  23. package/dist/index.d.ts +5 -0
  24. package/dist/index.js +30 -0
  25. package/dist/index.mjs +3 -0
  26. package/dist/io.d.ts +23 -0
  27. package/dist/io.js +139 -0
  28. package/dist/links.d.ts +26 -0
  29. package/dist/links.js +145 -0
  30. package/dist/msg.d.ts +7 -0
  31. package/dist/msg.js +97 -0
  32. package/dist/objects.d.ts +42 -0
  33. package/dist/objects.js +134 -0
  34. package/dist/odf.d.ts +3 -0
  35. package/dist/odf.js +297 -0
  36. package/dist/offcrypto.d.ts +31 -0
  37. package/dist/offcrypto.js +408 -0
  38. package/dist/ole.d.ts +12 -0
  39. package/dist/ole.js +127 -0
  40. package/dist/oleobj.d.ts +74 -0
  41. package/dist/oleobj.js +198 -0
  42. package/dist/ooxml.d.ts +8 -0
  43. package/dist/ooxml.js +468 -0
  44. package/dist/package.d.ts +3 -0
  45. package/dist/package.js +21 -0
  46. package/dist/ppt.d.ts +8 -0
  47. package/dist/ppt.js +241 -0
  48. package/dist/rtf.d.ts +8 -0
  49. package/dist/rtf.js +539 -0
  50. package/dist/score.d.ts +17 -0
  51. package/dist/score.js +63 -0
  52. package/dist/types.d.ts +274 -0
  53. package/dist/types.js +152 -0
  54. package/dist/word.d.ts +9 -0
  55. package/dist/word.js +160 -0
  56. package/dist/xls.d.ts +27 -0
  57. package/dist/xls.js +174 -0
  58. package/dist/xlsb.d.ts +19 -0
  59. package/dist/xlsb.js +101 -0
  60. package/dist/xml.d.ts +256 -0
  61. package/dist/xml.js +1105 -0
  62. package/dist/zip-writer.d.ts +38 -0
  63. package/dist/zip-writer.js +182 -0
  64. package/dist/zip.d.ts +55 -0
  65. package/dist/zip.js +535 -0
  66. package/package.json +96 -4
package/dist/xls.js ADDED
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.excelRules = excelRules;
4
+ exports.virtualPath = virtualPath;
5
+ exports.hyperlink = hyperlink;
6
+ const biff_1 = require("./biff");
7
+ const context_1 = require("./context");
8
+ const errors_1 = require("./errors");
9
+ const links_1 = require("./links");
10
+ const oleobj_1 = require("./oleobj");
11
+ const types_1 = require("./types");
12
+ const STATES = ['visible', 'hidden', 'very hidden', 'hidden'];
13
+ /**
14
+ * Inspects an Excel 5.0 to 2003 workbook stream. Excel reads the globals substream from the start of the stream,
15
+ * then each sheet from where its BoundSheet record says the sheet starts. The globals give the macro sheets, the
16
+ * names Excel runs as macros, and the DDE, OLE and workbook links. The sheets give shapes that run macros and
17
+ * hyperlinks. An encrypted workbook goes through `unlock`.
18
+ */
19
+ async function excelRules(ctx, cfb, stream, unlock) {
20
+ const location = stream.name;
21
+ const records = new biff_1.RecordReader(cfb, stream, 0, ctx.settings.deadline);
22
+ const first = await records.next();
23
+ if (first?.type !== biff_1.R.bof || first.body.length < 4)
24
+ throw new errors_1.StopError(types_1.OfficeCategory.Package, types_1.OfficeDetail.Unrecognized, `The ${stream.name} stream does not start with a BOF record`, { reason: 'a workbook stream without a BOF record' });
25
+ const biff8 = (first.body[0] | (first.body[1] << 8)) === 0x0600;
26
+ let decrypt = r => r.body;
27
+ const sheets = [];
28
+ const books = [];
29
+ const flags = { template: false, addIn: false };
30
+ for (let r = await records.next(); r && r.type !== biff_1.R.eof; r = await records.next()) {
31
+ if (r.type === biff_1.R.filePass) {
32
+ decrypt = await unlock(ctx, r, location);
33
+ continue;
34
+ }
35
+ const body = decrypt(r);
36
+ if (r.type === biff_1.R.boundSheet)
37
+ sheets.push((0, biff_1.parseBoundSheet)(body, biff8));
38
+ else if (r.type === biff_1.R.template)
39
+ flags.template = true;
40
+ else if (r.type === biff_1.R.addIn)
41
+ flags.addIn = true;
42
+ else if (r.type === biff_1.R.lbl) {
43
+ const name = (0, biff_1.parseLbl)(body, biff8);
44
+ const auto = (0, biff_1.autoName)(name.name);
45
+ if (auto)
46
+ ctx.report(types_1.OfficeCategory.Macro, auto.onOpen ? types_1.OfficeDetail.EventOnOpen : types_1.OfficeDetail.Event, location, { event: auto.event, name: (0, context_1.clip)(name.name) });
47
+ }
48
+ else if (r.type === biff_1.R.supBook && body.length >= 4) {
49
+ const cch = body[2] | (body[3] << 8);
50
+ books.push({ ctab: body[0] | (body[1] << 8), cch, path: cch > 0 && cch <= 0xff ? (0, biff_1.xlString)(body, 4, cch).text : '', ole: false, dde: false });
51
+ }
52
+ else if (r.type === biff_1.R.externName && body.length >= 2 && books.length) {
53
+ // fOle and fOleLink mark an OLE object's name. Excel writes StdDocumentName with fOle beside the items of a DDE
54
+ // link, so a link with any DDE item is a DDE link.
55
+ if ((body[0] | (body[1] << 8)) & 0x18)
56
+ books[books.length - 1].ole = true;
57
+ else
58
+ books[books.length - 1].dde = true;
59
+ }
60
+ }
61
+ for (const b of books)
62
+ linkRules(ctx, b, location);
63
+ for (const s of sheets)
64
+ await sheetRules(ctx, cfb, stream, s, decrypt, location);
65
+ return flags;
66
+ }
67
+ /** A SupBook record, read as MS-XLS 2.4.271 and oletools tell its kinds apart. */
68
+ function linkRules(ctx, b, location) {
69
+ if (b.cch === 0x401 || b.cch === 0x3a01 || b.path === ' ' || b.path === '\0' || !b.path)
70
+ return;
71
+ if (b.ctab === 0) {
72
+ // A DDE or OLE data source: the application or class, U+0003, and the topic or file.
73
+ const [application, topic = ''] = b.path.split('\x03');
74
+ if (b.ole && !b.dde) {
75
+ const data = { source: 'SupBook', className: (0, context_1.clip)(application) };
76
+ if (topic)
77
+ ctx.external(types_1.OfficeDetail.Object, topic, location, data, 'linked object');
78
+ else
79
+ ctx.report(types_1.OfficeCategory.External, types_1.OfficeDetail.Object, location, data);
80
+ }
81
+ else
82
+ ctx.report(types_1.OfficeCategory.Dde, types_1.OfficeDetail.Link, location, { application: (0, context_1.clip)(application), topic: (0, context_1.clip)(topic) });
83
+ return;
84
+ }
85
+ ctx.external(types_1.OfficeDetail.Workbook, virtualPath(b.path), location, { source: 'SupBook' }, 'external workbook');
86
+ }
87
+ /**
88
+ * A VirtualPath (MS-XLS 2.5.277) written out. One that starts with U+0001 is encoded: its control characters name a
89
+ * volume, the root, a folder, a step up, a URL's volume or Excel's startup folders.
90
+ */
91
+ function virtualPath(p) {
92
+ if (p.charCodeAt(0) !== 1)
93
+ return p;
94
+ let out = '';
95
+ for (let i = 1; i < p.length; i++) {
96
+ const c = p.charCodeAt(i);
97
+ if (c === 1) {
98
+ // A drive letter, or @ for a UNC host. A U+0003 after it starts the path.
99
+ const v = p[i + 1] ?? '';
100
+ i++;
101
+ out += v === '@' ? '\\\\' : `${v}:`;
102
+ }
103
+ else if (c === 2 || c === 3)
104
+ out += '\\';
105
+ else if (c === 4)
106
+ out += '..\\';
107
+ // A long volume, such as a URL, after a character that counts it.
108
+ else if (c === 5)
109
+ i++;
110
+ else if (c >= 6 && c <= 8)
111
+ out += 'XLSTART\\';
112
+ else
113
+ out += p[i];
114
+ }
115
+ return out;
116
+ }
117
+ /** One sheet's substream, with any chart substreams inside it: Obj records that run macros, and hyperlinks. */
118
+ async function sheetRules(ctx, cfb, stream, s, decrypt, location) {
119
+ const records = new biff_1.RecordReader(cfb, stream, s.position, ctx.settings.deadline);
120
+ const bof = await records.next();
121
+ if (bof?.type !== biff_1.R.bof || bof.body.length < 4)
122
+ return;
123
+ const bofType = bof.body[2] | (bof.body[3] << 8);
124
+ // The sheet's own BOF says what it is, and so does its BoundSheet record. Either one makes a macro sheet.
125
+ if (s.type === 1 || bofType === 0x0040)
126
+ ctx.report(types_1.OfficeCategory.Macro, types_1.OfficeDetail.XlmMacrosheet, location, { sheet: (0, context_1.clip)(s.name), state: STATES[s.state] });
127
+ let depth = 1;
128
+ for (let r = await records.next(); r && depth > 0; r = await records.next()) {
129
+ if (r.type === biff_1.R.bof)
130
+ depth++;
131
+ else if (r.type === biff_1.R.eof)
132
+ depth--;
133
+ else if (r.type === biff_1.R.obj) {
134
+ if (objMacro(decrypt(r)))
135
+ ctx.report(types_1.OfficeCategory.Macro, types_1.OfficeDetail.Link, location, { sheet: (0, context_1.clip)(s.name) });
136
+ }
137
+ else if (r.type === biff_1.R.hlink) {
138
+ const target = hyperlink(decrypt(r));
139
+ if (target.trim() && !(0, links_1.isFragment)(target))
140
+ ctx.link(target, location, { sheet: (0, context_1.clip)(s.name), source: 'HLink record' });
141
+ }
142
+ }
143
+ }
144
+ /** Whether an Obj record (MS-XLS 2.4.181) holds an FtMacro subrecord, the macro a click runs. */
145
+ function objMacro(b) {
146
+ let at = 0;
147
+ while (at + 4 <= b.length) {
148
+ const ft = b[at] | (b[at + 1] << 8);
149
+ const cb = b[at + 2] | (b[at + 3] << 8);
150
+ // FtEnd ends the list, and FtLbsData's length does not count all its data, so the walk stops there.
151
+ if (ft === 0x00 || ft === 0x13)
152
+ return false;
153
+ if (ft === 0x04)
154
+ return cb > 0;
155
+ at += 4 + cb;
156
+ }
157
+ return false;
158
+ }
159
+ /** The target of an HLink record: its Hyperlink Object (MS-OSHARED 2.3.7.1) after the cell range and class id. */
160
+ function hyperlink(b) {
161
+ const r = new oleobj_1.ByteReader(b);
162
+ return (0, oleobj_1.bounded)(() => {
163
+ r.skip(8 + 16 + 4);
164
+ const flags = r.u32();
165
+ const string = () => (0, oleobj_1.utf16)(r.bytes(r.u32() * 2)).replace(/\0+$/, '');
166
+ if (flags & 0x10)
167
+ string();
168
+ if (flags & 0x80)
169
+ string();
170
+ if (!(flags & 0x01))
171
+ return '';
172
+ return flags & 0x100 ? string() : (0, oleobj_1.readMoniker)(r).target;
173
+ }, () => '');
174
+ }
package/dist/xlsb.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ export interface DdeLink {
2
+ application: string;
3
+ topic: string;
4
+ }
5
+ /**
6
+ * Reads the records of an .xlsb external link part as its chunks arrive, and collects its DDE links. Each record
7
+ * body is skipped, except the first 64 KiB of a BrtBeginSupBook. A header that breaks the record format ends the
8
+ * reading; Excel cannot read such a part either.
9
+ */
10
+ export declare class XlsbLinks {
11
+ readonly dde: DdeLink[];
12
+ private head;
13
+ private left;
14
+ private body;
15
+ private kept;
16
+ private broken;
17
+ write(chunk: Uint8Array): void;
18
+ private finish;
19
+ }
package/dist/xlsb.js ADDED
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.XlsbLinks = void 0;
4
+ /** BrtBeginSupBook, the record that opens each link of an .xlsb external link part. */
5
+ const BEGIN_SUPBOOK = 360;
6
+ /** The link type BrtBeginSupBook gives a DDE link. */
7
+ const SUPBOOK_DDE = 1;
8
+ /** How much of one BrtBeginSupBook is kept: far more than the two names of a DDE link need. */
9
+ const KEEP = 65536;
10
+ /**
11
+ * The record header at the start of `b`: the record's type and size, undefined while `b` is too short, or 'bad' when
12
+ * the header runs longer than the format allows. A type takes one or two bytes and a size one to four, seven bits to
13
+ * a byte, and a byte with its high bit clear ends each.
14
+ */
15
+ function header(b) {
16
+ let i = 0;
17
+ let type = 0;
18
+ for (let shift = 0;; shift += 7) {
19
+ if (i >= b.length)
20
+ return undefined;
21
+ type |= (b[i] & 0x7f) << shift;
22
+ if (!(b[i++] & 0x80))
23
+ break;
24
+ if (shift === 7)
25
+ return 'bad';
26
+ }
27
+ let size = 0;
28
+ for (let shift = 0;; shift += 7) {
29
+ if (i >= b.length)
30
+ return undefined;
31
+ size += (b[i] & 0x7f) * 2 ** shift;
32
+ if (!(b[i++] & 0x80))
33
+ break;
34
+ if (shift === 21)
35
+ return 'bad';
36
+ }
37
+ return { type, size };
38
+ }
39
+ /** An XLWideString at `at`: a 32-bit character count, then UTF-16LE. Cut short at the end of what was kept. */
40
+ function wideString(b, at) {
41
+ if (at + 4 > b.length)
42
+ return { text: '', next: b.length };
43
+ const end = Math.min(b.length, at + 4 + b.readUInt32LE(at) * 2);
44
+ return { text: b.toString('utf16le', at + 4, end), next: end };
45
+ }
46
+ /**
47
+ * Reads the records of an .xlsb external link part as its chunks arrive, and collects its DDE links. Each record
48
+ * body is skipped, except the first 64 KiB of a BrtBeginSupBook. A header that breaks the record format ends the
49
+ * reading; Excel cannot read such a part either.
50
+ */
51
+ class XlsbLinks {
52
+ dde = [];
53
+ head = [];
54
+ left = 0;
55
+ body;
56
+ kept = 0;
57
+ broken = false;
58
+ write(chunk) {
59
+ let i = 0;
60
+ while (i < chunk.length && !this.broken) {
61
+ if (this.left > 0) {
62
+ const n = Math.min(this.left, chunk.length - i);
63
+ if (this.body && this.kept < KEEP) {
64
+ const part = Buffer.from(chunk.subarray(i, i + Math.min(n, KEEP - this.kept)));
65
+ this.body.push(part);
66
+ this.kept += part.length;
67
+ }
68
+ this.left -= n;
69
+ i += n;
70
+ if (this.left === 0)
71
+ this.finish();
72
+ continue;
73
+ }
74
+ this.head.push(chunk[i++]);
75
+ const h = header(this.head);
76
+ if (h === undefined)
77
+ continue;
78
+ if (h === 'bad') {
79
+ this.broken = true;
80
+ return;
81
+ }
82
+ this.head = [];
83
+ this.body = h.type === BEGIN_SUPBOOK ? [] : undefined;
84
+ this.kept = 0;
85
+ this.left = h.size;
86
+ if (this.left === 0)
87
+ this.finish();
88
+ }
89
+ }
90
+ finish() {
91
+ if (!this.body)
92
+ return;
93
+ const b = Buffer.concat(this.body);
94
+ this.body = undefined;
95
+ if (b.length < 2 || b.readUInt16LE(0) !== SUPBOOK_DDE)
96
+ return;
97
+ const application = wideString(b, 2);
98
+ this.dde.push({ application: application.text, topic: wideString(b, application.next).text });
99
+ }
100
+ }
101
+ exports.XlsbLinks = XlsbLinks;
package/dist/xml.d.ts ADDED
@@ -0,0 +1,256 @@
1
+ export declare const XML_NS = "http://www.w3.org/XML/1998/namespace";
2
+ export declare const XMLNS_NS = "http://www.w3.org/2000/xmlns/";
3
+ /**
4
+ * Stands in text for a reference to an external entity, whose content office-defuse never fetches: UNKNOWN, the
5
+ * entity's name, UNKNOWN again. U+FFFF cannot occur in XML, so nothing a part holds is taken for it.
6
+ */
7
+ export declare const UNKNOWN: string;
8
+ /** A value with each reference to an external entity written back as `&name;`, for a finding to show. */
9
+ export declare const showReferences: (s: string) => string;
10
+ /** The name of the first external entity whose content stands in `s`, or undefined when none does. */
11
+ export declare const unknownEntity: (s: string) => string | undefined;
12
+ export interface XmlAttribute {
13
+ /** Namespace URI, '' for none. */
14
+ ns: string;
15
+ local: string;
16
+ qname: string;
17
+ /** Normalized value, with references expanded. An attribute-list declaration can give it a default or normalize it further. */
18
+ value: string;
19
+ }
20
+ export interface XmlElement {
21
+ /** Namespace URI, '' for none. */
22
+ ns: string;
23
+ local: string;
24
+ qname: string;
25
+ /** Attributes other than namespace declarations. */
26
+ attributes: XmlAttribute[];
27
+ /** 1 for the root element. */
28
+ depth: number;
29
+ /**
30
+ * Offsets of the start tag in the decoded text, end exclusive. An element from an entity's text has the offsets of
31
+ * the reference to that entity in the part, or of the outermost one when references nest.
32
+ */
33
+ start: number;
34
+ end: number;
35
+ }
36
+ export interface XmlHandler {
37
+ start?(el: XmlElement): void;
38
+ /** `start` and `end` are the offsets of the end tag, or of the start tag again for an empty element. */
39
+ end?(el: XmlElement, start: number, end: number): void;
40
+ /** Character data and CDATA content, decoded, in pieces of any size. A reference to an external entity comes as one piece. */
41
+ text?(text: string): void;
42
+ }
43
+ export interface XmlLimits {
44
+ depth: number;
45
+ tokenSize: number;
46
+ /** Entity references nested inside entity text. */
47
+ entityDepth: number;
48
+ /** Entity references expanded, counted in the budget. */
49
+ entityExpansions: number;
50
+ /** Characters of entity text expanded, counted in the budget. */
51
+ entitySize: number;
52
+ }
53
+ /** Entity expansion so far. One inspection shares it among its parts, so the limits bound the whole package. */
54
+ export interface EntityBudget {
55
+ expansions: number;
56
+ size: number;
57
+ }
58
+ /** A document type declaration. */
59
+ export interface XmlDoctype {
60
+ /** The root element type it names. */
61
+ name: string;
62
+ publicId?: string;
63
+ systemId?: string;
64
+ /** Whether it has an internal subset, declarations between square brackets. */
65
+ internalSubset: boolean;
66
+ /** General entities the internal subset declares, and how many of them are external. */
67
+ entities: number;
68
+ externalEntities: number;
69
+ /** Attribute defaults the internal subset declares. */
70
+ attributeDefaults: number;
71
+ /** Entity and attribute-list declarations skipped after a parameter entity that was not read. */
72
+ skipped: number;
73
+ /** Offsets of the declaration in the decoded text, end exclusive. */
74
+ start: number;
75
+ end: number;
76
+ }
77
+ /** A reference to an external entity in content, which is never fetched. */
78
+ export interface XmlExternalReference {
79
+ name: string;
80
+ publicId?: string;
81
+ systemId: string;
82
+ /** Offsets of the reference in the decoded text, or of the outermost reference whose entity text holds it. */
83
+ start: number;
84
+ end: number;
85
+ }
86
+ /** What the tokenizer reports besides elements and text. */
87
+ export interface XmlNotes {
88
+ doctype?(d: XmlDoctype): void;
89
+ externalEntity?(r: XmlExternalReference): void;
90
+ }
91
+ export interface XmlOptions {
92
+ /** Reads the dialect Office writes in VML drawing parts. See XmlTokenizer. */
93
+ vml?: boolean;
94
+ notes?: XmlNotes;
95
+ /** Shared with the other parts of a package. A tokenizer without one counts on its own. */
96
+ budget?: EntityBudget;
97
+ }
98
+ /** The value of the attribute with this namespace and local name. */
99
+ export declare function attr(el: XmlElement, ns: string, local: string): string | undefined;
100
+ /** An XML name without a colon. */
101
+ export declare const isNcName: (s: string) => boolean;
102
+ /**
103
+ * A streaming XML 1.0 tokenizer with namespaces. It refuses references to entities nothing declares, encodings other
104
+ * than UTF-8 and UTF-16, and anything not well-formed. It holds one markup token at a time; text goes to the handler
105
+ * in pieces.
106
+ *
107
+ * A document type declaration goes to `notes.doctype`. No external DTD or other external entity is ever loaded. The
108
+ * internal subset is read as XML 1.0 (5.1) has a processor read it that reads internal parameter entities and no
109
+ * external ones: it keeps the general entities and attribute-list declarations, reads the text of each internal
110
+ * parameter entity it refers to, and skips the entity and attribute-list declarations after a parameter entity it
111
+ * does not read, unless the XML declaration says standalone="yes".
112
+ *
113
+ * A reference to an internal entity is expanded, within the entity limits, and the handler sees its text, markup
114
+ * included, as if the part held it. A reference to an external entity in content goes to `notes.externalEntity`, and
115
+ * stands in the text as UNKNOWN marks it. One in an attribute value, directly or through other entities, is refused,
116
+ * as XML 1.0 refuses it. An attribute an element leaves out gets the default its attribute-list declaration gives, and
117
+ * an attribute declared with a type other than CDATA is normalized further, as expat does. Each default added counts
118
+ * as an expansion against the entity limits.
119
+ */
120
+ export declare class XmlTokenizer {
121
+ private readonly handler;
122
+ private readonly limits;
123
+ private readonly part;
124
+ private decoder?;
125
+ private head;
126
+ private buf;
127
+ private pos;
128
+ /** Offset in the decoded text of buf[0]. */
129
+ private base;
130
+ private readonly stack;
131
+ private rootSeen;
132
+ private doctypeSeen;
133
+ /** The XML declaration says standalone="yes". */
134
+ private standalone;
135
+ private encoding;
136
+ /** The last text piece ended in CR, so an LF that starts the next piece belongs to the same line end. */
137
+ private lastCr;
138
+ private scan?;
139
+ /** General entities the internal subset declares, by name. */
140
+ private readonly entities;
141
+ /** Parameter entities the internal subset declares, by name. */
142
+ private readonly parameters;
143
+ /** What the attribute-list declarations say, by element type as written. */
144
+ private readonly declared;
145
+ /** The entities being expanded, outermost first. A parameter entity's name has "%" in front. */
146
+ private readonly active;
147
+ /** While entity text is read, the offsets of the outermost reference, which its elements report. */
148
+ private span?;
149
+ /** The stack depth at which the entity text being read started. Its end tags close nothing below it. */
150
+ private floor;
151
+ private readonly vml;
152
+ private readonly notes;
153
+ private readonly budget;
154
+ /**
155
+ * `options.vml` reads the dialect Office writes in VML drawing parts, which is not well-formed XML: it skips the
156
+ * `<![if ...]>` and `<![endif]>` markers around content and takes an unclosed `<br>` as an empty element. Both
157
+ * branches of a marker reach the handler.
158
+ */
159
+ constructor(handler: XmlHandler, limits: XmlLimits, part: string, options?: XmlOptions);
160
+ private stop;
161
+ private malformed;
162
+ write(bytes: Uint8Array): void;
163
+ end(): void;
164
+ /** Picks the encoding from the first bytes, as XML 1.0 Appendix F does, and reads the bytes held so far. */
165
+ private begin;
166
+ private decode;
167
+ /** Checks the XML declaration against the encoding the bytes are in, and notes whether it says standalone="yes". */
168
+ private declaration;
169
+ private feed;
170
+ /** Reads the text and markup in buf from pos. Entity text is read with `final` set, since all of it is there. */
171
+ private loop;
172
+ /** The offset in the decoded text of buf[i], or while entity text is read, that of the reference to it. */
173
+ private at;
174
+ /**
175
+ * Character data at `offset` in the decoded text. References are expanded and line ends turned into LF. Entity
176
+ * text had its line ends normalized where it was declared, so a CR in it, which only a character reference makes,
177
+ * stays.
178
+ */
179
+ private text;
180
+ /** Hands decoded text to the handler. Outside the root element only white space may stand. */
181
+ private characters;
182
+ /**
183
+ * Normalizes an attribute value as XML 1.0 (3.3.3) says: references expanded, and each white space character a
184
+ * space, except one written as a character reference. `normalized` marks entity text, whose line ends were
185
+ * normalized where it was declared, so a CR and LF in it are two characters.
186
+ */
187
+ private attributeValue;
188
+ /** The text a predefined entity or a character reference stands for, or undefined for any other entity. */
189
+ private plainReference;
190
+ private characterReference;
191
+ /** The entity a reference names. A reference to one nothing declares is refused. */
192
+ private entity;
193
+ /** Starts expanding an entity, within the limits. */
194
+ private enter;
195
+ /**
196
+ * Counts one expansion of `size` characters of declared text, an entity's or an attribute default's, against the
197
+ * limits, so a document type cannot make the part cost more than they allow.
198
+ */
199
+ private charge;
200
+ /** A reference to a general entity in content. Its text is read as content, in place of the reference. */
201
+ private contentReference;
202
+ /** A reference to a general entity in an attribute value. Its text is normalized into the value. */
203
+ private attributeReference;
204
+ /** Reads one markup token at pos. Returns false when the buffer does not yet hold all of it. */
205
+ private markup;
206
+ private wait;
207
+ private advance;
208
+ private checkChars;
209
+ private instruction;
210
+ /**
211
+ * Finds the end of the document type declaration at p: the ">" outside its literals and its internal subset, where
212
+ * comments, processing instructions and declarations may hold either. Returns the offset after it, or -1 when buf
213
+ * does not hold all of it yet. The scan goes on from where it stopped.
214
+ */
215
+ private scanDoctype;
216
+ /** Reads a whole document type declaration, keeping the entities and attributes its internal subset declares. */
217
+ private doctype;
218
+ /** SYSTEM and a system literal, or PUBLIC and a public and a system literal, or undefined when neither is next. */
219
+ private externalId;
220
+ /**
221
+ * Reads markup declarations: the internal subset up to and past its "]", or with `nested` the whole text of a
222
+ * parameter entity.
223
+ */
224
+ private declarations;
225
+ /**
226
+ * A parameter entity reference between declarations. An internal entity's text is read as declarations, with a
227
+ * space on each side as XML 1.0 (4.4.8) says. An external or undeclared one is not read, and the entity and
228
+ * attribute-list declarations after it are skipped, since it could have declared the same names first.
229
+ */
230
+ private parameterReference;
231
+ /**
232
+ * Reads an entity declaration after its keyword, and keeps the entity unless it comes after a parameter entity that
233
+ * was not read, or gives one of the predefined names, or a name already declared: the first declaration binds.
234
+ */
235
+ private entityDeclaration;
236
+ /**
237
+ * The text an entity value expands to: line ends normalized, unless `normalized` says they were, and character
238
+ * references replaced. References to general entities stay as written, to be expanded where the entity is used. A
239
+ * parameter entity reference cannot stand inside a declaration in the internal subset.
240
+ */
241
+ private entityValue;
242
+ /**
243
+ * Reads an attribute-list declaration after its keyword. Each attribute it names for the first time is kept, with
244
+ * its default normalized now, as the entities declared so far give it. After a parameter entity that was not read,
245
+ * the declaration is skipped.
246
+ */
247
+ private attributeListDeclaration;
248
+ /** Reads an attribute type and tells whether its values are tokens, normalized further than CDATA. */
249
+ private attributeType;
250
+ /** An enumerated type: name tokens between parentheses, separated by "|". */
251
+ private enumeration;
252
+ private lookup;
253
+ private split;
254
+ private startTag;
255
+ private endTag;
256
+ }