[cups-devel] Crash in rastertoepson.c

Matthew Ogilvie mmogilvi_cups at miniinfo.net
Sat Mar 7 19:53:25 PST 2015


rastertoepson.c will crash near line 658 if header->cupsWidth
is an odd number, because "width" is unsigned and when it is always
decremented by 2, an odd number will never become less than 1.

>        for (width = header->cupsWidth, tempptr = CompBuffer;
>             width > 0;
>             width -= 2, tempptr += 2, oddptr += DotBytes * 2,
>                 evenptr += DotBytes * 2)

I saw this when trying to print IRS form 8889 using
evince 3.12.2, when I configured cups with a generic
Epson 24 pin dot matrix printer, and ask to print it
with a resolution of either 360x180 or 180x180.  The
crash probably became reliable as of commit
7e86f2f686334cb3db458b4585dfce9c1b712bc4 in Feb 2014,
when several variables were changed to unsigned.  But I'm not
sure if the code correctly handled the odd-number width case
before that: it might have had a buffer overflow that was
rarely apparent - one instead of infinite.

Another problem: Although it isn't hit in the same configuration,
there might be a problem in the interleave case of OuptutRow()
as well: if the quantitiy (dot_count/DotBytes) happens to be
odd, then it will be one byte short outputing characters to
the printer in each case, interpreting the next byte (often "\033")
as part of the bitmap data.  I'm uncertain if this happens
in practice, or only in theory.

--------------

Working around firmware bug:

Slight tangent: I specifically have an old "ALPS 324e" dot
matrix printer, and it isn't printing shingled data
from this driver correctly even when the above is avoided.
(other document, or a minimally hacked driver):  It will
generates a vertically doubled/blurry image that is very
ugly (off by about 3 or 4 pixels).

After carefully auditing the middle-of-the-image shingling
logic [looks good, at least ignoring if boundary conditions],
examing the input raster data fed into rastertoepson [looks
good], and directly sending the printer hand-crafted test
patterns [without cups at all], it looks like the printer
has some kind of firmware bug that causes it to advance
the page an incorrect amount when the newline advance is
set to less than 24/180 of an inch AND other conditions theat I
haven't fully characterized involving dataless blank lines
are met.  These bad conditions happen to be met for every
pair of lines when the driver is doing the shingling thing.

If I hack the driver to avoid shingling in the 180x180 and
360x180 cases (and instead rely on a slightly tweaked version
of the "interleave" case in OutputRows()), then it seems to
work MUCH better.  When properly driven, the printer's output
is fairly hard to tell is from a dot matrix printer.

QUESTION: If I submitted a cleaned up version of my hack to
disable shingling in the 180x180 and 360x180 cases, is there
any chance it would be accepted?  Or is there some reason
to prefer the shingling operation for other printers that
I'm just not seeing?

As near as I can tell, the shingling is useless in these
cases.  It usually isn't any faster than interleaving, and at
least in my buggy firmware case, the interleaving is a much
more robust way to handle printer limitations with consecutive
pixels.  I'm not sure about the 360x360 case: This printer's
documentation doesn't seem to claim any way to support it,
I'm not sure how it is supposed to work, and I would probably
leave it as-is.

--------------

Farther-off tangent: I also have an "Epson Stylus Color 980 N"
inkjet printer.  I think it uses a driver from gutenprint instead
of cup's rastertoepson, although I haven't dug into the details yet.

But the interesting thing is that its output (when driven from
cups+gutentprint) has always been doubled/blurry in a way that
is very similar to the ALPS printer (a few pixels off vertically).
It seems odd that two completely different printers with (presumably)
different drivers would look as similar as these do.

When driven from a much older machine (using another driver
framework not related to cups+gutenprint at all), both the
Epson and the ALPS look much better.

History trivia: The inkjet uglyness thing has long been an
annoyance, but I mostly just lived with it because I only
rarely need to print anything.  But then its ink ran/dried out yet
again, and when I finally tried to switch back to the ALPS, I
ran into both a similar problem and a crash, and decided to spend
a little time digging into it...

--
Matthew Ogilvie



More information about the cups-devel mailing list