summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2014-03-18 21:35:41 -0700
committerEric Anholt <eric@anholt.net>2014-03-26 12:58:40 -0700
commit11e2f0de71fa341f8b0b1da0a1b9ccbfa6550a50 (patch)
treefea477d492c7a453d8e0cfbd41f9e3b0532727c4
parentae87b536155207e6e28b68963593a7ab09792e08 (diff)
downloadxserver-11e2f0de71fa341f8b0b1da0a1b9ccbfa6550a50.tar.gz
mi: miPutImage with XYPixmap failed at depth 32 on 64-bit machines
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@keithp.com> Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Aaron Plattner <aplattner@nvidia.com>
-rw-r--r--mi/mibitblt.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/mi/mibitblt.c b/mi/mibitblt.c
index b0d14ae55..3ed4ed1cc 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);