Age | Commit message (Collapse) | Author |
|
If the colorspace given in the dictionary of a JPX image differs from
the colorspace given in the image itself, decode to the native image
format, then convert.
This goes a long way towards fixing "1439 - color softmask fails to
draw jpx image.pdf" (aka hivemind.pdf). The lack of transfer function
support hopefully explains the rest.
|
|
Also change the way we pass the text rectangles so that
non-axis-aligned ones can be permitted, and relocate the code that
calculates the strike-out lines from the bounding boxes
|
|
|
|
|
|
Avoid heap overflow in the error case in fz_end_tile.
Avoid leaking all previously loaded annotations from pdf_load_annots
if pdf_is_dict throws an exception.
Various whitespace fixes.
Many thanks to zeniko.
|
|
A UTF-8 BOM followed by a UTF-16 BOM would treat the data as UTF-16 rather
than UTF-8. Clean up the BOM detection logic.
Thanks to zeniko.
|
|
Thanks to zeniko.
|
|
Thanks to zeniko.
|
|
Thanks to zeniko.
|
|
Thanks to zeniko.
|
|
Thanks to zeniko.
|
|
Thanks to zeniko.
|
|
Thanks to zeniko.
|
|
Thanks to zeniko.
|
|
Thanks to zeniko.
|
|
|
|
|
|
|
|
|
|
Also, move fz_is_infinite_rect and fz_is_empty_rect to be a static
inline rather than a macro. (Static inlines are preferred over
macros by at least one customers).
We appear to be calling them with bboxes too, so add fz_is_infinite_bbox
and fz_is_empty_bbox to solve this.
|
|
This is faster on ARM in particular. The primary changes involve
fz_matrix, fz_rect and fz_bbox.
Rather than passing 'fz_rect r' into a function, we now consistently
pass 'const fz_rect *r'. Where a rect is passed in and modified, we
miss the 'const' off. Where possible, we return the pointer to the
modified structure to allow 'chaining' of expressions.
The basic upshot of this work is that we do far fewer copies of
rectangle/matrix structures, and all the copies we do are explicit.
This has opened the way to other optimisations, also performed in
this commit.
Rather than using expressions like:
fz_concat(fz_scale(sx, sy), fz_translate(tx, ty))
we now have fz_pre_{scale,translate,rotate} functions. These
can be implemented much more efficiently than doing the fully
fledged matrix multiplication that fz_concat requires.
We add fz_rect_{min,max} functions to return pointers to the
min/max points of a rect. These can be used to in transformations
to directly manipulate values.
With a little casting in the path transformation code we can avoid
more needless copying.
We rename fz_widget_bbox to the more consistent fz_bound_widget.
|
|
It seems that gcc requires arg lists to be 'va_copy'ied, otherwise
they can't be reused. This solves problems in the rework of
fz_buffer_printf.
|
|
Better tolerate long horizontal spaces without breaking lines.
|
|
Send blocks as paragraphs, rather than lines. Send lines as spans.
|
|
Various functions in the code output to FILE *, when there are times
we'd like them to output to other things, such as fz_buffers.
Add an fz_output type, together with fz_printf to allow things to
output to this.
|
|
|
|
Also simplify some other functions using pdf_dict_puts_drop
|
|
|
|
|
|
It used to be called fz_bbox_covering_rect. It does exact rounding outwards
of a rect, so that the resulting irect will always cover the entire
area of the input rect.
Use fz_round_rect for fuzzy rounding where near-integer values are
rounded inwards.
|
|
Inside the renderer we often deal with integer sized areas, for
pixmaps and scissoring regions. Use a new fz_irect type in these
places.
|
|
|
|
|
|
|
|
Jarkko Poyry(*) points out that gradients are incorrectly rendered
when they aren't axis aligned. This review fixes it here using a
patch inspired by both his and zenikos patch. Thanks guys.
Further thanks to zeniko for spotting that it applies to the XPS
code too and providing a patch.
* Apologies for the lack of the accent - my editor/git gives problems
with them in commit messages.
|
|
Simple patch to replace const char * with char *. I made the patch
myself, but I suspect it's extremely close to the one submitted
by Evgeniy A Dushistov, who reported the bug - many thanks!
|
|
Talking to zeniko, he reports that SEGVs still occur in find_changing
within the fax decoder; he doesn't have an example that shows the
problem though (either one he can share, or one he cannot). Presumably
he has some sort of online feedback thing in the event of crashes.
Having stared at the code for a while, I see a potential problem.
I think the code may read too many bytes in the case where we
are entered with x already within the last byte of w. (i.e. where
x >= ((w-1)>>3)<<3). Fixed here.
|
|
If a PDF xref subsection is broken in the wrong place, we can get
NULL back from fz_strsep, which causes a SEGV when fed to atoi.
Add a new fz_atoi that copes with NULL to avoid this.
Problem found in a test file, 3959.pdf.SIGSEGV.ad4.3289 supplied
by Mateusz "j00ru" Jurczyk and Gynvael Coldwind of the Google
Security Team using Address Sanitizer. Many thanks!
|
|
When cleaning a file with a corrupt stream in it, historically mupdf
would give up when it encountered such a stream. This is often not
what is desired, as information can be lost.
The changes herein allow us to use our best efforts when reading
a stream, so that broken streams are reproduced in the output
cleaned file.
Problem found in a test file, pdf_001/2599.pdf.asan.58.1778 supplied
by Mateusz "j00ru" Jurczyk and Gynvael Coldwind of the Google
Security Team using Address Sanitizer. Many thanks!
|
|
While investigating samples_mupdf_001/2599.pdf.asan.58.1778, a leak
showed up while cleaning the file, due to not dropping an object in
an error case.
mutool clean -dif samples_mupdf_001/2599.pdf.asan.58.1778 leak.pdf
Simple Fix. Also extend PDF writing so that it can cope with skipping
errors so we at least get something out at the end.
Problem found in a test file supplied by Mateusz "j00ru" Jurczyk and
Gynvael Coldwind of the Google Security Team using Address Sanitizer.
Many thanks!
|
|
With added comment to explain the funky boolean logic.
|
|
Two problems with tiling are fixed here.
Firstly, if the tiling bounds are huge, the 'patch' region (the region
we are writing into), can overflow, causing a SEGV due to the paint code
being very confused by pixmaps that go from just under INT_MAX to just
over INT_MIN. Fix this by checking explicitly for overflow in these
bounds.
If the tiles are stupidly huge, but the scissor is small, we can end up
looping many more times than we need to. We fix mapping the scissor
region back through the inverse transform, and intersecting this
with the pattern area.
Problem found in 4201.pdf.SIGSEGV.622.3560, a test file supplied by
Mateusz "j00ru" Jurczyk and Gynvael Coldwind of the Google Security
Team using Address Sanitizer. Many thanks!
|
|
When calculating the bbox for draw_glyph, if the x and y origins of
the glyph are extreme (too large to fit in an int), we get overflows
of the bbox; empty bboxes are transformed to large ones.
The fix is to introduce an fz_translate_bbox function that checks for
such things.
Also, we update various bbox/rect functions to check for empty bboxes
before they check for infinite ones (as a bbox of x0=0 x1=0 y0=0 y1=-1
will be detected both as infinite and empty).
Problem found in 2485.pdf.SIGSEGV.2a.1652, a test file supplied by
Mateusz "j00ru" Jurczyk and Gynvael Coldwind of the Google Security
Team using Address Sanitizer. Many thanks!
|
|
It is perfectly allowable to have type3 glyphs that refer to
other type3 glyphs in the same font (and in theory it's probably
even possible to have type3 glyphs that refer back and forth
between 2 or more type3 fonts).
The old code used to cope with this just fine, but with the change
to 'early loading' of the glyphs to display lists at interpret time
a problem has crept in. When we load the type 3 font, we load
each glyph in turn. If glyph 1 tries to use glyph 2, then we look
up the font, only to find that that the font has not been installed
yet, so we reload the entire font. This gets us into an infinite
loop.
As a fix for this, we split the loading of the type3 font into 2; we
load the font as normal, then allow the font to be inserted into
the list of current fonts. Then we run through the glyphs in the
font 'preparing' them (turning them into display lists).
This solves the infinite loop issue, but causes another problem;
recursive references (such as a font holding a display list that
contains a text node that contains a reference to the original font)
result in us never being able to free the structures.
To avoid this, we insist on never allowing type3 glyphs to be referenced
within a type3 display list. The display lists for all type3 glyphs
are therefore 'flat'. We achieve this by adding a 'nested' flag to
the pdf command stream interpreter structure, and setting this in the
case where we are running a glyph stream. We check for that flag in the
type3 glyph render function, and if present, we force the 'render_direct'
path to be used.
Finally, we ensure that fz_text groups are not needlessly created with
no contents.
Problem found in 2923.pdf.asan.22.2139, a test file supplied by
Mateusz "j00ru" Jurczyk and Gynvael Coldwind of the Google Security
Team using Address Sanitizer. Many thanks!
|
|
Leaking long linked lists leads to stack overflows during the
Memento debug output. Avoid this by iterating rather than recursing
where possible.
Also, for sanities sake, where we intent more than 40 spaces, use a
single '*' instead. This keeps logfiles sane.
|
|
Whenever we have an error while pushing a gstate, we run the risk of
getting confused over how many pops we need etc.
With this commit we introduce some checking at the dev_null level that
attempts to make this behaviour consistent.
Any caller may now assume that calling an operation that pushes a clip
will always succeed. This means the only error cleanup they need to
do is to ensure that if they have pushed a clip (or begun a group, or
a mask etc) is to pop it too.
Any callee may now assume that if it throws an error during the call
to a device entrypoint that would create a group/clip/mask then no more
calls will be forthcoming until after the caller has completely finished
with that group.
This is achieved by the dev_null layer (the layer that indirects from
device calls through the device structure to the function pointers)
swallowing errors and regurgitating them later as required. A count is
kept of the number of pushes that have happened since an error
occurred during a push (including that initial one). When this count
reaches zero, the original error is regurgitated. This allows the
caller to keep the cookie correctly updated.
|
|
With illegal fax streams we could access beyond the right hand edge
of the allocated line. Fix this by adding some simple checks.
Issue found by Mateusz "j00ru" Jurczyk and Gynvael Coldwind of the
Google Security Team using Address Sanitizer. Many thanks!
|
|
If an illegal keysize is passed into the AES crypt filter, we
currently exit without setting up the AES context. This causes
us to fail in all manner of ways later on.
We now return failure and callers throw an exception.
This appears to solve all the SEGVs and memory exceptions found in
crypt_aes by Mateusz "j00ru" Jurczyk and Gynvael Coldwind of the
Google Security Team using Address Sanitizer. Many thanks!
|
|
The issues fixed here were found by zeniko - many thanks.
The patch here is our own work - larger change, avoiding casts
for a (hopefully) neater result.
|
|
Thanks to zeniko for pointing out that the recent changes to
the fz_try/fz_catch macros to allow for throws in the fz_always
block had broken the exception stack overflow case.
Thanks also for the example file (nesting stack overflow.pdf),
which has now been added to the regression suite.
|