@extenshi/cli 0.8.0 → 0.8.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.
- package/dist/icon.d.ts +4 -3
- package/dist/icon.d.ts.map +1 -1
- package/dist/icon.js +4 -18
- package/dist/icon.js.map +1 -1
- package/dist/svg-scrub.d.ts +29 -0
- package/dist/svg-scrub.d.ts.map +1 -0
- package/dist/svg-scrub.js +75 -0
- package/dist/svg-scrub.js.map +1 -0
- package/package.json +1 -1
package/dist/icon.d.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* command only renders the verification page. The paid, server-side
|
|
12
12
|
* generation path lives in dojo and is metered separately.
|
|
13
13
|
*/
|
|
14
|
+
import { scrubSvgMarkup } from './svg-scrub.js';
|
|
14
15
|
export interface IconPreviewCmdOptions {
|
|
15
16
|
/** Extension display name shown in the mockups (default: derived from the file name). */
|
|
16
17
|
name?: string;
|
|
@@ -23,10 +24,10 @@ export interface IconPreviewCmdOptions {
|
|
|
23
24
|
* Strip scripting constructs from untrusted SVG source. The preview page only
|
|
24
25
|
* ever embeds the icon through <img src="data:..."> (where scripts never run),
|
|
25
26
|
* but the raw source is also shipped inside the export ZIP — so it must not
|
|
26
|
-
* carry executable payloads either.
|
|
27
|
-
* (
|
|
27
|
+
* carry executable payloads either. The scrubber itself lives in svg-scrub.ts
|
|
28
|
+
* (shared byte-identical with dojo); re-exported here under its historical name.
|
|
28
29
|
*/
|
|
29
|
-
export declare
|
|
30
|
+
export declare const sanitizeSvgSource: typeof scrubSvgMarkup;
|
|
30
31
|
/** Human-ish display name from a file name: "my-cool_icon.svg" → "My Cool Icon". */
|
|
31
32
|
export declare function displayNameFromFile(filePath: string): string;
|
|
32
33
|
/** Resolve the HTML destination: explicit --output wins, else auto-named in cwd. */
|
package/dist/icon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../src/icon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../src/icon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAM/C,MAAM,WAAW,qBAAqB;IACrC,yFAAyF;IACzF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qFAAqF;IACrF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oFAAoF;IACpF,IAAI,CAAC,EAAE,OAAO,CAAA;CACd;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,uBAAiB,CAAA;AAE/C,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAK5D;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIvF;AAmBD;;;GAGG;AACH,wBAAsB,cAAc,CACnC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,qBAAqB,EAC3B,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAkDf"}
|
package/dist/icon.js
CHANGED
|
@@ -15,6 +15,7 @@ import { spawn } from 'node:child_process';
|
|
|
15
15
|
import * as fs from 'node:fs';
|
|
16
16
|
import * as path from 'node:path';
|
|
17
17
|
import { renderIconPreviewHtml } from './icon-preview.js';
|
|
18
|
+
import { scrubSvgMarkup } from './svg-scrub.js';
|
|
18
19
|
const MAX_SVG_BYTES = 512 * 1024;
|
|
19
20
|
const MAX_PNG_BYTES = 2 * 1024 * 1024;
|
|
20
21
|
const PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
|
|
@@ -22,25 +23,10 @@ const PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0
|
|
|
22
23
|
* Strip scripting constructs from untrusted SVG source. The preview page only
|
|
23
24
|
* ever embeds the icon through <img src="data:..."> (where scripts never run),
|
|
24
25
|
* but the raw source is also shipped inside the export ZIP — so it must not
|
|
25
|
-
* carry executable payloads either.
|
|
26
|
-
* (
|
|
26
|
+
* carry executable payloads either. The scrubber itself lives in svg-scrub.ts
|
|
27
|
+
* (shared byte-identical with dojo); re-exported here under its historical name.
|
|
27
28
|
*/
|
|
28
|
-
export
|
|
29
|
-
return (svg
|
|
30
|
-
// XML prolog junk that has no place in an icon
|
|
31
|
-
.replace(/<!DOCTYPE[\s\S]*?>/gi, '')
|
|
32
|
-
.replace(/<!ENTITY[\s\S]*?>/gi, '')
|
|
33
|
-
// executable containers, paired or self-closing
|
|
34
|
-
.replace(/<\s*(script|foreignObject|iframe|object|embed)\b[\s\S]*?<\s*\/\s*\1\s*>/gi, '')
|
|
35
|
-
.replace(/<\s*(script|foreignObject|iframe|object|embed)\b[^>]*\/?>/gi, '')
|
|
36
|
-
// inline event handlers: onload="..." / onclick='...' / onerror=x
|
|
37
|
-
.replace(/\son[a-z]+\s*=\s*"[^"]*"/gi, '')
|
|
38
|
-
.replace(/\son[a-z]+\s*=\s*'[^']*'/gi, '')
|
|
39
|
-
.replace(/\son[a-z]+\s*=\s*[^\s>]+/gi, '')
|
|
40
|
-
// javascript:/data: link targets
|
|
41
|
-
.replace(/\s(href|xlink:href)\s*=\s*"(\s*(javascript|data):)[^"]*"/gi, '')
|
|
42
|
-
.replace(/\s(href|xlink:href)\s*=\s*'(\s*(javascript|data):)[^']*'/gi, ''));
|
|
43
|
-
}
|
|
29
|
+
export const sanitizeSvgSource = scrubSvgMarkup;
|
|
44
30
|
/** Human-ish display name from a file name: "my-cool_icon.svg" → "My Cool Icon". */
|
|
45
31
|
export function displayNameFromFile(filePath) {
|
|
46
32
|
const base = path.basename(filePath).replace(/\.(svg|png)$/i, '');
|
package/dist/icon.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon.js","sourceRoot":"","sources":["../src/icon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"icon.js","sourceRoot":"","sources":["../src/icon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical regex-based SVG scrubber, shared by the offline CLI preview and the
|
|
3
|
+
* hosted dojo generator so both strip the exact same constructs.
|
|
4
|
+
*
|
|
5
|
+
* Regex-based (not DOM-based) on purpose: it must run in Node with no DOMParser
|
|
6
|
+
* — the CLI runs offline in a terminal, and the dojo API route runs server-side.
|
|
7
|
+
* Patterns intentionally over-remove rather than under-remove: an icon has no
|
|
8
|
+
* legitimate use for scripts, styles, animation, or external references.
|
|
9
|
+
*
|
|
10
|
+
* SINGLE SOURCE, TWO COPIES: this file exists byte-identical at
|
|
11
|
+
* tools/extenshi-cli/src/svg-scrub.ts (canonical — edit here)
|
|
12
|
+
* dojo/src/lib/tools/svg-scrub.ts (synced copy for the dojo build)
|
|
13
|
+
* because the published @extenshi/cli npm package cannot depend on unpublished
|
|
14
|
+
* workspace packages, and dojo's Docker build does not build the CLI package.
|
|
15
|
+
* A test in tools/extenshi-cli/src/icon.test.ts fails CI when the copies drift;
|
|
16
|
+
* after editing, run: cp tools/extenshi-cli/src/svg-scrub.ts dojo/src/lib/tools/svg-scrub.ts
|
|
17
|
+
*
|
|
18
|
+
* This is the same rationale as icon-preview.ts (see the note there).
|
|
19
|
+
*/
|
|
20
|
+
export declare const SVG_DANGEROUS_TAGS: readonly ["script", "style", "foreignObject", "iframe", "object", "embed", "applet", "form", "input", "textarea", "select", "button", "animate", "animateTransform", "animateMotion", "set"];
|
|
21
|
+
/**
|
|
22
|
+
* Strip scripting / active constructs from untrusted SVG source. Safe to run on
|
|
23
|
+
* anything: LLM output (dojo), a developer's own file (CLI). The result is only
|
|
24
|
+
* ever consumed as image data (rendered through `<img src="data:…">`, where
|
|
25
|
+
* scripts never execute, and rasterized on a canvas), but we scrub anyway so the
|
|
26
|
+
* raw string is also safe if written to a file or opened directly.
|
|
27
|
+
*/
|
|
28
|
+
export declare function scrubSvgMarkup(svg: string): string;
|
|
29
|
+
//# sourceMappingURL=svg-scrub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg-scrub.d.ts","sourceRoot":"","sources":["../src/svg-scrub.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAMH,eAAO,MAAM,kBAAkB,8LAiBrB,CAAA;AAIV;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA0BlD"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical regex-based SVG scrubber, shared by the offline CLI preview and the
|
|
3
|
+
* hosted dojo generator so both strip the exact same constructs.
|
|
4
|
+
*
|
|
5
|
+
* Regex-based (not DOM-based) on purpose: it must run in Node with no DOMParser
|
|
6
|
+
* — the CLI runs offline in a terminal, and the dojo API route runs server-side.
|
|
7
|
+
* Patterns intentionally over-remove rather than under-remove: an icon has no
|
|
8
|
+
* legitimate use for scripts, styles, animation, or external references.
|
|
9
|
+
*
|
|
10
|
+
* SINGLE SOURCE, TWO COPIES: this file exists byte-identical at
|
|
11
|
+
* tools/extenshi-cli/src/svg-scrub.ts (canonical — edit here)
|
|
12
|
+
* dojo/src/lib/tools/svg-scrub.ts (synced copy for the dojo build)
|
|
13
|
+
* because the published @extenshi/cli npm package cannot depend on unpublished
|
|
14
|
+
* workspace packages, and dojo's Docker build does not build the CLI package.
|
|
15
|
+
* A test in tools/extenshi-cli/src/icon.test.ts fails CI when the copies drift;
|
|
16
|
+
* after editing, run: cp tools/extenshi-cli/src/svg-scrub.ts dojo/src/lib/tools/svg-scrub.ts
|
|
17
|
+
*
|
|
18
|
+
* This is the same rationale as icon-preview.ts (see the note there).
|
|
19
|
+
*/
|
|
20
|
+
// Executable / interactive / animated containers that have no place in a flat
|
|
21
|
+
// icon. The DOM-based sanitizer in dojo (svg-sanitize.ts → DANGEROUS_ELEMENTS)
|
|
22
|
+
// derives its element set from this list, so the two sanitizers can never
|
|
23
|
+
// disagree on which elements are dangerous.
|
|
24
|
+
export const SVG_DANGEROUS_TAGS = [
|
|
25
|
+
'script',
|
|
26
|
+
'style',
|
|
27
|
+
'foreignObject',
|
|
28
|
+
'iframe',
|
|
29
|
+
'object',
|
|
30
|
+
'embed',
|
|
31
|
+
'applet',
|
|
32
|
+
'form',
|
|
33
|
+
'input',
|
|
34
|
+
'textarea',
|
|
35
|
+
'select',
|
|
36
|
+
'button',
|
|
37
|
+
'animate',
|
|
38
|
+
'animateTransform',
|
|
39
|
+
'animateMotion',
|
|
40
|
+
'set',
|
|
41
|
+
];
|
|
42
|
+
const TAGS_ALT = SVG_DANGEROUS_TAGS.join('|');
|
|
43
|
+
/**
|
|
44
|
+
* Strip scripting / active constructs from untrusted SVG source. Safe to run on
|
|
45
|
+
* anything: LLM output (dojo), a developer's own file (CLI). The result is only
|
|
46
|
+
* ever consumed as image data (rendered through `<img src="data:…">`, where
|
|
47
|
+
* scripts never execute, and rasterized on a canvas), but we scrub anyway so the
|
|
48
|
+
* raw string is also safe if written to a file or opened directly.
|
|
49
|
+
*/
|
|
50
|
+
export function scrubSvgMarkup(svg) {
|
|
51
|
+
return (svg
|
|
52
|
+
// XML prolog junk (DOCTYPE/ENTITY → billion-laughs / XXE vectors).
|
|
53
|
+
// Handle the internal-subset form `<!DOCTYPE x [ … ]>` first (a
|
|
54
|
+
// non-greedy `<!DOCTYPE …?>` would stop at the first `>` inside the
|
|
55
|
+
// brackets and leave `]>` behind), then the simple form and entities.
|
|
56
|
+
.replace(/<!DOCTYPE[^>[]*\[[\s\S]*?\]\s*>/gi, '')
|
|
57
|
+
.replace(/<!DOCTYPE[^>]*>/gi, '')
|
|
58
|
+
.replace(/<!ENTITY[\s\S]*?>/gi, '')
|
|
59
|
+
// executable / interactive / animation containers, paired or self-closing.
|
|
60
|
+
// One pass, non-greedy: multiply-nested tags of the SAME type (e.g.
|
|
61
|
+
// `<script>a<script>b</script>c</script>`) are not fully unwrapped, but
|
|
62
|
+
// the leftover text is inert and the render context (<img src="data:…">)
|
|
63
|
+
// never executes it — the self-closing sweep below catches stray opens.
|
|
64
|
+
.replace(new RegExp(`<\\s*(${TAGS_ALT})\\b[\\s\\S]*?<\\s*/\\s*\\1\\s*>`, 'gi'), '')
|
|
65
|
+
.replace(new RegExp(`<\\s*(${TAGS_ALT})\\b[^>]*/?>`, 'gi'), '')
|
|
66
|
+
// inline event handlers: onload="…" / onclick='…' / onerror=x
|
|
67
|
+
.replace(/\son[a-z]+\s*=\s*"[^"]*"/gi, '')
|
|
68
|
+
.replace(/\son[a-z]+\s*=\s*'[^']*'/gi, '')
|
|
69
|
+
.replace(/\son[a-z]+\s*=\s*[^\s>]+/gi, '')
|
|
70
|
+
// javascript:/data: link targets on href / xlink:href
|
|
71
|
+
.replace(/\s(href|xlink:href)\s*=\s*"(\s*(javascript|data):)[^"]*"/gi, '')
|
|
72
|
+
.replace(/\s(href|xlink:href)\s*=\s*'(\s*(javascript|data):)[^']*'/gi, '')
|
|
73
|
+
.trim());
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=svg-scrub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg-scrub.js","sourceRoot":"","sources":["../src/svg-scrub.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,8EAA8E;AAC9E,+EAA+E;AAC/E,0EAA0E;AAC1E,4CAA4C;AAC5C,MAAM,CAAC,MAAM,kBAAkB,GAAG;IACjC,QAAQ;IACR,OAAO;IACP,eAAe;IACf,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,MAAM;IACN,OAAO;IACP,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,kBAAkB;IAClB,eAAe;IACf,KAAK;CACI,CAAA;AAEV,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAE7C;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACzC,OAAO,CACN,GAAG;QACF,mEAAmE;QACnE,gEAAgE;QAChE,oEAAoE;QACpE,sEAAsE;SACrE,OAAO,CAAC,mCAAmC,EAAE,EAAE,CAAC;SAChD,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC;SAChC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC;QACnC,2EAA2E;QAC3E,oEAAoE;QACpE,wEAAwE;QACxE,yEAAyE;QACzE,wEAAwE;SACvE,OAAO,CAAC,IAAI,MAAM,CAAC,SAAS,QAAQ,kCAAkC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;SAClF,OAAO,CAAC,IAAI,MAAM,CAAC,SAAS,QAAQ,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;QAC/D,8DAA8D;SAC7D,OAAO,CAAC,4BAA4B,EAAE,EAAE,CAAC;SACzC,OAAO,CAAC,4BAA4B,EAAE,EAAE,CAAC;SACzC,OAAO,CAAC,4BAA4B,EAAE,EAAE,CAAC;QAC1C,sDAAsD;SACrD,OAAO,CAAC,4DAA4D,EAAE,EAAE,CAAC;SACzE,OAAO,CAAC,4DAA4D,EAAE,EAAE,CAAC;SACzE,IAAI,EAAE,CACR,CAAA;AACF,CAAC"}
|