Repository navigation
Conversation
…ot segfault Blend2D's JIT analytic fill reused a stale span length when the last coverage word of a scanline was all ones, which happens when an affine image blit's edge crosses the right clip edge and the clip width is 252..255 mod 256. The zero-length span then ran the per-pixel loop 2^32 times and walked the destination pointer off the heap. Page 7 of the PDF in docling-project#365 hits exactly that at scale 3.0 (1279 px canvas). Carry the upstream fix (blend2d/blend2d#268, for blend2d/blend2d#267) as a FetchContent PATCH_COMMAND on the pinned commit, applied once by cmake/apply_patch.cmake, and add a regression test that renders a synthetic page on the crashing geometry in a child process. Fixes docling-project#365 Signed-off-by: Jeff Witt <1848307+wittjeff@users.noreply.github.com>
|
✅ DCO Check Passed Thanks @wittjeff, all your commits are properly signed off. 🎉 |
Merge Protections🟢 Merge protection satisfied — ready to merge. Show 1 satisfied protection🟢 Enforce conventional commitMake sure that we follow https://www.conventionalcommits.org/en/v1.0.0/
|
|
Likely production hit, for prioritisation: docling-serve v1.37.0 (docling-parse 7.22.3) died with SIGSEGV |
|
Follow-up: confirmed. Converting the production document page by page, one page crashes with SIGSEGV whenever EasyOCR renders it at the default scale 3.0, and converts at 2.99 and 3.01: docling-serve v1.38.1 (docling-parse 7.23.0), x86_64. The document is a scanned book with slightly skewed CCITT/JBIG2 page images; two neighbouring pages crash the same way. The page from #365 crashes in the same setup and converts at 2.99. With |
|
Thanks for this contribution. This PR is on hold until it has been consolidated as described in #428. Please resubmit it as part of the topic PR listed there, with the evidence the issue asks for. |
Fixes #365.
What
get_image()segfaulted on page 7 of the scanned manual from #365 at exactly scale 3.0. The crash is inside Blend2D's JIT-generated analytic fill, not in docling-parse code, and it is triggered by a combination of our geometry and the clip width:render_bitmap_affine.FillAnalyticPartthen re-enters its bit-scan loop from the bit-gap path with a stale span length (0 after the constant-mask loop) instead of 64, computes a zero-length span, and its per-pixel do/while loop runs 2^32 times until the destination pointer leaves the heap.Root cause and trace: blend2d/blend2d#267. Upstream fix: blend2d/blend2d#268.
This PR:
PATCH_COMMANDon the pinned Blend2D commit (cmake/blend2d-fillanalytic-stale-i.patch, applied once bycmake/apply_patch.cmake, which detects an already-applied patch on re-population). Drop both when the pin moves past the upstream fix.tests/test_unit_affine_image_clip.py: a 255.5 x 5 pt page (511 x 10 px at scale 2) with a 16 x 16 image placed on the crashing geometry. It renders in a child process so a regression fails the test with the signal instead of killing the pytest run. It fails with-11on the current wheels and passes with the patch.Why it looked like a 7.10.0 regression
Affine image blits exist since v5.9 (#250). 7.9.0 rendered this page only because its int-truncated crop box gave a 1278 x 1794 canvas with the top edge 1.7 px higher, which kept the skewed edge above the canvas. #305 moved the geometry by about 2 px into the failing configuration. Any version can hit this with the right PDF, and clip rectangles can trigger it at any canvas width, so padding the canvas would not be a fix.
Verification