@poe-platform/safe-fs 0.1.813 → 0.1.815
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/xml-ast/index.d.ts +3 -1
- package/dist/xml-ast/index.js +77 -80
- package/package.json +1 -1
package/dist/xml-ast/index.d.ts
CHANGED
|
@@ -54,7 +54,9 @@ export interface XmlStepLimits extends XmlLimits {
|
|
|
54
54
|
readonly events?: (event: XmlStreamEvent) => void;
|
|
55
55
|
}
|
|
56
56
|
export interface XmlSourceLimits extends XmlStepLimits {
|
|
57
|
-
/**
|
|
57
|
+
/** Keep normalized declaration fields instead of the complete source spelling. */
|
|
58
|
+
readonly compactDeclaration?: boolean;
|
|
59
|
+
/** Emit content bodies in bounded fragments, marking continuations of the same logical
|
|
58
60
|
* node. Requires retainTree: false; consumers must preserve fragment identity. */
|
|
59
61
|
readonly fragmentContent?: boolean;
|
|
60
62
|
/** Store active parser frames through host-serviced requests. Requires retainTree: false. */
|
package/dist/xml-ast/index.js
CHANGED
|
@@ -176,11 +176,10 @@ function* entities(text, recover) {
|
|
|
176
176
|
}
|
|
177
177
|
return result;
|
|
178
178
|
}
|
|
179
|
-
function*
|
|
180
|
-
let offset = 0;
|
|
179
|
+
function* readDeclaration(source, offset, end, expectedEncoding) {
|
|
181
180
|
const whitespace = function* () {
|
|
182
181
|
const start = offset;
|
|
183
|
-
while (offset <
|
|
182
|
+
while (offset < end && " \t\n\r".includes(yield* source.slice(offset, offset + 1))) {
|
|
184
183
|
offset++;
|
|
185
184
|
if ((offset - start) % 512 === 0)
|
|
186
185
|
yield 512;
|
|
@@ -189,53 +188,58 @@ function* validDeclaration(content, expectedEncoding) {
|
|
|
189
188
|
yield (offset - start) % 512;
|
|
190
189
|
return offset - start;
|
|
191
190
|
};
|
|
192
|
-
const field = function* (name) {
|
|
193
|
-
if (
|
|
191
|
+
const field = function* (name, maxLength) {
|
|
192
|
+
if ((yield* source.slice(offset, Math.min(end, offset + name.length))) !== name)
|
|
194
193
|
return undefined;
|
|
195
194
|
offset += name.length;
|
|
196
195
|
yield name.length;
|
|
197
196
|
yield* whitespace();
|
|
198
|
-
if (
|
|
197
|
+
if (offset >= end || (yield* source.charCodeAt(offset++)) !== 61)
|
|
199
198
|
return undefined;
|
|
200
199
|
yield* whitespace();
|
|
201
|
-
|
|
200
|
+
if (offset >= end)
|
|
201
|
+
return undefined;
|
|
202
|
+
const quote = yield* source.slice(offset++, offset);
|
|
202
203
|
if (quote !== "'" && quote !== '"')
|
|
203
204
|
return undefined;
|
|
204
205
|
const start = offset;
|
|
205
|
-
while (offset <
|
|
206
|
+
while (offset < end && (yield* source.slice(offset, offset + 1)) !== quote) {
|
|
206
207
|
offset++;
|
|
207
208
|
if ((offset - start) % 512 === 0)
|
|
208
209
|
yield 512;
|
|
209
210
|
}
|
|
210
211
|
if ((offset - start) % 512)
|
|
211
212
|
yield (offset - start) % 512;
|
|
212
|
-
if (offset >=
|
|
213
|
+
if (offset >= end || offset - start > maxLength)
|
|
213
214
|
return undefined;
|
|
214
|
-
return
|
|
215
|
+
return yield* source.slice(start, offset++);
|
|
215
216
|
};
|
|
216
|
-
if (!(yield* whitespace()) || (yield* field("version")) !== "1.0")
|
|
217
|
-
return
|
|
217
|
+
if (!(yield* whitespace()) || (yield* field("version", 3)) !== "1.0")
|
|
218
|
+
return undefined;
|
|
219
|
+
let result = '<?xml version="1.0"';
|
|
218
220
|
let spacing = yield* whitespace();
|
|
219
|
-
if (
|
|
221
|
+
if ((yield* source.slice(offset, Math.min(end, offset + 8))) === "encoding") {
|
|
220
222
|
if (!spacing)
|
|
221
|
-
return
|
|
222
|
-
const encoding = yield* field("encoding");
|
|
223
|
-
if (encoding === undefined ||
|
|
224
|
-
return
|
|
223
|
+
return undefined;
|
|
224
|
+
const encoding = yield* field("encoding", 8);
|
|
225
|
+
if (encoding === undefined || !["utf-8", "utf-16", "utf-16le", "utf-16be"].includes(encoding.toLowerCase()))
|
|
226
|
+
return undefined;
|
|
225
227
|
if (expectedEncoding !== undefined && encoding.toLowerCase() !== expectedEncoding.toLowerCase()
|
|
226
228
|
&& !(encoding.toLowerCase() === "utf-16" && (expectedEncoding === "UTF-16LE" || expectedEncoding === "UTF-16BE")))
|
|
227
|
-
return
|
|
229
|
+
return undefined;
|
|
230
|
+
result += ` encoding="${encoding}"`;
|
|
228
231
|
spacing = yield* whitespace();
|
|
229
232
|
}
|
|
230
|
-
if (
|
|
233
|
+
if ((yield* source.slice(offset, Math.min(end, offset + 10))) === "standalone") {
|
|
231
234
|
if (!spacing)
|
|
232
|
-
return
|
|
233
|
-
const standalone = yield* field("standalone");
|
|
234
|
-
if (standalone === undefined ||
|
|
235
|
-
return
|
|
235
|
+
return undefined;
|
|
236
|
+
const standalone = yield* field("standalone", 3);
|
|
237
|
+
if (standalone === undefined || !["yes", "no"].includes(standalone))
|
|
238
|
+
return undefined;
|
|
239
|
+
result += ` standalone="${standalone}"`;
|
|
236
240
|
yield* whitespace();
|
|
237
241
|
}
|
|
238
|
-
return offset ===
|
|
242
|
+
return offset === end ? result + "?>" : undefined;
|
|
239
243
|
}
|
|
240
244
|
function validateLimits(limits) {
|
|
241
245
|
for (const limit of [limits.maxDepth, limits.maxNodes, limits.maxAttributes, limits.maxContentNodes, limits.maxAttributesPerElement, limits.maxNamespaces]) {
|
|
@@ -326,6 +330,33 @@ export function* parseXmlSourceSteps(length, limits = {}) {
|
|
|
326
330
|
const [prefix, localName] = qualifiedNameSync(name, qualifiedNames);
|
|
327
331
|
return [name, prefix, localName];
|
|
328
332
|
};
|
|
333
|
+
const rawContent = function* (kind, start, end, parent, target = "") {
|
|
334
|
+
if (end - start > maxTextLength - textLength)
|
|
335
|
+
throw new XmlLimitError("maxTextLength", "XML text limit exceeded");
|
|
336
|
+
textLength += end - start;
|
|
337
|
+
admitContent();
|
|
338
|
+
let cursor = start, continuation = false;
|
|
339
|
+
do {
|
|
340
|
+
let finish = limits.fragmentContent ? Math.min(end, cursor + 512) : end;
|
|
341
|
+
if (finish < end) {
|
|
342
|
+
const last = yield* source.charCodeAt(finish - 1);
|
|
343
|
+
if (last >= 0xd800 && last <= 0xdbff)
|
|
344
|
+
finish--;
|
|
345
|
+
}
|
|
346
|
+
const text = yield* source.slice(cursor, finish);
|
|
347
|
+
const content = kind === "processing-instruction" ? { kind, target, text } : { kind, text };
|
|
348
|
+
if (kind === "cdata" && retainTree)
|
|
349
|
+
parent.element.text += text;
|
|
350
|
+
if (retain)
|
|
351
|
+
(parent?.content ?? (root ? epilog : prolog)).push(content);
|
|
352
|
+
limits.events?.({ type: "content", content, parent: parent?.element,
|
|
353
|
+
...(continuation ? { continuation: true } : {}) });
|
|
354
|
+
if (limits.fragmentContent)
|
|
355
|
+
yield Math.max(1, text.length);
|
|
356
|
+
continuation = true;
|
|
357
|
+
cursor = finish;
|
|
358
|
+
} while (cursor < end);
|
|
359
|
+
};
|
|
329
360
|
while (yield* source.has(offset)) {
|
|
330
361
|
pendingWork += 1;
|
|
331
362
|
if (pendingWork >= 512) {
|
|
@@ -431,17 +462,10 @@ export function* parseXmlSourceSteps(length, limits = {}) {
|
|
|
431
462
|
}
|
|
432
463
|
else if ((yield* source.startsWith("<!--", offset))) {
|
|
433
464
|
const end = yield* find(source, "-->", offset + 4);
|
|
434
|
-
|
|
435
|
-
|
|
465
|
+
if (end < 0 || (yield* source.indexOf("--", offset + 4, end)) >= 0
|
|
466
|
+
|| (end > offset + 4 && (yield* source.charCodeAt(end - 1)) === 45))
|
|
436
467
|
invalid("malformed comment");
|
|
437
|
-
|
|
438
|
-
const parent = (yield* stack.peek());
|
|
439
|
-
admitText(text);
|
|
440
|
-
admitContent();
|
|
441
|
-
if (retain) {
|
|
442
|
-
(parent?.content ?? (root ? epilog : prolog)).push({ kind: "comment", text });
|
|
443
|
-
}
|
|
444
|
-
limits.events?.({ type: "content", content: { kind: "comment", text }, parent: parent?.element });
|
|
468
|
+
yield* rawContent("comment", offset + 4, end, yield* stack.peek());
|
|
445
469
|
offset = end + 3;
|
|
446
470
|
}
|
|
447
471
|
else if ((yield* source.startsWith("<![CDATA[", offset))) {
|
|
@@ -450,32 +474,7 @@ export function* parseXmlSourceSteps(length, limits = {}) {
|
|
|
450
474
|
const end = yield* find(source, "]]>", offset + 9);
|
|
451
475
|
if (end < 0)
|
|
452
476
|
invalid("unterminated CDATA");
|
|
453
|
-
|
|
454
|
-
throw new XmlLimitError("maxTextLength", "XML text limit exceeded");
|
|
455
|
-
const parent = (yield* stack.peek());
|
|
456
|
-
admitContent();
|
|
457
|
-
let cursor = offset + 9, continuation = false;
|
|
458
|
-
do {
|
|
459
|
-
let finish = limits.fragmentContent ? Math.min(end, cursor + 512) : end;
|
|
460
|
-
if (finish < end) {
|
|
461
|
-
const last = yield* source.charCodeAt(finish - 1);
|
|
462
|
-
if (last >= 0xd800 && last <= 0xdbff)
|
|
463
|
-
finish--;
|
|
464
|
-
}
|
|
465
|
-
const text = yield* source.slice(cursor, finish);
|
|
466
|
-
admitText(text);
|
|
467
|
-
if (retainTree)
|
|
468
|
-
parent.element.text += text;
|
|
469
|
-
if (retain)
|
|
470
|
-
parent.content.push({ kind: "cdata", text });
|
|
471
|
-
limits.events?.({ type: "content", content: { kind: "cdata", text }, parent: parent.element,
|
|
472
|
-
...(continuation ? { continuation: true } : {}) });
|
|
473
|
-
// Let external consumers persist each fragment before producing another.
|
|
474
|
-
if (limits.fragmentContent)
|
|
475
|
-
yield Math.max(1, text.length);
|
|
476
|
-
continuation = true;
|
|
477
|
-
cursor = finish;
|
|
478
|
-
} while (cursor < end);
|
|
477
|
+
yield* rawContent("cdata", offset + 9, end, yield* stack.peek());
|
|
479
478
|
offset = end + 3;
|
|
480
479
|
}
|
|
481
480
|
else if ((yield* source.startsWith("<?", offset))) {
|
|
@@ -489,34 +488,32 @@ export function* parseXmlSourceSteps(length, limits = {}) {
|
|
|
489
488
|
const end = yield* find(source, "?>", offset);
|
|
490
489
|
if (end < 0)
|
|
491
490
|
invalid("unterminated processing instruction");
|
|
492
|
-
const content = (yield* source.slice(offset, end));
|
|
493
491
|
if (target.length === 3 && target.toLowerCase() === "xml") {
|
|
494
|
-
if (start !== 0 || target !== "xml"
|
|
495
|
-
|
|
492
|
+
if (start !== 0 || target !== "xml")
|
|
493
|
+
invalid("unsupported XML declaration");
|
|
494
|
+
const parsed = yield* readDeclaration(source, offset, end, limits.expectedEncoding);
|
|
495
|
+
if (parsed === undefined)
|
|
496
496
|
invalid("unsupported XML declaration");
|
|
497
|
-
}
|
|
498
497
|
if (retainContent)
|
|
499
|
-
declaration =
|
|
498
|
+
declaration = limits.compactDeclaration ? parsed : yield* source.slice(start, end + 2);
|
|
500
499
|
}
|
|
501
|
-
else
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
500
|
+
else {
|
|
501
|
+
if (offset < end && !" \t\n\r".includes(yield* source.slice(offset, offset + 1)))
|
|
502
|
+
invalid("invalid processing instruction");
|
|
503
|
+
let body = offset;
|
|
504
|
+
while (body < end && " \t\n\r".includes(yield* source.slice(body, body + 1))) {
|
|
505
|
+
body++;
|
|
506
|
+
pendingWork++;
|
|
507
|
+
if (pendingWork >= 512) {
|
|
508
|
+
yield 512;
|
|
509
|
+
pendingWork -= 512;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
509
512
|
while (pendingWork >= 512) {
|
|
510
513
|
yield 512;
|
|
511
514
|
pendingWork -= 512;
|
|
512
515
|
}
|
|
513
|
-
|
|
514
|
-
admitText(text);
|
|
515
|
-
admitContent();
|
|
516
|
-
if (retain) {
|
|
517
|
-
(parent?.content ?? (root ? epilog : prolog)).push({ kind: "processing-instruction", target, text });
|
|
518
|
-
}
|
|
519
|
-
limits.events?.({ type: "content", content: { kind: "processing-instruction", target, text }, parent: parent?.element });
|
|
516
|
+
yield* rawContent("processing-instruction", body, end, yield* stack.peek(), target);
|
|
520
517
|
}
|
|
521
518
|
offset = end + 2;
|
|
522
519
|
}
|