Bug#422712: gs-esp: pstoraster fails with signal 11 when printing cups testpage
On Sunday 23 January 2011, Jonathan Nieder wrote:
> tags 422712 + moreinfo
> quit
>
> Hi,
>
> Troy Rollo wrote:
> > This only seems to affect applications using the CUPS v1.1 libraries -
> > applications using the CUPS v1.2 libraries seem to work OK.
> >
> > diff -ru gs-esp-8.15.3.dfsg.1/src/gxcht.c
> > gs-esp-8.15.3.dfsg.1-fixed/src/gxcht.c ---
> > gs-esp-8.15.3.dfsg.1/src/gxcht.c 2005-01-19 15:08:41.000000000 +1100 +++
> > gs-esp-8.15.3.dfsg.1-fixed/src/gxcht.c 2007-12-25 19:55:36.000000000
> > +1100 @@ -1087,7 +1087,14 @@
> > int tw = btile->size.x;
> > int bx = ((ptc->tile_shift = btile->shift) == 0 ? endx :
> > endx + lasty / btile->size.y * ptc->tile_shift) % tw;
> > - int by = lasty % btile->size.y;
> > + int by;
> > +
> > + if (lasty < 0)
> > + by = btile->size.y - (-lasty % btile->size.y);
> > + else
> > + by = lasty % btile->size.y;
> > +
> > + by = lasty % btile->size.y;
>
> This patch does not seem to be part of current ghostscript. Could
> you explain what it does? Is there an example postscript file and gs
> invocation that would trigger it, or is it useful for robustness reasons?
That's the wrong version of the patch. The correct version looks like this:
> diff -ru gs-esp-8.15.3.dfsg.1.orig/src/gxcht.c
> gs-esp-8.15.3.dfsg.1/src/gxcht.c --- gs-esp-8.15.3.dfsg.1.orig/src/gxcht.c
> 2007-12-27 09:39:57.000000000 +1100 +++
> gs-esp-8.15.3.dfsg.1/src/gxcht.c 2007-12-27 10:57:54.000000000 +1100 @@
> -1087,7 +1087,18 @@
> int tw = btile->size.x;
> int bx = ((ptc->tile_shift = btile->shift) == 0 ? endx :
> endx + lasty / btile->size.y * ptc->tile_shift) % tw;
> - int by = lasty % btile->size.y;
> + int by;
> +
> + if (lasty < 0)
> + {
> + by = btile->size.y - (-lasty % btile->size.y);
> + if (by == btile->size.y)
> + by = 0;
> + }
> + else
> + {
> + by = lasty % btile->size.y;
> + }
>
> ptc->xoffset = bx >> 3;
> ptc->xshift = 8 - (bx & 7);
I do not recall the precise reasoning behind this, other than that at the time
the patch seemed to make sense mathematically and without it there was a
segmentation violation, however running a short program seems to reveal the
problem:
> troy@enterprise:~$ cat test.c
> #include <stdio.h>
>
> #define TEST(x) printf(#x " = %d\n", x)
>
> int
> main(int argc, char **argv)
> {
> TEST(5 % 8);
> TEST(-3 % 8);
> return 0;
> }
> troy@enterprise:~$ gcc test.c
> troy@enterprise:~$ ./a.out
> 5 % 8 = 5
> -3 % 8 = -3
> troy@enterprise:~$
The code patched seems to attempt to constrain "lasty" to a position within
the passed in "btile", vertically (that is, "btile->size.y"). That would mean
the output had to be in the range (0,btile->size.y - 1). Where lasty is less
than zero, the modulo formula returns a negative number, so the output is not
in that range, hence a segmentation violation.
Take f(x) being "x % btile->size.y". The following is true for all positive
integer "x" and "n":
f(x) == f(x + btile->size.y * n)
I assumed that the desired behaviour was to have a function, f(x), that
behaved like "x % btile->size.y" for all positive "x", but where the above
relationship was also true if either "x" or "n" (or both) was negative. The
condition does that.
To put it another way, if btile->size.y is 8, then I assumed we want:
f(9) == 1
f(8) == 0
f(7) == 7
f(6) == 6
f(5) == 5
f(4) == 4
f(3) == 3
f(2) == 2
f(1) == 1
f(0) == 0
f(-1) == 7
f(-2) == 6
etc.
Does that sufficiently answer your question?
Reply to: