Bug 700301 - infinite loop in function svg_dev_end_tile in source/fitz/svg-device.c
Summary: infinite loop in function svg_dev_end_tile in source/fitz/svg-device.c
Alias: None
Product: MuPDF
Classification: Unclassified
Component: svg output (show other bugs)
Version: master
Hardware: PC Linux
: P4 normal
Assignee: Robin Watts
Depends on:
Reported: 2018-11-30 03:08 UTC by kuaicar87
Modified: 2019-05-16 13:16 UTC (History)
1 user (show)

See Also:
Word Size: ---

the POC to trigger the bug (1.21 KB, application/pdf)
2018-11-30 03:08 UTC, kuaicar87

Note You need to log in before you can comment on or make changes to this bug.
Description kuaicar87 2018-11-30 03:08:49 UTC
Created attachment 16426 [details]
the POC to trigger the bug

When I tried to convert a pdf file to svg file, there is an infite loop in svg_dev_end_tile in source/fitz/svg-device.c. 

static void
svg_dev_end_tile(fz_context *ctx, fz_device *dev)

for (x = 0; x > -w; x -= t->step.x)
		for (y = 0; y > -h; y -= t->step.y)
			fz_write_printf(ctx, out, "<use x=\"%g\" y=\"%g\" xlink:href=\"#pac%d\"/>\n", x, y, t->pattern);

gef➤  p t.step
$11 = {
  x = 0, 
  y = 0
because the values of t->step.x and t->step.y always are zero, so the program can be stuck in infinite loop state.
Comment 1 kuaicar87 2018-11-30 03:10:23 UTC
This bug is reported by fish@360TeamSeri0us, please send email to teamSeri0us360@gmail.com if you have some quetions.
Comment 2 M.J.G. 2019-05-13 13:00:59 UTC
I can confirm this bug is still present in 1.15.0.
Comment 3 Tor Andersson 2019-05-15 17:05:28 UTC
commit 754ac68f119e0c25cd33c5d652d8aabd533a9fb3
Author: Robin Watts <Robin.Watts@artifex.com>
Date:   Mon May 13 13:28:57 2019 +0100

    Bug 700301: Fix potential infinite loop in svg output device.
    The POC in the bug no longer triggers the problem, but potentially
    the problem is there all the same.
    Spot an attempt to define a pattern with X or Y height of 0, and
    cope with it. We print a warning, and reset the X or Y step to 1.
Comment 4 M.J.G. 2019-05-16 13:16:21 UTC
I don't want to be extra picky, but I'm not sure this fix is complete:

Since we're dealing with floats here, xstep and ystep may very well be != 0 (say, only in the lowest digit) but as soon as we add up the steps often enough (say, 10^d times, d the representable digits) we will have x == x - xstep, i.e. the same problem.

Thus, an evil attacker can still trigger the bug with specifically chosen steps.

I see two possible solutions:

- impose a larger lower bound on the step size (then just >0) in begin_tile()

- check for x-xstep != xstep in end_tile(); might be too expensive