[PATCH 02/20] mi: miPutImage with XYPixmap failed at depth 32 on 64-bit machines

Aaron Plattner aplattner at nvidia.com
Wed Mar 19 12:37:01 PDT 2014


On 03/18/2014 10:09 PM, Keith Packard wrote:
> The X server still has 'unsigned long' in a few places to hold 32 bit
> values. One of those is in miPutImage where it's holding the temporary
> planemask for XYPixmap format images.
>
> It computed the highest plane in the source image with 1 << (depth -
> 1). On 64-bit machines, taking that value and storing it in an
> unsigned long promotes it to a signed 64-bit value
> (0xffffffff80000000).
>
> Then, it loops over that value, shifting one bit right each time,
> waiting for it to go to zero.. That takes 64 iterations, and ends up
> with some mystic planemask values *and* walking off the end of the
> source image data and out into space.
>
> A simple cast is all that is required to compute the correct initial
> plane mask (0x0000000080000000), at which point the loop operates
> correctly once again.
>
> Checking the fbPutImage code, I note that this same bug was fixed
> in 2006 by Aaron Plattner in commit
> f39fd4242902eaa862321d39337f429dd14ebacf
>
> Signed-off-by: Keith Packard <keithp at keithp.com>

Sorry for not noticing this when I fixed the other one.  Also, since 
2006 I learned that you can use 1UL instead of a cast to unsigned long, 
if that seems cleaner.

Reviewed-by: Aaron Plattner <aplattner at nvidia.com>

I still think we should make the server replace all XYPixmap images with 
a picture of something rude.

> ---
>   mi/mibitblt.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/mi/mibitblt.c b/mi/mibitblt.c
> index b0d14ae..3ed4ed1 100644
> --- a/mi/mibitblt.c
> +++ b/mi/mibitblt.c
> @@ -730,7 +730,7 @@ miPutImage(DrawablePtr pDraw, GCPtr pGC, int depth,
>           ChangeGC(NullClient, pGC, GCForeground | GCBackground, gcv);
>           bytesPer = (long) h *BitmapBytePad(w + leftPad);
>
> -        for (i = 1 << (depth - 1); i != 0; i >>= 1, pImage += bytesPer) {
> +        for (i = (unsigned long) 1 << (depth - 1); i != 0; i >>= 1, pImage += bytesPer) {
>               if (i & oldPlanemask) {
>                   gcv[0].val = (XID) i;
>                   ChangeGC(NullClient, pGC, GCPlaneMask, gcv);
>

-- 
Aaron


More information about the xorg-devel mailing list