diff options
| author | Gabriel Schneider <[email protected]> | 2026-08-11 11:15:28 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-08-11 11:35:08 -0300 |
| commit | 89d93d5e7348304bc7d8a148f9ad9c1beb200459 (patch) | |
| tree | 50aea92dce0b42195dfe1beb5950a35c05618e33 /build.zig | |
| parent | a797a1ab2f648e773f7a1b28d12bf9441b9f13f4 (diff) | |
| download | pardes-89d93d5e7348304bc7d8a148f9ad9c1beb200459.tar.gz pardes-89d93d5e7348304bc7d8a148f9ad9c1beb200459.zip | |
mupdf: -Djpx, on by default, so a scanned PDF is not a blank page
A scan is typically one /JPXDecode image per page. With FZ_ENABLE_JPX=0 and no
openjpeg compiled, MuPDF raised "JPX support disabled" for every one of them
and handed back a page with nothing drawn on it -- the pane opened, the page
count was right, and the page was empty, which reads as a renderer bug rather
than a missing codec.
OPENJPEG_SRC comes out of Makelists through the same makeSources path the other
three third-party libraries already use, with MuPDF's own OPENJPEG_CFLAGS and
OPENJPEG_BUILD_CFLAGS, so there is no second source list to go stale.
-fno-sanitize=undefined for the reason source/fitz needs it: upstream C full of
deliberate wrapping arithmetic that ReleaseSafe's trap-mode UBSan would turn
into a crash.
FZ_ENABLE_JPX reaches the public headers, so Result carries the flag and
linkTo hands consumers the archive's actual value instead of re-deriving it --
a consumer that disagrees is an ODR bug that shows up as a wrong struct layout
at runtime rather than as a link error.
A switch at all because it is 31 files of third-party C parsing untrusted
input, and openjpeg has the CVE history to match. Default on because a viewer
that cannot open scans is the more surprising default. +1.6 MB of archive;
mupdf-check passes with it on and off.
Diffstat (limited to 'build.zig')
| -rw-r--r-- | build.zig | 8 |
1 files changed, 8 insertions, 0 deletions
@@ -61,6 +61,13 @@ pub fn build(b: *std.Build) void { const dump_path = b.option([]const u8, "dump", "dump .zon embedded into the web shell (-Dplatform=web)"); const is_web = platform == .web; const enable_mupdf = b.option(bool, "mupdf", "native PDF rendering with MuPDF (AGPL/commercial; native default on, web off; -Dmupdf=false disables)") orelse !is_web; + // JPEG 2000, and with it scanned PDFs: a scan is one /JPXDecode image per + // page, so without this MuPDF decodes nothing and every page comes back + // blank. On by default — a viewer that cannot open scans is the more + // surprising default — and a switch at all because it is 31 files of + // third-party C parsing untrusted input. See the OPENJPEG block in + // mupdf.zig. + const enable_jpx = b.option(bool, "jpx", "JPEG 2000 in PDFs, for scanned documents (default on; -Djpx=false drops openjpeg)") orelse true; const is_web_target = target.result.cpu.arch == .wasm32 and target.result.os.tag == .freestanding; // wasm: size is the budget const optimize = if (is_web) .ReleaseSmall else requested_optimize; @@ -362,6 +369,7 @@ pub fn build(b: *std.Build) void { const mupdf = mupdf_build.add(b, io, mupdf_dep, .{ .target = target, .optimize = c_optimize, + .jpx = enable_jpx, }); const mupdf_mod = b.createModule(.{ .target = target, |
