Use after free w/ PicDocument image decoding or rendering & MuPDF scaling
NiLuJe opened this issue · comments
c.f. #816 for the original crash report.
The quickest repro I could get is simply to alternate between opening a PNG and viewing its cover (possibly throwing an unscale/rescale pass in the process).
i.e.,
- Long-press on image > "View full size cover"
- Original size
- Scale
- Back to FM
- Tap on image to "open" it
- Back to FM
- Long-press on image > "View full size cover"
- KABLOOEY
Tracked down to ffi/pic.lua
's doc.image_bb:setAllocated(1)
in openPNGDocument
.
I don't know when exactly it gets free'd, but stuff blows up in ffi/mupdf.lua
's fz_scale_pixmap
in scaleBlitBuffer
.
I'm not familiar with the BB intricacies as far as the allocated flag is concerned, and the FFI + GC interactions make my brain hurt. (Plus, LodePNG's use of a double pointer for the output buffer doesn't help).
On a hunch, I tried with a JPG: same issue ;).
(In this case, memory is allocated by BB:new, which automatically sets the allocated flag, though).
Okay, further narrowed it down to PicDocument.
If I associate an image w/ MuPDF, I can do the toggle dance all day long without a crash.
If it gets open'ed by PicDocument, the next show cover will crash.
Which neatly explains why this hadn't been caught before, I don't imagine a lot of people are actually actively using PicDocument & Show Cover in succession ;).
I remember I added PicDocument:getCoverPageImage()
very quickly, without thinking much.
It may be all other xxxdocument:getCoverPageImage() returns a copy/own image object, so the code can free it with done - unlike this PicDocument:getCoverPageImage()
which seem to return the object. It should just return a copy I guess.
(^ Quickly jotted down, I haven't checked much)