@intlify/shared
Advanced tools
Comparing version
@@ -141,2 +141,4 @@ | ||
export declare function sanitizeTranslatedHtml(html: string): string; | ||
export declare const toDisplayString: (val: unknown) => string; | ||
@@ -143,0 +145,0 @@ |
/*! | ||
* shared v9.14.4 | ||
* shared v9.14.5 | ||
* (c) 2025 kazuya kawaguchi | ||
* Released under the MIT License. | ||
*/ | ||
function warn(msg, err) { | ||
if (typeof console !== 'undefined') { | ||
console.warn(`[intlify] ` + msg); | ||
/* istanbul ignore if */ | ||
if (err) { | ||
console.warn(err.stack); | ||
} | ||
} | ||
} | ||
const hasWarned = {}; | ||
function warnOnce(msg) { | ||
if (!hasWarned[msg]) { | ||
hasWarned[msg] = true; | ||
warn(msg); | ||
} | ||
} | ||
/** | ||
@@ -74,7 +91,46 @@ * Original Utilities | ||
return rawText | ||
.replace(/&/g, '&') // escape `&` first to avoid double escaping | ||
.replace(/</g, '<') | ||
.replace(/>/g, '>') | ||
.replace(/"/g, '"') | ||
.replace(/'/g, '''); | ||
.replace(/'/g, ''') | ||
.replace(/\//g, '/') // escape `/` to prevent closing tags or JavaScript URLs | ||
.replace(/=/g, '='); // escape `=` to prevent attribute injection | ||
} | ||
function escapeAttributeValue(value) { | ||
return value | ||
.replace(/&(?![a-zA-Z0-9#]{2,6};)/g, '&') // escape unescaped `&` | ||
.replace(/"/g, '"') | ||
.replace(/'/g, ''') | ||
.replace(/</g, '<') | ||
.replace(/>/g, '>'); | ||
} | ||
function sanitizeTranslatedHtml(html) { | ||
// Escape dangerous characters in attribute values | ||
// Process attributes with double quotes | ||
html = html.replace(/(\w+)\s*=\s*"([^"]*)"/g, (_, attrName, attrValue) => `${attrName}="${escapeAttributeValue(attrValue)}"`); | ||
// Process attributes with single quotes | ||
html = html.replace(/(\w+)\s*=\s*'([^']*)'/g, (_, attrName, attrValue) => `${attrName}='${escapeAttributeValue(attrValue)}'`); | ||
// Detect and neutralize event handler attributes | ||
const eventHandlerPattern = /\s*on\w+\s*=\s*["']?[^"'>]+["']?/gi; | ||
if (eventHandlerPattern.test(html)) { | ||
{ | ||
warn('Potentially dangerous event handlers detected in translation. ' + | ||
'Consider removing onclick, onerror, etc. from your translation messages.'); | ||
} | ||
// Neutralize event handler attributes by escaping 'on' | ||
html = html.replace(/(\s+)(on)(\w+\s*=)/gi, '$1on$3'); | ||
} | ||
// Disable javascript: URLs in various contexts | ||
const javascriptUrlPattern = [ | ||
// In href, src, action, formaction attributes | ||
/(\s+(?:href|src|action|formaction)\s*=\s*["']?)\s*javascript:/gi, | ||
// In style attributes within url() | ||
/(style\s*=\s*["'][^"']*url\s*\(\s*)javascript:/gi | ||
]; | ||
javascriptUrlPattern.forEach(pattern => { | ||
html = html.replace(pattern, '$1javascript:'); | ||
}); | ||
return html; | ||
} | ||
const hasOwnProperty = Object.prototype.hasOwnProperty; | ||
@@ -160,19 +216,2 @@ function hasOwn(obj, key) { | ||
function warn(msg, err) { | ||
if (typeof console !== 'undefined') { | ||
console.warn(`[intlify] ` + msg); | ||
/* istanbul ignore if */ | ||
if (err) { | ||
console.warn(err.stack); | ||
} | ||
} | ||
} | ||
const hasWarned = {}; | ||
function warnOnce(msg) { | ||
if (!hasWarned[msg]) { | ||
hasWarned[msg] = true; | ||
warn(msg); | ||
} | ||
} | ||
/** | ||
@@ -253,2 +292,2 @@ * Event emitter, forked from the below: | ||
export { assign, create, createEmitter, deepCopy, escapeHtml, format, friendlyJSONstringify, generateCodeFrame, generateFormatCacheKey, getGlobalThis, hasOwn, inBrowser, incrementer, isArray, isBoolean, isDate, isEmptyObject, isFunction, isNumber, isObject, isPlainObject, isPromise, isRegExp, isString, isSymbol, join, makeSymbol, mark, measure, objectToString, toDisplayString, toTypeString, warn, warnOnce }; | ||
export { assign, create, createEmitter, deepCopy, escapeHtml, format, friendlyJSONstringify, generateCodeFrame, generateFormatCacheKey, getGlobalThis, hasOwn, inBrowser, incrementer, isArray, isBoolean, isDate, isEmptyObject, isFunction, isNumber, isObject, isPlainObject, isPromise, isRegExp, isString, isSymbol, join, makeSymbol, mark, measure, objectToString, sanitizeTranslatedHtml, toDisplayString, toTypeString, warn, warnOnce }; |
/*! | ||
* shared v9.14.4 | ||
* shared v9.14.5 | ||
* (c) 2025 kazuya kawaguchi | ||
* Released under the MIT License. | ||
*/ | ||
const inBrowser="undefined"!=typeof window;let mark,measure;const RE_ARGS=/\{([0-9a-zA-Z]+)\}/g;function format(e,...t){return 1===t.length&&isObject(t[0])&&(t=t[0]),t&&t.hasOwnProperty||(t={}),e.replace(RE_ARGS,((e,n)=>t.hasOwnProperty(n)?t[n]:""))}const makeSymbol=(e,t=!1)=>t?Symbol.for(e):Symbol(e),generateFormatCacheKey=(e,t,n)=>friendlyJSONstringify({l:e,k:t,s:n}),friendlyJSONstringify=e=>JSON.stringify(e).replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029").replace(/\u0027/g,"\\u0027"),isNumber=e=>"number"==typeof e&&isFinite(e),isDate=e=>"[object Date]"===toTypeString(e),isRegExp=e=>"[object RegExp]"===toTypeString(e),isEmptyObject=e=>isPlainObject(e)&&0===Object.keys(e).length,assign=Object.assign,_create=Object.create,create=(e=null)=>_create(e);let _globalThis;const getGlobalThis=()=>_globalThis||(_globalThis="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:create());function escapeHtml(e){return e.replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}const hasOwnProperty=Object.prototype.hasOwnProperty;function hasOwn(e,t){return hasOwnProperty.call(e,t)}const isArray=Array.isArray,isFunction=e=>"function"==typeof e,isString=e=>"string"==typeof e,isBoolean=e=>"boolean"==typeof e,isSymbol=e=>"symbol"==typeof e,isObject=e=>null!==e&&"object"==typeof e,isPromise=e=>isObject(e)&&isFunction(e.then)&&isFunction(e.catch),objectToString=Object.prototype.toString,toTypeString=e=>objectToString.call(e),isPlainObject=e=>{if(!isObject(e))return!1;const t=Object.getPrototypeOf(e);return null===t||t.constructor===Object},toDisplayString=e=>null==e?"":isArray(e)||isPlainObject(e)&&e.toString===objectToString?JSON.stringify(e,null,2):String(e);function join(e,t=""){return e.reduce(((e,n,r)=>0===r?e+n:e+t+n),"")}const RANGE=2;function generateCodeFrame(e,t=0,n=e.length){const r=e.split(/\r?\n/);let o=0;const i=[];for(let s=0;s<r.length;s++)if(o+=r[s].length+1,o>=t){for(let e=s-2;e<=s+2||n>o;e++){if(e<0||e>=r.length)continue;const a=e+1;i.push(`${a}${" ".repeat(3-String(a).length)}| ${r[e]}`);const c=r[e].length;if(e===s){const e=t-(o-c)+1,r=Math.max(1,n>o?c-e:n-t);i.push(" | "+" ".repeat(e)+"^".repeat(r))}else if(e>s){if(n>o){const e=Math.max(Math.min(n-o,c),1);i.push(" | "+"^".repeat(e))}o+=c+1}}break}return i.join("\n")}function incrementer(e){let t=e;return()=>++t}function warn(e,t){"undefined"!=typeof console&&(console.warn("[intlify] "+e),t&&console.warn(t.stack))}const hasWarned={};function warnOnce(e){hasWarned[e]||(hasWarned[e]=!0,warn(e))}function createEmitter(){const e=new Map;return{events:e,on(t,n){const r=e.get(t);r&&r.push(n)||e.set(t,[n])},off(t,n){const r=e.get(t);r&&r.splice(r.indexOf(n)>>>0,1)},emit(t,n){(e.get(t)||[]).slice().map((e=>e(n))),(e.get("*")||[]).slice().map((e=>e(t,n)))}}}const isNotObjectOrIsArray=e=>!isObject(e)||isArray(e);function deepCopy(e,t){if(isNotObjectOrIsArray(e)||isNotObjectOrIsArray(t))throw new Error("Invalid value");const n=[{src:e,des:t}];for(;n.length;){const{src:e,des:t}=n.pop();Object.keys(e).forEach((r=>{"__proto__"!==r&&(isObject(e[r])&&!isObject(t[r])&&(t[r]=Array.isArray(e[r])?[]:create()),isNotObjectOrIsArray(t[r])||isNotObjectOrIsArray(e[r])?t[r]=e[r]:n.push({src:e[r],des:t[r]}))}))}}export{assign,create,createEmitter,deepCopy,escapeHtml,format,friendlyJSONstringify,generateCodeFrame,generateFormatCacheKey,getGlobalThis,hasOwn,inBrowser,incrementer,isArray,isBoolean,isDate,isEmptyObject,isFunction,isNumber,isObject,isPlainObject,isPromise,isRegExp,isString,isSymbol,join,makeSymbol,mark,measure,objectToString,toDisplayString,toTypeString,warn,warnOnce}; | ||
function warn(e,t){"undefined"!=typeof console&&(console.warn("[intlify] "+e),t&&console.warn(t.stack))}const hasWarned={};function warnOnce(e){hasWarned[e]||(hasWarned[e]=!0,warn(e))}const inBrowser="undefined"!=typeof window;let mark,measure;const RE_ARGS=/\{([0-9a-zA-Z]+)\}/g;function format(e,...t){return 1===t.length&&isObject(t[0])&&(t=t[0]),t&&t.hasOwnProperty||(t={}),e.replace(RE_ARGS,((e,r)=>t.hasOwnProperty(r)?t[r]:""))}const makeSymbol=(e,t=!1)=>t?Symbol.for(e):Symbol(e),generateFormatCacheKey=(e,t,r)=>friendlyJSONstringify({l:e,k:t,s:r}),friendlyJSONstringify=e=>JSON.stringify(e).replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029").replace(/\u0027/g,"\\u0027"),isNumber=e=>"number"==typeof e&&isFinite(e),isDate=e=>"[object Date]"===toTypeString(e),isRegExp=e=>"[object RegExp]"===toTypeString(e),isEmptyObject=e=>isPlainObject(e)&&0===Object.keys(e).length,assign=Object.assign,_create=Object.create,create=(e=null)=>_create(e);let _globalThis;const getGlobalThis=()=>_globalThis||(_globalThis="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:create());function escapeHtml(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/").replace(/=/g,"=")}function escapeAttributeValue(e){return e.replace(/&(?![a-zA-Z0-9#]{2,6};)/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function sanitizeTranslatedHtml(e){e=(e=e.replace(/(\w+)\s*=\s*"([^"]*)"/g,((e,t,r)=>`${t}="${escapeAttributeValue(r)}"`))).replace(/(\w+)\s*=\s*'([^']*)'/g,((e,t,r)=>`${t}='${escapeAttributeValue(r)}'`));/\s*on\w+\s*=\s*["']?[^"'>]+["']?/gi.test(e)&&(e=e.replace(/(\s+)(on)(\w+\s*=)/gi,"$1on$3"));return[/(\s+(?:href|src|action|formaction)\s*=\s*["']?)\s*javascript:/gi,/(style\s*=\s*["'][^"']*url\s*\(\s*)javascript:/gi].forEach((t=>{e=e.replace(t,"$1javascript:")})),e}const hasOwnProperty=Object.prototype.hasOwnProperty;function hasOwn(e,t){return hasOwnProperty.call(e,t)}const isArray=Array.isArray,isFunction=e=>"function"==typeof e,isString=e=>"string"==typeof e,isBoolean=e=>"boolean"==typeof e,isSymbol=e=>"symbol"==typeof e,isObject=e=>null!==e&&"object"==typeof e,isPromise=e=>isObject(e)&&isFunction(e.then)&&isFunction(e.catch),objectToString=Object.prototype.toString,toTypeString=e=>objectToString.call(e),isPlainObject=e=>{if(!isObject(e))return!1;const t=Object.getPrototypeOf(e);return null===t||t.constructor===Object},toDisplayString=e=>null==e?"":isArray(e)||isPlainObject(e)&&e.toString===objectToString?JSON.stringify(e,null,2):String(e);function join(e,t=""){return e.reduce(((e,r,n)=>0===n?e+r:e+t+r),"")}const RANGE=2;function generateCodeFrame(e,t=0,r=e.length){const n=e.split(/\r?\n/);let s=0;const i=[];for(let o=0;o<n.length;o++)if(s+=n[o].length+1,s>=t){for(let e=o-2;e<=o+2||r>s;e++){if(e<0||e>=n.length)continue;const a=e+1;i.push(`${a}${" ".repeat(3-String(a).length)}| ${n[e]}`);const c=n[e].length;if(e===o){const e=t-(s-c)+1,n=Math.max(1,r>s?c-e:r-t);i.push(" | "+" ".repeat(e)+"^".repeat(n))}else if(e>o){if(r>s){const e=Math.max(Math.min(r-s,c),1);i.push(" | "+"^".repeat(e))}s+=c+1}}break}return i.join("\n")}function incrementer(e){let t=e;return()=>++t}function createEmitter(){const e=new Map;return{events:e,on(t,r){const n=e.get(t);n&&n.push(r)||e.set(t,[r])},off(t,r){const n=e.get(t);n&&n.splice(n.indexOf(r)>>>0,1)},emit(t,r){(e.get(t)||[]).slice().map((e=>e(r))),(e.get("*")||[]).slice().map((e=>e(t,r)))}}}const isNotObjectOrIsArray=e=>!isObject(e)||isArray(e);function deepCopy(e,t){if(isNotObjectOrIsArray(e)||isNotObjectOrIsArray(t))throw new Error("Invalid value");const r=[{src:e,des:t}];for(;r.length;){const{src:e,des:t}=r.pop();Object.keys(e).forEach((n=>{"__proto__"!==n&&(isObject(e[n])&&!isObject(t[n])&&(t[n]=Array.isArray(e[n])?[]:create()),isNotObjectOrIsArray(t[n])||isNotObjectOrIsArray(e[n])?t[n]=e[n]:r.push({src:e[n],des:t[n]}))}))}}export{assign,create,createEmitter,deepCopy,escapeHtml,format,friendlyJSONstringify,generateCodeFrame,generateFormatCacheKey,getGlobalThis,hasOwn,inBrowser,incrementer,isArray,isBoolean,isDate,isEmptyObject,isFunction,isNumber,isObject,isPlainObject,isPromise,isRegExp,isString,isSymbol,join,makeSymbol,mark,measure,objectToString,sanitizeTranslatedHtml,toDisplayString,toTypeString,warn,warnOnce}; |
{ | ||
"name": "@intlify/shared", | ||
"version": "9.14.4", | ||
"version": "9.14.5", | ||
"description": "@intlify/shared", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
57863
17.22%1338
13.39%