PageSourceSearch

https://www.pdfwix.com/qpdf/worker.js

js pdfwix.com collected 2026-10-08 10:49:01 UTC 3,187 bytes, 84 lines download raw bytes

1/* eslint-disable */
2/**
3 * Classic Web Worker that runs the qpdf CLI compiled to WebAssembly locally in
4 * the browser.
5 *
6 * Why local: the edge function runs the same WASM, but an edge worker has a
7 * small fixed memory budget and qpdf needs the whole document addressable in
8 * memory (the encryption key is document-wide and the xref must be parsed
9 * first, so decryption cannot be chunked). Multi-MB files therefore died with
10 * WORKER_RESOURCE_LIMIT. A browser tab has orders of magnitude more heap, so we
11 * run it here and keep the server only as a fallback.
12 *
13 * Protocol:
14 *   in  { id, args: string[], bytes: ArrayBuffer }
15 *   out { id, ok: true, bytes: ArrayBuffer } | { id, ok: false, error, exitCode }
16 */
17self.importScripts("/qpdf/qpdf.js");
18
19self.onmessage = async (ev) => {
20  const { id, args, bytes } = ev.data || {};
21  const stderr = [];
22  let exitCode = 0;
23  let module;
24
25  try {
26    module = await self.Module({
27      locateFile: (p) => (p.endsWith(".wasm") ? "/qpdf/qpdf.wasm" : "/qpdf/" + p),
28      noInitialRun: true,
29      print: () => {},
30      printErr: (s) => { stderr.push(String(s)); },
31      quit: (code) => { exitCode = code; },
32    });
33  } catch (e) {
34    self.postMessage({ id, ok: false, error: "engine-init: " + (e && e.message ? e.message : String(e)) });
35    return;
36  }
37
38  try {
39    // Some Emscripten builds capture their logging hooks before the factory
40    // options are merged, so re-assign them on the live module too.
41    module.printErr = (s) => { stderr.push(String(s)); };
42    module.print = () => {};
43    // This qpdf build is minified and writes some diagnostics straight to the
44    // console, so tap the console as well to recover the real reason.
45    const realError = console.error;
46    const realWarn = console.warn;
47    console.error = (...a) => { stderr.push(a.join(" ")); };
48    console.warn = (...a) => { stderr.push(a.join(" ")); };
49    const restore = () => { console.error = realError; console.warn = realWarn; };
50    module.FS.writeFile("/in.pdf", new Uint8Array(bytes));
51    try {
52      module.callMain(args);
53    } catch (e) {
54      if (e && typeof e.status === "number") exitCode = e.status;
55      else if (e) stderr.push("threw: " + (e.message || String(e)));
56    }
57
58    restore();
59
60    let out = null;
61    try { out = module.FS.readFile("/out.pdf"); } catch (_) { out = null; }
62
63    // qpdf exit 3 means "completed with warnings" — the output is written and
64    // usable, which is the normal case for damaged documents.
65    if (out && out.length > 100 && (exitCode === 0 || exitCode === 3)) {
66      const buf = out.buffer.slice(out.byteOffset, out.byteOffset + out.byteLength);
67      self.postMessage({ id, ok: true, bytes: buf }, [buf]);
68    } else {
69      self.postMessage({
70        id,
71        ok: false,
72        exitCode,
73        error: stderr.join("\n").slice(0, 500),
74      });
75    }
76  } catch (e) {
77    self.postMessage({ id, ok: false, error: (e && e.message) || String(e) });
78  } finally {
79    try { module.FS.unlink("/in.pdf"); } catch (_) {}
80    try { module.FS.unlink("/out.pdf"); } catch (_) {}
81    // A fresh module per run keeps the WASM heap from growing across files.
82    module = null;
83  }
84};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.