@reckona/mreact-shared 0.0.179 → 0.0.180

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.
@@ -1 +1 @@
1
- {"version":3,"file":"url-safety.d.ts","sourceRoot":"","sources":["../src/url-safety.ts"],"names":[],"mappings":"AA4BA,0FAA0F;AAC1F,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,8DAA8D;AAC9D,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAO7B;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAczE;AAED,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAErF;AAED,8EAA8E;AAC9E,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAKtF"}
1
+ {"version":3,"file":"url-safety.d.ts","sourceRoot":"","sources":["../src/url-safety.ts"],"names":[],"mappings":"AA8BA,0FAA0F;AAC1F,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,8DAA8D;AAC9D,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAO7B;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAczE;AAED,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAErF;AAED,8EAA8E;AAC9E,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAKtF"}
@@ -10,6 +10,8 @@ const URL_ATTRIBUTE_NAMES = new Set([
10
10
  "poster",
11
11
  "background",
12
12
  "manifest",
13
+ "data",
14
+ "codebase",
13
15
  ]);
14
16
  const SRCSET_ATTRIBUTE_NAMES = new Set(["srcset", "imagesrcset"]);
15
17
  const DANGEROUS_HTML_ATTRIBUTE_NAMES = new Set(["srcdoc"]);
@@ -1 +1 @@
1
- {"version":3,"file":"url-safety.js","sourceRoot":"","sources":["../src/url-safety.ts"],"names":[],"mappings":"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","sourcesContent":["// Canonical URL and HTML-attribute safety helpers shared across server,\n// React compatibility, and reactive DOM render paths.\n\nconst URL_ATTRIBUTE_NAMES = new Set([\n \"href\",\n \"src\",\n \"action\",\n \"formaction\",\n \"xlink:href\",\n \"ping\",\n \"poster\",\n \"background\",\n \"manifest\",\n]);\n\nconst SRCSET_ATTRIBUTE_NAMES = new Set([\"srcset\", \"imagesrcset\"]);\n\nconst DANGEROUS_HTML_ATTRIBUTE_NAMES = new Set([\"srcdoc\"]);\n\nconst UNSAFE_URL_SCHEMES = new Set([\n \"javascript\",\n \"data\",\n \"vbscript\",\n \"livescript\",\n \"mhtml\",\n \"file\",\n]);\n\n/** Returns true for HTML attributes that require explicit unsafe-HTML opt-in handling. */\nexport function isDangerousHtmlAttribute(name: string): boolean {\n return DANGEROUS_HTML_ATTRIBUTE_NAMES.has(name);\n}\n\n/** Narrows a value to an explicit raw HTML opt-in payload. */\nexport function isDangerousHtmlOptIn(\n value: unknown,\n): value is { __html: string } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"__html\" in value &&\n typeof (value as { __html?: unknown }).__html === \"string\"\n );\n}\n\n/** Returns true when an attribute name normally carries a single URL value. */\nexport function isUrlAttribute(name: string): boolean {\n return URL_ATTRIBUTE_NAMES.has(name);\n}\n\n/** Returns true when an attribute name carries a srcset-style URL list. */\nexport function isSrcsetAttribute(name: string): boolean {\n return SRCSET_ATTRIBUTE_NAMES.has(name);\n}\n\n/** Checks whether an HTML URL-bearing attribute value uses a blocked scheme. */\nexport function isUnsafeUrlAttribute(name: string, value: string): boolean {\n if (isUrlAttribute(name)) {\n return isUnsafeUrlValueForName(name, value);\n }\n if (isSrcsetAttribute(name)) {\n const canonical = canonicalizeUrlForSchemeCheck(value);\n for (const candidate of canonical.split(\",\")) {\n const url = candidate.trim().split(/\\s+/)[0] ?? \"\";\n if (url === \"\") continue;\n if (isUnsafeUrlValueForName(\"src\", url)) return true;\n }\n return false;\n }\n return false;\n}\n\n/** Returns the original URL attribute value when it is safe, otherwise undefined. */\nexport function safeUrlAttributeValue(name: string, value: string): string | undefined {\n return isUnsafeUrlAttribute(name, value) ? undefined : value;\n}\n\n/** Checks whether a meta refresh content value redirects to an unsafe URL. */\nexport function isUnsafeMetaRefreshContent(httpEquiv: string, content: string): boolean {\n if (httpEquiv.toLowerCase() !== \"refresh\") return false;\n const match = /^[^;]*;\\s*url\\s*=\\s*([\\s\\S]+)$/iu.exec(content);\n if (match === null || match[1] === undefined) return false;\n return isUnsafeUrlValueForName(\"href\", stripSurroundingQuotes(match[1].trim()));\n}\n\nfunction stripSurroundingQuotes(value: string): string {\n if (value.length < 2) return value;\n\n const quote = value[0];\n if ((quote === '\"' || quote === \"'\") && value[value.length - 1] === quote) {\n return value.slice(1, -1).trim();\n }\n\n return value;\n}\n\nfunction canonicalizeUrlForSchemeCheck(value: string): string {\n let start = 0;\n\n while (start < value.length && value.charCodeAt(start) <= 0x20) {\n start += 1;\n }\n\n return value.slice(start).replace(/[\\t\\r\\n]/g, \"\");\n}\n\nfunction schemeOf(value: string): string | undefined {\n const match = /^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(value);\n if (match === null || match[1] === undefined) return undefined;\n return match[1].toLowerCase();\n}\n\nfunction isUnsafeUrlValueForName(name: string, value: string): boolean {\n const canonical = canonicalizeUrlForSchemeCheck(value);\n const scheme = schemeOf(canonical);\n if (scheme === undefined) return false;\n if (!UNSAFE_URL_SCHEMES.has(scheme)) return false;\n if (scheme === \"data\" && (name === \"src\" || name === \"poster\")) {\n if (/^data:image\\/(?!svg\\+xml(?:[;,]|$))/i.test(canonical)) return false;\n }\n return true;\n}\n"]}
1
+ {"version":3,"file":"url-safety.js","sourceRoot":"","sources":["../src/url-safety.ts"],"names":[],"mappings":"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","sourcesContent":["// Canonical URL and HTML-attribute safety helpers shared across server,\n// React compatibility, and reactive DOM render paths.\n\nconst URL_ATTRIBUTE_NAMES = new Set([\n \"href\",\n \"src\",\n \"action\",\n \"formaction\",\n \"xlink:href\",\n \"ping\",\n \"poster\",\n \"background\",\n \"manifest\",\n \"data\",\n \"codebase\",\n]);\n\nconst SRCSET_ATTRIBUTE_NAMES = new Set([\"srcset\", \"imagesrcset\"]);\n\nconst DANGEROUS_HTML_ATTRIBUTE_NAMES = new Set([\"srcdoc\"]);\n\nconst UNSAFE_URL_SCHEMES = new Set([\n \"javascript\",\n \"data\",\n \"vbscript\",\n \"livescript\",\n \"mhtml\",\n \"file\",\n]);\n\n/** Returns true for HTML attributes that require explicit unsafe-HTML opt-in handling. */\nexport function isDangerousHtmlAttribute(name: string): boolean {\n return DANGEROUS_HTML_ATTRIBUTE_NAMES.has(name);\n}\n\n/** Narrows a value to an explicit raw HTML opt-in payload. */\nexport function isDangerousHtmlOptIn(\n value: unknown,\n): value is { __html: string } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"__html\" in value &&\n typeof (value as { __html?: unknown }).__html === \"string\"\n );\n}\n\n/** Returns true when an attribute name normally carries a single URL value. */\nexport function isUrlAttribute(name: string): boolean {\n return URL_ATTRIBUTE_NAMES.has(name);\n}\n\n/** Returns true when an attribute name carries a srcset-style URL list. */\nexport function isSrcsetAttribute(name: string): boolean {\n return SRCSET_ATTRIBUTE_NAMES.has(name);\n}\n\n/** Checks whether an HTML URL-bearing attribute value uses a blocked scheme. */\nexport function isUnsafeUrlAttribute(name: string, value: string): boolean {\n if (isUrlAttribute(name)) {\n return isUnsafeUrlValueForName(name, value);\n }\n if (isSrcsetAttribute(name)) {\n const canonical = canonicalizeUrlForSchemeCheck(value);\n for (const candidate of canonical.split(\",\")) {\n const url = candidate.trim().split(/\\s+/)[0] ?? \"\";\n if (url === \"\") continue;\n if (isUnsafeUrlValueForName(\"src\", url)) return true;\n }\n return false;\n }\n return false;\n}\n\n/** Returns the original URL attribute value when it is safe, otherwise undefined. */\nexport function safeUrlAttributeValue(name: string, value: string): string | undefined {\n return isUnsafeUrlAttribute(name, value) ? undefined : value;\n}\n\n/** Checks whether a meta refresh content value redirects to an unsafe URL. */\nexport function isUnsafeMetaRefreshContent(httpEquiv: string, content: string): boolean {\n if (httpEquiv.toLowerCase() !== \"refresh\") return false;\n const match = /^[^;]*;\\s*url\\s*=\\s*([\\s\\S]+)$/iu.exec(content);\n if (match === null || match[1] === undefined) return false;\n return isUnsafeUrlValueForName(\"href\", stripSurroundingQuotes(match[1].trim()));\n}\n\nfunction stripSurroundingQuotes(value: string): string {\n if (value.length < 2) return value;\n\n const quote = value[0];\n if ((quote === '\"' || quote === \"'\") && value[value.length - 1] === quote) {\n return value.slice(1, -1).trim();\n }\n\n return value;\n}\n\nfunction canonicalizeUrlForSchemeCheck(value: string): string {\n let start = 0;\n\n while (start < value.length && value.charCodeAt(start) <= 0x20) {\n start += 1;\n }\n\n return value.slice(start).replace(/[\\t\\r\\n]/g, \"\");\n}\n\nfunction schemeOf(value: string): string | undefined {\n const match = /^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(value);\n if (match === null || match[1] === undefined) return undefined;\n return match[1].toLowerCase();\n}\n\nfunction isUnsafeUrlValueForName(name: string, value: string): boolean {\n const canonical = canonicalizeUrlForSchemeCheck(value);\n const scheme = schemeOf(canonical);\n if (scheme === undefined) return false;\n if (!UNSAFE_URL_SCHEMES.has(scheme)) return false;\n if (scheme === \"data\" && (name === \"src\" || name === \"poster\")) {\n if (/^data:image\\/(?!svg\\+xml(?:[;,]|$))/i.test(canonical)) return false;\n }\n return true;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reckona/mreact-shared",
3
- "version": "0.0.179",
3
+ "version": "0.0.180",
4
4
  "description": "Shared runtime utilities used by mreact packages.",
5
5
  "keywords": [
6
6
  "jsx",
package/src/url-safety.ts CHANGED
@@ -11,6 +11,8 @@ const URL_ATTRIBUTE_NAMES = new Set([
11
11
  "poster",
12
12
  "background",
13
13
  "manifest",
14
+ "data",
15
+ "codebase",
14
16
  ]);
15
17
 
16
18
  const SRCSET_ATTRIBUTE_NAMES = new Set(["srcset", "imagesrcset"]);