tag-soup-ng 0.0.1-security → 1.1.10

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.

Potentially problematic release.


This version of tag-soup-ng might be problematic. Click here for more details.

@@ -0,0 +1,425 @@
1
+ /**
2
+ * An array-like object that is used instead of actual arrays to avoid performance penalty associated with `length`
3
+ * updates.
4
+ *
5
+ * @template T The type of an element.
6
+ */
7
+ export interface IArrayLike<T> {
8
+ [index: number]: T;
9
+ length: number;
10
+ }
11
+ /**
12
+ * The type of the token produced by the SAX parser.
13
+ */
14
+ export declare const enum TokenType {
15
+ START_TAG = 1,
16
+ END_TAG = 101,
17
+ ATTRIBUTE = 2,
18
+ DOCTYPE = 10,
19
+ TEXT = 3,
20
+ CDATA_SECTION = 4,
21
+ PROCESSING_INSTRUCTION = 7,
22
+ COMMENT = 8
23
+ }
24
+ /**
25
+ * A token provided to SAX handler callback.
26
+ */
27
+ export declare type Token = IStartTagToken | IEndTagToken | IAttributeToken | IDoctypeToken | ITextToken | ICdataSectionToken | IProcessingInstructionToken | ICommentToken;
28
+ /**
29
+ * The token read from the source.
30
+ */
31
+ export interface IToken {
32
+ /**
33
+ * The type of the token.
34
+ */
35
+ tokenType: TokenType;
36
+ /**
37
+ * The index where the token starts.
38
+ */
39
+ start: number;
40
+ /**
41
+ * The index where the token ends.
42
+ */
43
+ end: number;
44
+ /**
45
+ * Returns the deep clone of the token.
46
+ */
47
+ clone(): this;
48
+ }
49
+ /**
50
+ * The tag token.
51
+ */
52
+ export interface ITagToken extends IToken {
53
+ /**
54
+ * The tag name as it was read from the source.
55
+ */
56
+ rawName: string;
57
+ /**
58
+ * The tag name after {@link IParserOptions.renameTag} was applied.
59
+ */
60
+ name: string;
61
+ /**
62
+ * The index where the {@link rawName} starts or -1 if this tag doesn't actually present in the source.
63
+ */
64
+ nameStart: number;
65
+ /**
66
+ * The index where the {@link rawName} ends or -1 if this tag doesn't actually present in the source.
67
+ */
68
+ nameEnd: number;
69
+ }
70
+ /**
71
+ * The character data token.
72
+ */
73
+ export interface IDataToken extends IToken {
74
+ /**
75
+ * The data as it was read from the source.
76
+ */
77
+ rawData: string;
78
+ /**
79
+ * The data after {@link IParserOptions.decodeText} was applied.
80
+ */
81
+ data: string;
82
+ /**
83
+ * The index where the {@link rawData} starts.
84
+ */
85
+ dataStart: number;
86
+ /**
87
+ * The index where the {@link rawData} ends.
88
+ */
89
+ dataEnd: number;
90
+ }
91
+ /**
92
+ * The start tag token.
93
+ */
94
+ export interface IStartTagToken extends ITagToken {
95
+ tokenType: TokenType.START_TAG;
96
+ /**
97
+ * The list of attributes.
98
+ *
99
+ * This array-like object and {@link IAttributeToken} objects that it contains are pooled. They all are revoked after
100
+ * the handler callback finishes. Make a deep copy using {@link IToken.clone} to retain a token.
101
+ *
102
+ * Object pooling is used to reduce memory consumption during parsing by avoiding excessive object allocation.
103
+ */
104
+ attributes: IArrayLike<IAttributeToken>;
105
+ /**
106
+ * `true` if tag is self-closing, `false` otherwise.
107
+ *
108
+ * @see {@link IParserOptions.selfClosingEnabled}
109
+ */
110
+ selfClosing: boolean;
111
+ }
112
+ /**
113
+ * The end tag token.
114
+ */
115
+ export interface IEndTagToken extends ITagToken {
116
+ tokenType: TokenType.END_TAG;
117
+ }
118
+ /**
119
+ * The tag attribute token.
120
+ */
121
+ export interface IAttributeToken extends IToken {
122
+ tokenType: TokenType.ATTRIBUTE;
123
+ /**
124
+ * The name of the attribute as it was read from the source.
125
+ */
126
+ rawName: string;
127
+ /**
128
+ * The name of the attribute after {@link IParserOptions.renameAttribute} was applied.
129
+ */
130
+ name: string;
131
+ /**
132
+ * The index where {@link rawName} starts.
133
+ */
134
+ nameStart: number;
135
+ /**
136
+ * The index where {@link rawName} ends.
137
+ */
138
+ nameEnd: number;
139
+ /**
140
+ * The value of the attribute as it was read from the source.
141
+ *
142
+ * If value is omitted and name is followed by "=" char like `foo=` then {@link rawValue} is `null`. If value is
143
+ * omitted and name isn't followed by a "=" char like `foo` then {@link rawValue} is `undefined`.
144
+ */
145
+ rawValue: string | null | undefined;
146
+ /**
147
+ * The value of the attribute after {@link IParserOptions.decodeAttribute} was applied.
148
+ *
149
+ * If value is omitted and name is followed by "=" char like `foo=` then {@link value} is `null`. If value is omitted
150
+ * and name isn't followed by a "=" char like `foo` then {@link value} is `undefined`.
151
+ */
152
+ value: string | null | undefined;
153
+ /**
154
+ * The index where {@link rawValue} starts or -1 if value was omitted.
155
+ */
156
+ valueStart: number;
157
+ /**
158
+ * The index where {@link rawValue} ends or -1 if value was omitted.
159
+ */
160
+ valueEnd: number;
161
+ /**
162
+ * `true` if {@link rawValue} was surrounded with quotes.
163
+ */
164
+ quoted: boolean;
165
+ }
166
+ /**
167
+ * The DOCTYPE token.
168
+ */
169
+ export interface IDoctypeToken extends IDataToken {
170
+ tokenType: TokenType.DOCTYPE;
171
+ }
172
+ /**
173
+ * The text token.
174
+ */
175
+ export interface ITextToken extends IDataToken {
176
+ tokenType: TokenType.TEXT;
177
+ }
178
+ /**
179
+ * The CDATA section token `<![CDATA[ … ]]>`.
180
+ */
181
+ export interface ICdataSectionToken extends IDataToken {
182
+ tokenType: TokenType.CDATA_SECTION;
183
+ }
184
+ /**
185
+ * The processing instruction token `<?xml-stylesheet … ?>`.
186
+ */
187
+ export interface IProcessingInstructionToken extends IDataToken {
188
+ tokenType: TokenType.PROCESSING_INSTRUCTION;
189
+ }
190
+ /**
191
+ * The comment token `<!-- … -->`.
192
+ */
193
+ export interface ICommentToken extends IDataToken {
194
+ tokenType: TokenType.COMMENT;
195
+ }
196
+ /**
197
+ * The streaming parser.
198
+ *
199
+ * @template The type of the result returned by {@link IParser.write} and {@link IParser.parse} methods.
200
+ */
201
+ export interface IParser<Result> {
202
+ /**
203
+ * Tries to parse a given source chunk. If there's an ambiguity during parsing then the parser is paused until the
204
+ * next {@link write} or {@link parse} invocation. The part of chunk that wasn't parsed is appended to an internal
205
+ * buffer.
206
+ *
207
+ * @param sourceChunk The source chunk to parse.
208
+ */
209
+ write(sourceChunk: string): Result;
210
+ /**
211
+ * Parses the source. If there's a leftover in the internal buffer after the last {@link write} call it is also used
212
+ * for parsing. Parser is reset after parsing is completed.
213
+ *
214
+ * @param source The source to parse. If omitted then content of the internal buffer is parsed.
215
+ */
216
+ parse(source?: string): Result;
217
+ /**
218
+ * Clears the internal buffer and resets the parser state.
219
+ */
220
+ reset(): void;
221
+ }
222
+ /**
223
+ * Options of a parser.
224
+ */
225
+ export interface IParserOptions {
226
+ /**
227
+ * Toggles CDATA sections recognition `<![CDATA[ … ]]>`. If set to `false` then CDATA sections are treated as
228
+ * comments.
229
+ */
230
+ cdataEnabled?: boolean;
231
+ /**
232
+ * Toggles processing instructions recognition `<?xml-stylesheet … ?>`. If set to `false` then processing
233
+ * instructions are treated as comments.
234
+ */
235
+ processingInstructionsEnabled?: boolean;
236
+ /**
237
+ * Toggles self-closing tags recognition `<foo/>`. If set to `false` then slash in self closing tags is ignored or
238
+ * processed as a part of an attribute value, depending on the markup.
239
+ */
240
+ selfClosingEnabled?: boolean;
241
+ /**
242
+ * Decodes XML entities in a plain text value.
243
+ *
244
+ * @param text The text to decode.
245
+ * @return The decoded text.
246
+ */
247
+ decodeText?(text: string): string;
248
+ /**
249
+ * Decodes XML entities in an attribute value. If omitted then {@link decodeText} callback is used.
250
+ *
251
+ * @param value The attribute value to decode.
252
+ * @return The decoded value.
253
+ */
254
+ decodeAttribute?(value: string): string;
255
+ /**
256
+ * Rewrites a tag name. Start and end tags are matched via tag name comparison. Provide a rewriter to support
257
+ * case-insensitive tag matching.
258
+ *
259
+ * @param name The raw name of the tag.
260
+ * @returns The rewritten name of the tag.
261
+ */
262
+ renameTag?(name: string): string;
263
+ /**
264
+ * Rewrites an attribute name.
265
+ *
266
+ * @param name The raw name of the attribute.
267
+ * @returns The rewritten name of the attribute.
268
+ */
269
+ renameAttribute?(name: string): string;
270
+ /**
271
+ * Checks whether the content of the container tag should be interpreted as a markup or as a character data. Entities
272
+ * aren't decoded in the content of character data tags. Useful when parsing such tags as `script`, `style` and
273
+ * others.
274
+ *
275
+ * @param token The start tag token read from the source.
276
+ * @returns `true` to interpret the contents of the `token` container tag as a character data, `false` otherwise.
277
+ */
278
+ checkCdataTag?(token: IStartTagToken): boolean;
279
+ /**
280
+ * Checks whether the tag has no content. Useful when parsing such tags as `hr`, `img` and others.
281
+ *
282
+ * @param token The start tag token.
283
+ * @returns `true` to interpret tag as self-closing even if it isn't marked up as such, `false` otherwise.
284
+ */
285
+ checkVoidTag?(token: IStartTagToken): boolean;
286
+ /**
287
+ * Inspects ancestors and returns an index of an ancestor for which end tag is implied. Useful when parsing such tags
288
+ * as `p`, `li`, `td` and others.
289
+ *
290
+ * @param ancestors The list of start tag tokens of current ancestors.
291
+ * @param token The token of the start tag that was read.
292
+ * @returns The index among `ancestors` that points to an ancestor for which an end tag is implied or -1 if no
293
+ * implicit end detected.
294
+ */
295
+ endsAncestorAt?(ancestors: ArrayLike<IStartTagToken>, token: IStartTagToken): number;
296
+ }
297
+ /**
298
+ * Parser-related handler callbacks.
299
+ */
300
+ export interface IHandler {
301
+ /**
302
+ * Triggered when parsing of the source is completed.
303
+ *
304
+ * @param sourceLength The number of chars that were read from the source.
305
+ */
306
+ sourceEnd?(sourceLength: number): void;
307
+ /**
308
+ * Triggered when the parser internal state was reset.
309
+ */
310
+ reset?(): void;
311
+ }
312
+ /**
313
+ * Defines callbacks that are invoked during SAX parsing.
314
+ *
315
+ * **Note:** Don't keep references to tokens! Tokens passed to the handler callbacks are pooled objects that are reused
316
+ * by the parser after callback finishes. Make a deep copy using {@link IToken.clone} to retain a token.
317
+ */
318
+ export interface ISaxHandler extends IHandler {
319
+ /**
320
+ * Triggered when a start tag and its attributes were read.
321
+ *
322
+ * @param token The start tag token.
323
+ */
324
+ startTag?(token: IStartTagToken): void;
325
+ /**
326
+ * Triggered when an end tag was read.
327
+ *
328
+ * @param token The end tag token.
329
+ */
330
+ endTag?(token: IEndTagToken): void;
331
+ /**
332
+ * Triggered when a text was read.
333
+ *
334
+ * @param token The text token.
335
+ */
336
+ text?(token: ITextToken): void;
337
+ /**
338
+ * Triggered when a comment was read.
339
+ *
340
+ * @param token The comment token.
341
+ */
342
+ comment?(token: ICommentToken): void;
343
+ /**
344
+ * Triggered when a DOCTYPE was read.
345
+ *
346
+ * @param token The DOCTYPE token.
347
+ */
348
+ doctype?(token: IDoctypeToken): void;
349
+ /**
350
+ * Triggered when a processing instruction was read.
351
+ *
352
+ * @param token The processing instruction token.
353
+ */
354
+ processingInstruction?(token: IProcessingInstructionToken): void;
355
+ /**
356
+ * Triggered when a CDATA section was read.
357
+ *
358
+ * @param token The CDATA section token.
359
+ */
360
+ cdata?(token: ICdataSectionToken): void;
361
+ }
362
+ /**
363
+ * Defines node factories and callbacks that are invoked during DOM parsing.
364
+ *
365
+ * **Note:** Don't keep references to tokens! Tokens passed to some of the handler callbacks are pooled objects that
366
+ * are reused by the parser after callback finishes. Make a deep copy using {@link IToken.clone} to retain a token.
367
+ */
368
+ export interface IDomHandler<Node, ContainerNode extends Node> extends IHandler {
369
+ /**
370
+ * Creates a new element node.
371
+ *
372
+ * @param token The start tag token that denotes the opened element.
373
+ * @returns The new element node.
374
+ */
375
+ element(token: IStartTagToken): ContainerNode;
376
+ /**
377
+ * Triggered when the `node` must be added to the list of children of the `parentNode`.
378
+ *
379
+ * @param parentNode The container node to which `node` must be appended.
380
+ * @param node The node to append to `parentNode` as a child.
381
+ */
382
+ appendChild(parentNode: ContainerNode, node: Node): void;
383
+ /**
384
+ * Triggered when an element or a document was fully read from source.
385
+ *
386
+ * @param node The element or document node for which the end token was read.
387
+ * @param token The token that closes the container.
388
+ */
389
+ containerEnd?(node: ContainerNode, token: Token): void;
390
+ /**
391
+ * Creates a new text node.
392
+ *
393
+ * @param token The text token.
394
+ * @returns The DOM node that describes a text.
395
+ */
396
+ text?(token: ITextToken): Node;
397
+ /**
398
+ * Creates a new document node when a DOCTYPE was read.
399
+ *
400
+ * @param token The DOCTYPE token.
401
+ * @returns The DOM node that document container.
402
+ */
403
+ document?(token: IDoctypeToken): ContainerNode;
404
+ /**
405
+ * Creates a new comment node.
406
+ *
407
+ * @param token The comment token.
408
+ * @returns The DOM node that describes a comment.
409
+ */
410
+ comment?(token: ICommentToken): Node;
411
+ /**
412
+ * Creates a new processing instruction node.
413
+ *
414
+ * @param token The processing instruction token.
415
+ * @returns The DOM node that describes a processing instruction.
416
+ */
417
+ processingInstruction?(token: IProcessingInstructionToken): Node;
418
+ /**
419
+ * Creates a new CDATA section node.
420
+ *
421
+ * @param token The CDATA section token.
422
+ * @returns The DOM node that describes a CDATA section.
423
+ */
424
+ cdata?(token: ICdataSectionToken): Node;
425
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The type of the token produced by the SAX parser.
3
+ */
4
+ export var TokenType;
5
+ (function (TokenType) {
6
+ TokenType[TokenType["START_TAG"] = 1] = "START_TAG";
7
+ TokenType[TokenType["END_TAG"] = 101] = "END_TAG";
8
+ TokenType[TokenType["ATTRIBUTE"] = 2] = "ATTRIBUTE";
9
+ TokenType[TokenType["DOCTYPE"] = 10] = "DOCTYPE";
10
+ TokenType[TokenType["TEXT"] = 3] = "TEXT";
11
+ TokenType[TokenType["CDATA_SECTION"] = 4] = "CDATA_SECTION";
12
+ TokenType[TokenType["PROCESSING_INSTRUCTION"] = 7] = "PROCESSING_INSTRUCTION";
13
+ TokenType[TokenType["COMMENT"] = 8] = "COMMENT";
14
+ })(TokenType || (TokenType = {}));
@@ -0,0 +1,34 @@
1
+ import { ObjectPool } from '@smikhalevski/object-pool';
2
+ import { IArrayLike, IAttributeToken, IDataToken, IEndTagToken, IParserOptions, ISaxHandler, IStartTagToken } from './parser-types';
3
+ /**
4
+ * Reads attributes from the source.
5
+ *
6
+ * @param chunk The string to read attributes from.
7
+ * @param index The index in `chunk` from which to start reading.
8
+ * @param chunkOffset The offset of the `chunk` in scope of the whole input.
9
+ * @param attributes An array-like object to which {@link IAttributeToken} objects are added.
10
+ * @param options Tokenization options.
11
+ * @param parserOptions Parsing options.
12
+ * @returns The index in `chunk` at which reading was completed.
13
+ */
14
+ export declare function tokenizeAttributes(chunk: string, index: number, chunkOffset: number, attributes: IArrayLike<IAttributeToken>, options: ITokenizerOptions, parserOptions: IParserOptions): number;
15
+ export interface ITokenizerOptions {
16
+ startTagTokenPool: ObjectPool<IStartTagToken>;
17
+ attributeTokenPool: ObjectPool<IAttributeToken>;
18
+ endTagToken: IEndTagToken;
19
+ dataToken: IDataToken;
20
+ }
21
+ /**
22
+ * Reads markup tokens from the string.
23
+ *
24
+ * **Note:** Tokenizer doesn't return allocated tokens back to pools.
25
+ *
26
+ * @param chunk The chunk of the input to read tokens from.
27
+ * @param streaming If set to `true` then tokenizer stops when an ambiguous char sequence is met.
28
+ * @param chunkOffset The offset of the `chunk` in scope of the whole input.
29
+ * @param options Tokenization options.
30
+ * @param parserOptions Parsing options.
31
+ * @param handler SAX handler that is notified about parsed tokens.
32
+ * @returns The index in `chunk` right after the last parsed character.
33
+ */
34
+ export declare function tokenize(chunk: string, streaming: boolean, chunkOffset: number, options: ITokenizerOptions, parserOptions: IParserOptions, handler: ISaxHandler): number;