@file-viewer/renderer-chm 3.0.2 → 3.0.3
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/chm.worker.js +2 -2
- package/dist/security.js +70 -3
- package/package.json +2 -2
package/dist/chm.worker.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
`||e==="\f"||e==="\r",
|
|
1
|
+
var I=/[\u0000-\u001f\u007f]/;var ie=16*1024*1024;var oe=8*1024*1024;var se=4*1024*1024,j=4*1024*1024,F=(e=Number.POSITIVE_INFINITY)=>{let t=[],n="",r=0;return{append:o=>{if(!o||r>=e)return;let a=e-r,s=o.length>a?o.slice(0,a):o;if(r+=s.length,n.length+s.length<=16384){n+=s;return}n&&t.push(n),s.length>16384?(t.push(s),n=""):n=s},get length(){return r},finish:()=>(n&&t.push(n),t.join(""))}};var q=e=>{try{return decodeURIComponent(e)}catch{return e}},_=e=>{if(typeof e!="string"||I.test(e))return null;let t=e.trim();if(!t||t.length>4096)return null;let n=q(t);if(/^(?:[a-z]:[\\/]|[\\/]{2})/i.test(n))return null;let r=n.replace(/\\/g,"/"),i=[];for(let o of r.split("/"))if(!(!o||o===".")){if(o===".."){if(!i.length)return null;i.pop();continue}if(I.test(o))return null;i.push(o)}return`/${i.join("/")}`};var B=e=>{let t=(e||"").trim().toLowerCase().replace(/_/g,"-");return t?t==="utf8"?"utf-8":t==="gbk"||t==="cp936"?"gb18030":t==="big5-hkscs"?"big5":t==="shift-jis"||t==="sjis"||t==="cp932"?"shift_jis":t==="euc-kr"||t==="cp949"?"euc-kr":/^windows-?\d+$/.test(t)?t.replace(/^windows-?/,"windows-"):/^cp\d+$/.test(t)?t.replace(/^cp/,"windows-"):t:""},V=e=>{let t=e.subarray(0,Math.min(e.byteLength,8192)),n="";for(let i=0;i<t.byteLength;i+=1){let o=t[i];n+=o>=32&&o<=126?String.fromCharCode(o):" "}let r=0;for(;r<n.length;){let i=n.indexOf("<",r);if(i<0)break;if(n.startsWith("<!--",i)){let f=n.indexOf("-->",i+4);r=f<0?n.length:f+3;continue}let o=i+1,a=o;for(;w(n[o]);)o+=1;let s=n.slice(a,o).toLowerCase(),l=M(n,o);if(r=s==="script"||s==="style"?R(n,l,s):l,s!=="meta")continue;let c=new Map;for(;o<l&&n[o]!==">";){if(!w(n[o])){o+=1;continue}let f=o;for(;w(n[o]);)o+=1;let h=n.slice(f,o).toLowerCase();for(;y(n[o]);)o+=1;if(n[o]!=="=")continue;for(o+=1;y(n[o]);)o+=1;let x=n[o]==='"'||n[o]==="'"?n[o++]:"",X=o;if(x)for(;o<l&&n[o]!==x;)o+=1;else for(;o<l&&!y(n[o])&&n[o]!==">";)o+=1;c.has(h)||c.set(h,n.slice(X,o)),x&&n[o]===x&&(o+=1)}let u=c.get("charset");if(!u)for(let f of(c.get("content")||"").split(";")){let h=f.indexOf("=");if(h>=0&&f.slice(0,h).trim().toLowerCase()==="charset"){u=f.slice(h+1);break}}let g=u?.trim().match(/^[^\s"'/>;]+/)?.[0];if(g)return B(g)}return""},E=(e,t)=>{try{return new TextDecoder(t,{fatal:!1}).decode(e)}catch{return""}},N=(e,t="windows-1252")=>{if(e.byteLength>=3&&e[0]===239&&e[1]===187&&e[2]===191)return E(e.subarray(3),"utf-8");if(e.byteLength>=2&&e[0]===255&&e[1]===254)return E(e.subarray(2),"utf-16le");if(e.byteLength>=2&&e[0]===254&&e[1]===255){let r=new Uint8Array(e.byteLength-2);for(let i=2;i+1<e.byteLength;i+=2)r[i-2]=e[i+1],r[i-1]=e[i];return E(r,"utf-16le")}let n=[V(e),B(t),"utf-8","windows-1252"];for(let r of n){if(!r)continue;let i=E(e,r);if(i)return i.replace(/^\ufeff/,"")}return""},y=e=>e===" "||e===" "||e===`
|
|
2
|
+
`||e==="\f"||e==="\r",w=e=>{if(!e)return!1;let t=e.charCodeAt(0);return t>=48&&t<=57||t>=65&&t<=90||t>=97&&t<=122||e===":"||e==="_"||e==="-"},G=(e,t,n)=>{if(t+n.length>e.length)return!1;for(let r=0;r<n.length;r+=1){let i=e.charCodeAt(t+r),o=n.charCodeAt(r);if((i>=65&&i<=90?i+32:i)!==o)return!1}return!0},M=(e,t)=>{let n=t,r="";for(;n<e.length;){let i=e[n];if(r)i===r&&(r="");else if(i==='"'||i==="'")r=i;else if(i===">")return n+1;n+=1}return e.length},R=(e,t,n)=>{let r=t;for(;r<e.length;){if(e[r]==="<"&&e[r+1]==="/"&&G(e,r+2,n)&&!w(e[r+2+n.length]))return M(e,r+2+n.length);r+=1}return e.length},K=(e,t)=>{let n=t+1,r=Math.min(e.length,t+13);for(;n<r&&e[n]!==";";){if(e[n]==="&"||e[n]==="<"||y(e[n]))return null;n+=1}if(n>=r||e[n]!==";")return null;let i=e.slice(t+1,n).toLowerCase(),o={amp:"&",apos:"'",gt:">",lt:"<",nbsp:" ",quot:'"'};if(o[i]!=null)return{end:n+1,value:o[i]};let a=i.startsWith("#x")?Number.parseInt(i.slice(2),16):i.startsWith("#")?Number.parseInt(i.slice(1),10):Number.NaN;return!Number.isFinite(a)||a<=0||a>1114111||a>=55296&&a<=57343?null:{end:n+1,value:String.fromCodePoint(a)}},D=(e,t=j)=>{let n=F(Math.max(0,t)),r=0,i=!1,o=a=>{if(a){if(y(a)){i=n.length>0;return}i&&n.length<t&&n.append(" "),i=!1,n.append(a)}};for(;r<e.length;){let a=e[r];if(a==="<"){if(i=n.length>0,e.startsWith("<!--",r)){let f=e.indexOf("-->",r+4);r=f<0?e.length:f+3;continue}let s=r+1,l=e[s]==="/";for(l&&(s+=1);y(e[s]);)s+=1;let c=s;for(;w(e[s]);)s+=1;let u=e.slice(c,s).toLowerCase(),g=M(e,s);r=!l&&(u==="script"||u==="style")?R(e,g,u):g;continue}if(a==="&"){let s=K(e,r);if(s){o(s.value),r=s.end;continue}}o(a),r+=1}return n.finish().trim()};var ce=Object.freeze({workerTimeoutMs:6e4,maxArchiveBytes:335544320,maxEntries:5e4,maxEntryBytes:33554432,maxTotalDecompressedBytes:536870912,maxHtmlBytes:16777216,maxSearchTopics:1e4,maxSearchResults:200}),A=1024*1024,le=Object.freeze({maxArchiveBytes:1024*A,maxEntries:25e4,maxEntryBytes:512*A,maxTotalDecompressedBytes:8*1024*A,maxHtmlBytes:64*A});var d=e=>typeof e=="string"?e:"",S=e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,T=e=>e===!0,Y=e=>{if(!e||typeof e!="object")return null;let t=e,n=d(t.path||t.local||t.url);return n?{title:d(t.title||t.name)||n,path:n,contextId:S(t.contextId??t.context_id)}:null},O=e=>{if(!Array.isArray(e))return[];let t=[],n=[];for(let r=e.length-1;r>=0;r-=1)n.push({source:e[r],target:t});for(;n.length;){let r=n.pop();if(!r?.source||typeof r.source!="object")continue;let i=r.source,o=[],a={title:d(i.title||i.name||i.keyword)||d(i.path||i.local),path:d(i.path||i.local||i.url)||void 0,keyword:d(i.keyword)||void 0,children:o};r.target.push(a);let s=Array.isArray(i.locals)?i.locals.filter(c=>typeof c=="string"&&!!c):[];!a.path&&s.length&&(a.path=s[0]);for(let c=a.path?1:0;c<s.length;c+=1)o.push({title:`${a.title} \xB7 ${c+1}`,path:s[c],children:[]});let l=Array.isArray(i.children)?i.children:[];for(let c=l.length-1;c>=0;c-=1)n.push({source:l[c],target:o})}return t},$=e=>{let t=e&&typeof e=="object"?e:{},n=Array.isArray(t.topics)?t.topics.map(Y).filter(r=>!!r):[];return{title:d(t.title),homePath:d(t.homePath??t.home_path),encoding:d(t.encoding)||"windows-1252",language:d(t.language)||void 0,topics:n,contents:O(t.contents??t.toc),index:O(t.index??t.keywords),hasBinaryToc:T(t.hasBinaryToc??t.has_binary_toc),hasBinaryIndex:T(t.hasBinaryIndex??t.has_binary_index),hasFullTextIndex:T(t.hasFullTextIndex??t.has_full_text_index)||!!(t.fullTextIndex&&typeof t.fullTextIndex=="object"&&t.fullTextIndex.available)}},z=e=>Array.isArray(e)?e.flatMap(t=>{if(!t||typeof t!="object")return[];let n=t,r=d(n.path||n.name);return r?[{path:r,size:S(n.size??n.length??n.byteLength??n.byte_length)??0,section:S(n.section)}]:[]}):[];var P=self,m,b,k,H=0,L=new Set,C=(e,t=[])=>{P.postMessage(e,t)},p=(e,t,n)=>{C({id:0,ok:!0,type:"progress",phase:e,current:t,total:n})},v=()=>{if(m)try{m.dispose?.()}finally{try{m.free?.()}catch{}m=void 0,b=void 0,k=void 0,H=0,L.clear()}},Z=e=>e.match(/^([A-Z][A-Z0-9_]+):/)?.[1],J=e=>{let t=e instanceof Error?e.message:String(e);return{name:e instanceof Error?e.name:"Error",message:t,code:Z(t)}},Q=async(e,t)=>{p("wasm",0,1);let n=await import(e);if(typeof n.default=="function"&&await n.default({module_or_path:t}),typeof n.ChmArchive!="function")throw new Error("CHM_WASM_API_MISMATCH: ChmArchive is not exported by the WASM module.");return p("wasm",1,1),n},ee=async e=>{if(v(),e.buffer.byteLength>e.limits.maxArchiveBytes)throw new Error(`CHM_LIMIT_EXCEEDED: source is ${e.buffer.byteLength} bytes; limit is ${e.limits.maxArchiveBytes}.`);let t=await Q(e.moduleUrl,e.wasmUrl);p("directory",0,1),m=new t.ChmArchive(new Uint8Array(e.buffer),e.limits),k=e.limits;let n=z(m.entries());if(n.length>e.limits.maxEntries)throw new Error(`CHM_LIMIT_EXCEEDED: ${n.length} entries exceed limit ${e.limits.maxEntries}.`);return p("directory",1,1),p("manifest",0,1),b=$(m.manifest()),p("manifest",1,1),{manifest:b,entries:n}},W=()=>{if(!m||!b||!k)throw new Error("CHM_NOT_OPEN: no CHM archive is active in this Worker.");return{archive:m,manifest:b,limits:k}},U=e=>{let t=W(),n=t.archive.read(e);if(n.byteLength>t.limits.maxEntryBytes)throw new Error(`CHM_LIMIT_EXCEEDED: entry ${e} exceeds ${t.limits.maxEntryBytes} bytes.`);let r=e.toLocaleLowerCase();if(!L.has(r)){let i=H+n.byteLength;if(i>t.limits.maxTotalDecompressedBytes)throw new Error(`CHM_LIMIT_EXCEEDED: unique decoded content exceeds ${t.limits.maxTotalDecompressedBytes} bytes.`);L.add(r),H=i}return n},te=e=>{let t=_(e);if(!t)throw new Error("CHM_BAD_PATH: the requested entry path is invalid.");let n=U(t);return n.byteOffset===0&&n.byteLength===n.buffer.byteLength?n:n.slice()},ne=(e,t)=>{let r=e.toLocaleLowerCase().indexOf(t);if(r<0)return"";let i=Math.max(0,r-72),o=Math.min(e.length,r+t.length+128);return`${i?"\u2026":""}${e.slice(i,o).trim()}${o<e.length?"\u2026":""}`},re=(e,t,n)=>{let r=W(),i=e.trim().toLocaleLowerCase();if(!i)return{hits:[],inspected:0,truncated:!1};let o=[],a=new Set,s=r.manifest.topics.slice(0,Math.max(1,n)),l=0;p("search",0,s.length);for(let c of s){if(o.length>=t)break;let u=_(c.path);if(!u||a.has(u.toLocaleLowerCase()))continue;a.add(u.toLocaleLowerCase()),l+=1;let g=c.title.toLocaleLowerCase().includes(i),f="";try{let h=U(u),x=D(N(h,r.manifest.encoding));f=ne(x,i)}catch(h){if(h instanceof Error&&h.message.startsWith("CHM_LIMIT_EXCEEDED:"))throw h}(g||f)&&o.push({title:c.title||u,path:u,snippet:f,titleMatch:g}),l%64===0&&p("search",l,s.length)}return p("search",l,s.length),{hits:o,inspected:l,truncated:s.length<r.manifest.topics.length||o.length>=t}};P.addEventListener("message",async e=>{let t=e.data;try{if(t.type==="open"){let n=await ee(t);C({id:t.id,ok:!0,type:"open",...n});return}if(t.type==="read"){let n=te(t.path);C({id:t.id,ok:!0,type:"read",data:n},[n.buffer]);return}if(t.type==="search"){let n=re(t.query,Math.max(1,t.limit),Math.max(1,t.maxTopics));C({id:t.id,ok:!0,type:"search",...n});return}v(),C({id:t.id,ok:!0,type:"close"})}catch(n){t.type==="open"&&v(),C({id:t.id,ok:!1,type:t.type,error:J(n)})}});
|
package/dist/security.js
CHANGED
|
@@ -231,15 +231,82 @@ const normalizeEncoding = (value) => {
|
|
|
231
231
|
return normalized;
|
|
232
232
|
};
|
|
233
233
|
const sniffHtmlEncoding = (bytes) => {
|
|
234
|
+
var _a;
|
|
234
235
|
const prefix = bytes.subarray(0, Math.min(bytes.byteLength, 8192));
|
|
235
236
|
let ascii = '';
|
|
236
237
|
for (let index = 0; index < prefix.byteLength; index += 1) {
|
|
237
238
|
const value = prefix[index];
|
|
238
239
|
ascii += value >= 0x20 && value <= 0x7e ? String.fromCharCode(value) : ' ';
|
|
239
240
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
241
|
+
// Walk the bounded prefix once; overlapping whitespace regexes can backtrack.
|
|
242
|
+
let position = 0;
|
|
243
|
+
while (position < ascii.length) {
|
|
244
|
+
const open = ascii.indexOf('<', position);
|
|
245
|
+
if (open < 0)
|
|
246
|
+
break;
|
|
247
|
+
if (ascii.startsWith('<!--', open)) {
|
|
248
|
+
const end = ascii.indexOf('-->', open + 4);
|
|
249
|
+
position = end < 0 ? ascii.length : end + 3;
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
let cursor = open + 1;
|
|
253
|
+
const nameStart = cursor;
|
|
254
|
+
while (isHtmlNameCharacter(ascii[cursor]))
|
|
255
|
+
cursor += 1;
|
|
256
|
+
const name = ascii.slice(nameStart, cursor).toLowerCase();
|
|
257
|
+
const end = scanHtmlTagEnd(ascii, cursor);
|
|
258
|
+
position = name === 'script' || name === 'style'
|
|
259
|
+
? skipHtmlRawTextElement(ascii, end, name)
|
|
260
|
+
: end;
|
|
261
|
+
if (name !== 'meta')
|
|
262
|
+
continue;
|
|
263
|
+
const attributes = new Map();
|
|
264
|
+
while (cursor < end && ascii[cursor] !== '>') {
|
|
265
|
+
if (!isHtmlNameCharacter(ascii[cursor])) {
|
|
266
|
+
cursor += 1;
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
const start = cursor;
|
|
270
|
+
while (isHtmlNameCharacter(ascii[cursor]))
|
|
271
|
+
cursor += 1;
|
|
272
|
+
const attribute = ascii.slice(start, cursor).toLowerCase();
|
|
273
|
+
while (isAsciiWhitespace(ascii[cursor]))
|
|
274
|
+
cursor += 1;
|
|
275
|
+
if (ascii[cursor] !== '=')
|
|
276
|
+
continue;
|
|
277
|
+
cursor += 1;
|
|
278
|
+
while (isAsciiWhitespace(ascii[cursor]))
|
|
279
|
+
cursor += 1;
|
|
280
|
+
const quote = ascii[cursor] === '"' || ascii[cursor] === "'" ? ascii[cursor++] : '';
|
|
281
|
+
const valueStart = cursor;
|
|
282
|
+
if (quote) {
|
|
283
|
+
while (cursor < end && ascii[cursor] !== quote)
|
|
284
|
+
cursor += 1;
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
while (cursor < end && !isAsciiWhitespace(ascii[cursor]) && ascii[cursor] !== '>')
|
|
288
|
+
cursor += 1;
|
|
289
|
+
}
|
|
290
|
+
if (!attributes.has(attribute))
|
|
291
|
+
attributes.set(attribute, ascii.slice(valueStart, cursor));
|
|
292
|
+
if (quote && ascii[cursor] === quote)
|
|
293
|
+
cursor += 1;
|
|
294
|
+
}
|
|
295
|
+
let encoding = attributes.get('charset');
|
|
296
|
+
if (!encoding) {
|
|
297
|
+
for (const parameter of (attributes.get('content') || '').split(';')) {
|
|
298
|
+
const equals = parameter.indexOf('=');
|
|
299
|
+
if (equals >= 0 && parameter.slice(0, equals).trim().toLowerCase() === 'charset') {
|
|
300
|
+
encoding = parameter.slice(equals + 1);
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
const token = (_a = encoding === null || encoding === void 0 ? void 0 : encoding.trim().match(/^[^\s"'/>;]+/)) === null || _a === void 0 ? void 0 : _a[0];
|
|
306
|
+
if (token)
|
|
307
|
+
return normalizeEncoding(token);
|
|
308
|
+
}
|
|
309
|
+
return '';
|
|
243
310
|
};
|
|
244
311
|
const decodeWith = (bytes, encoding) => {
|
|
245
312
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@file-viewer/renderer-chm",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"THIRD_PARTY_NOTICES.md"
|
|
76
76
|
],
|
|
77
77
|
"dependencies": {
|
|
78
|
-
"@file-viewer/core": "3.0.
|
|
78
|
+
"@file-viewer/core": "3.0.3"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
81
|
"esbuild": "^0.28.1",
|