@uniweb/semantic-parser 1.10.0 → 1.12.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 +2 -2
- package/package.json +1 -1
- package/src/sanitize.js +43 -17
package/README.md
CHANGED
|
@@ -222,8 +222,8 @@ parser builds — a `<` someone typed shows as `<`. Marks become tags:
|
|
|
222
222
|
```
|
|
223
223
|
|
|
224
224
|
A link is drawn only when its URL may be followed — relative, or `http:`,
|
|
225
|
-
`https:`, `mailto:`, `tel
|
|
226
|
-
|
|
225
|
+
`https:`, `mailto:`, `tel:` or `page:`. Any other, such as `javascript:`,
|
|
226
|
+
leaves its text unlinked. A `button` mark is a link whose `role`
|
|
227
227
|
is `button`.
|
|
228
228
|
|
|
229
229
|
### Span Marks
|
package/package.json
CHANGED
package/src/sanitize.js
CHANGED
|
@@ -172,10 +172,9 @@ function cleanStyle(value) {
|
|
|
172
172
|
|
|
173
173
|
/**
|
|
174
174
|
* The schemes a link may use: the web, mail and phone, and the framework's own
|
|
175
|
-
*
|
|
176
|
-
* a route at render.
|
|
175
|
+
* reference to a page, `page:`, which kit resolves to a route at render.
|
|
177
176
|
*/
|
|
178
|
-
const LINK_SCHEMES = new Set(["http", "https", "mailto", "tel", "page"
|
|
177
|
+
const LINK_SCHEMES = new Set(["http", "https", "mailto", "tel", "page"]);
|
|
179
178
|
|
|
180
179
|
/** A link a document may follow: relative, or one of LINK_SCHEMES. */
|
|
181
180
|
function isSafeUrl(value) {
|
|
@@ -347,9 +346,16 @@ function rebuild(input, policy) {
|
|
|
347
346
|
|
|
348
347
|
/**
|
|
349
348
|
* What a rebuild would leave out of `input`, item by item — the same walk as
|
|
350
|
-
* `rebuild`, reporting instead of writing
|
|
351
|
-
*
|
|
352
|
-
*
|
|
349
|
+
* `rebuild`, reporting instead of writing — and, when it leaves nothing out but
|
|
350
|
+
* writes the markup differently, one `spelling` item at the first difference.
|
|
351
|
+
* Empty when a rebuild writes `input` back exactly as given.
|
|
352
|
+
*
|
|
353
|
+
* ⭐ Exactly, not "up to spelling" (since 2026-10-18): every text run and
|
|
354
|
+
* attribute value a rebuild writes is escaped, so markup in that form reads the
|
|
355
|
+
* same to any reader. Markup spelled otherwise — a `<` left in text, a CDATA
|
|
356
|
+
* section, a reference the rebuild would write as its character — can read one
|
|
357
|
+
* way here and another way to a reader that parses it as written, which a store
|
|
358
|
+
* holding it for every reader cannot allow.
|
|
353
359
|
*/
|
|
354
360
|
function inspect(input, policy) {
|
|
355
361
|
const outside = [];
|
|
@@ -394,6 +400,14 @@ function inspect(input, policy) {
|
|
|
394
400
|
}
|
|
395
401
|
}
|
|
396
402
|
}
|
|
403
|
+
if (!outside.length) {
|
|
404
|
+
const rebuilt = rebuild(input, policy);
|
|
405
|
+
if (rebuilt !== input) {
|
|
406
|
+
let at = 0;
|
|
407
|
+
while (input[at] === rebuilt[at]) at++;
|
|
408
|
+
outside.push({ reason: "spelling", value: input.slice(at, at + 40) });
|
|
409
|
+
}
|
|
410
|
+
}
|
|
397
411
|
return outside;
|
|
398
412
|
}
|
|
399
413
|
|
|
@@ -412,14 +426,16 @@ export function sanitizeMathML(mathml) {
|
|
|
412
426
|
/**
|
|
413
427
|
* What in a MathML string falls outside the allowlist `sanitizeMathML` rebuilds
|
|
414
428
|
* from: each element and attribute a rebuild drops, each style declaration it
|
|
415
|
-
* drops, and any comment, doctype or processing instruction
|
|
416
|
-
*
|
|
429
|
+
* drops, and any comment, doctype or processing instruction — or, when it drops
|
|
430
|
+
* nothing, a `spelling` item if the rebuild writes the markup differently. Empty
|
|
431
|
+
* when `sanitizeMathML` writes the markup back exactly as given, so a writer
|
|
432
|
+
* that stores what `sanitizeMathML` returns stores markup within it.
|
|
417
433
|
*
|
|
418
434
|
* This is how content is checked rather than cleaned — a writer refused with
|
|
419
435
|
* what it sent can fix it, where a cleaned value changes without a word.
|
|
420
436
|
*
|
|
421
437
|
* @param {string} mathml
|
|
422
|
-
* @returns {Array<{reason: 'element'|'attribute'|'style'|'markup', element?: string, attribute?: string, value?: string}>}
|
|
438
|
+
* @returns {Array<{reason: 'element'|'attribute'|'style'|'markup'|'spelling', element?: string, attribute?: string, value?: string}>}
|
|
423
439
|
*/
|
|
424
440
|
export function inspectMathML(mathml) {
|
|
425
441
|
if (typeof mathml !== "string" || !mathml) return [];
|
|
@@ -443,11 +459,11 @@ export function sanitizeSVG(svg) {
|
|
|
443
459
|
|
|
444
460
|
/**
|
|
445
461
|
* What in an SVG string falls outside the allowlist `sanitizeSVG` rebuilds
|
|
446
|
-
* from, reported as `inspectMathML` reports MathML. Empty when
|
|
447
|
-
*
|
|
462
|
+
* from, reported as `inspectMathML` reports MathML. Empty when `sanitizeSVG`
|
|
463
|
+
* writes the markup back exactly as given.
|
|
448
464
|
*
|
|
449
465
|
* @param {string} svg
|
|
450
|
-
* @returns {Array<{reason: 'element'|'attribute'|'style'|'markup', element?: string, attribute?: string, value?: string}>}
|
|
466
|
+
* @returns {Array<{reason: 'element'|'attribute'|'style'|'markup'|'spelling', element?: string, attribute?: string, value?: string}>}
|
|
451
467
|
*/
|
|
452
468
|
export function inspectSVG(svg) {
|
|
453
469
|
if (typeof svg !== "string" || !svg) return [];
|
|
@@ -456,7 +472,7 @@ export function inspectSVG(svg) {
|
|
|
456
472
|
|
|
457
473
|
/**
|
|
458
474
|
* Whether a link may be followed: a relative URL, or `http:`, `https:`,
|
|
459
|
-
* `mailto:`, `tel:`, or the framework's `page:`
|
|
475
|
+
* `mailto:`, `tel:`, or the framework's `page:` reference. Control
|
|
460
476
|
* characters and spaces are ignored when reading the scheme, as a browser
|
|
461
477
|
* ignores them, so `java\tscript:` is read as `javascript:`.
|
|
462
478
|
*
|
|
@@ -480,8 +496,8 @@ export function isImageSource(url) {
|
|
|
480
496
|
|
|
481
497
|
/**
|
|
482
498
|
* Whether a `data:` URL holds an image a page may show: a PNG, JPEG, GIF, WebP
|
|
483
|
-
* or AVIF in base64, or SVG — percent-encoded or base64 — whose markup is
|
|
484
|
-
*
|
|
499
|
+
* or AVIF in base64, or SVG — percent-encoded or base64 — whose markup is
|
|
500
|
+
* exactly what `sanitizeSVG` writes of it (`inspectSVG`). ⭐ Admitted [Diego, 2026-10-16]: a
|
|
485
501
|
* picture an `<img>` loads runs no script, and a built-in starter image is one.
|
|
486
502
|
* The URL is read as a browser reads it: tab and newline removed, leading and
|
|
487
503
|
* trailing spaces and controls trimmed.
|
|
@@ -598,6 +614,14 @@ export function isCssColor(value) {
|
|
|
598
614
|
return typeof value === "string" && CSS_COLOR.test(value) && !NOT_A_COLOR.test(value);
|
|
599
615
|
}
|
|
600
616
|
|
|
617
|
+
/** How a rebuild writes markup — what `inspect` compares the input with. */
|
|
618
|
+
const WRITTEN =
|
|
619
|
+
"exactly as a rebuild writes it: a text run with `&`, `<` and `>` written `&`, `<` and `>`, and every other character as itself; " +
|
|
620
|
+
"a start tag `<name>` or `<name/>` and an end tag `</name>`, the name as `elements` spells it, with no space before `>` or `/>`; " +
|
|
621
|
+
"each attribute once, as one space then `name=\"value\"` — the name as `attributes` spells it, or a common one in lower case — " +
|
|
622
|
+
"with `&`, `<`, `>` and `\"` in the value written `&`, `<`, `>` and `"`; " +
|
|
623
|
+
"a `style` value as its declarations, each `property:value;` with the property in lower case and the value trimmed";
|
|
624
|
+
|
|
601
625
|
/**
|
|
602
626
|
* The same rules, as data — for a reader that implements them in another
|
|
603
627
|
* language, such as a backend checking content when it is written. Every list
|
|
@@ -632,7 +656,8 @@ export function allowlists() {
|
|
|
632
656
|
unsafeValue: UNSAFE_VALUE.source,
|
|
633
657
|
urlInAValue: "only url(#id), a reference within the document",
|
|
634
658
|
style: "declaration by declaration: a property of letters and -, a value with none of \\ < > { } /* and no unsafe value",
|
|
635
|
-
markup: "no comment, doctype
|
|
659
|
+
markup: "no comment, doctype, processing instruction or CDATA section",
|
|
660
|
+
written: WRITTEN,
|
|
636
661
|
},
|
|
637
662
|
imageData: {
|
|
638
663
|
raster: RASTER_DATA.source,
|
|
@@ -649,7 +674,8 @@ export function allowlists() {
|
|
|
649
674
|
unsafeValue: UNSAFE_VALUE.source,
|
|
650
675
|
urlInAValue: "only url(#id), a reference within the document",
|
|
651
676
|
style: "declaration by declaration: a property of letters and -, a value with none of \\ < > { } /* and no unsafe value",
|
|
652
|
-
markup: "no comment, doctype
|
|
677
|
+
markup: "no comment, doctype, processing instruction or CDATA section",
|
|
678
|
+
written: `${WRITTEN}; an \`href\` or \`xlink:href\` value trimmed`,
|
|
653
679
|
},
|
|
654
680
|
},
|
|
655
681
|
};
|