Package: libx11-6 Version: 4.3.0.dfsg.1-8 Severity: normal Tags: patch XQueryColors() doesn't return if ncolors is 65536, at least on the 16-bit TrueColor screen. Test program and patch are attatched.
% xdpyinfo name of display: :0.0 version number: 11.0 vendor string: The XFree86 Project, Inc vendor release number: 40300001 XFree86 version: 4.3.0.1 maximum request size: 4194300 bytes motion buffer size: 256 bitmap unit, bit order, padding: 32, LSBFirst, 32 image byte order: LSBFirst number of supported pixmap formats: 7 supported pixmap formats: depth 1, bits_per_pixel 1, scanline_pad 32 depth 4, bits_per_pixel 8, scanline_pad 32 depth 8, bits_per_pixel 8, scanline_pad 32 depth 15, bits_per_pixel 16, scanline_pad 32 depth 16, bits_per_pixel 16, scanline_pad 32 depth 24, bits_per_pixel 32, scanline_pad 32 depth 32, bits_per_pixel 32, scanline_pad 32 keycode range: minimum 8, maximum 255 focus: window 0xe00003, revert to Parent number of extensions: 28 BIG-REQUESTS DOUBLE-BUFFER DPMS Extended-Visual-Information FontCache GLX LBX MIT-SCREEN-SAVER MIT-SHM MIT-SUNDRY-NONSTANDARD RANDR RENDER SECURITY SGI-GLX SHAPE SYNC TOG-CUP X-Resource XC-APPGROUP XC-MISC XFree86-Bigfont XFree86-DGA XFree86-Misc XFree86-VidModeExtension XInputExtension XKEYBOARD XTEST XVideo default screen number: 0 number of screens: 1 screen #0: dimensions: 1600x1200 pixels (330x242 millimeters) resolution: 123x126 dots per inch depths (7): 16, 1, 4, 8, 15, 24, 32 root window id: 0x41 depth of root window: 16 planes number of colormaps: minimum 1, maximum 1 default colormap: 0x20 default number of colormap cells: 64 preallocated pixels: black 0, white 65535 options: backing-store NO, save-unders NO largest cursor: 64x64 current input event mask: 0xda003f KeyPressMask KeyReleaseMask ButtonPressMask ButtonReleaseMask EnterWindowMask LeaveWindowMask StructureNotifyMask SubstructureNotifyMask SubstructureRedirectMask PropertyChangeMask ColormapChangeMask number of visuals: 8 default visual id: 0x23 visual: visual id: 0x23 class: TrueColor depth: 16 planes available colormap entries: 64 per subfield red, green, blue masks: 0xf800, 0x7e0, 0x1f significant bits in color specification: 6 bits visual: visual id: 0x24 class: TrueColor depth: 16 planes available colormap entries: 64 per subfield red, green, blue masks: 0xf800, 0x7e0, 0x1f significant bits in color specification: 6 bits visual: visual id: 0x25 class: TrueColor depth: 16 planes available colormap entries: 64 per subfield red, green, blue masks: 0xf800, 0x7e0, 0x1f significant bits in color specification: 6 bits visual: visual id: 0x26 class: TrueColor depth: 16 planes available colormap entries: 64 per subfield red, green, blue masks: 0xf800, 0x7e0, 0x1f significant bits in color specification: 6 bits visual: visual id: 0x27 class: DirectColor depth: 16 planes available colormap entries: 64 per subfield red, green, blue masks: 0xf800, 0x7e0, 0x1f significant bits in color specification: 6 bits visual: visual id: 0x28 class: DirectColor depth: 16 planes available colormap entries: 64 per subfield red, green, blue masks: 0xf800, 0x7e0, 0x1f significant bits in color specification: 6 bits visual: visual id: 0x29 class: DirectColor depth: 16 planes available colormap entries: 64 per subfield red, green, blue masks: 0xf800, 0x7e0, 0x1f significant bits in color specification: 6 bits visual: visual id: 0x2a class: DirectColor depth: 16 planes available colormap entries: 64 per subfield red, green, blue masks: 0xf800, 0x7e0, 0x1f significant bits in color specification: 6 bits % cat querycolors.c #include <stdio.h> #include <X11/Xlib.h> int main(void) { Display *display; Colormap cmap; XColor color[65536]; unsigned long i; display = XOpenDisplay(NULL); if (display == NULL) { return 1; } cmap = DefaultColormap(display, DefaultScreen(display)); for (i = 0; i < 65536; ++i) { color[i].pixel = i; } XQueryColors(display, cmap, color, 65536); for (i = 0; i < 65536; ++i) { printf("pixel: 0x%04lX red: 0x%04X green: 0x%04X blue: 0x%04X\n", i, color[i].red, color[i].green, color[i].blue); } XCloseDisplay(display); return 0; } % gcc -L/usr/X11R6/lib querycolors.c -lX11 % ./a.out -- System Information: Debian Release: 3.1 APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Kernel: Linux 2.6.9 Locale: LANG=ja_JP.eucJP, LC_CTYPE=ja_JP.eucJP (charmap=EUC-JP) Versions of packages libx11-6 depends on: ii debconf [debconf-2.0] 1.4.39 Debian configuration management sy ii libc6 2.3.2.ds1-18 GNU C Library: Shared libraries an ii xfree86-common 4.3.0.dfsg.1-8 X Window System (XFree86) infrastr ii xlibs-data 4.3.0.dfsg.1-8 X Window System client data -- debconf information: libx11-6/migrate_xkb_dir: true
#include <stdio.h> #include <X11/Xlib.h> int main(void) { Display *display; Colormap cmap; XColor color[65536]; unsigned long i; display = XOpenDisplay(NULL); if (display == NULL) { return 1; } cmap = DefaultColormap(display, DefaultScreen(display)); for (i = 0; i < 65536; ++i) { color[i].pixel = i; } XQueryColors(display, cmap, color, 65536); for (i = 0; i < 65536; ++i) { printf("pixel: 0x%04lX red: 0x%04X green: 0x%04X blue: 0x%04X\n", i, color[i].red, color[i].green, color[i].blue); } XCloseDisplay(display); return 0; }
--- xc/lib/X11/QuColors.c.orig 2004-10-30 13:34:19.000000000 +0900 +++ xc/lib/X11/QuColors.c 2004-10-31 03:16:32.000000000 +0900 @@ -36,40 +36,62 @@ XColor *defs; /* RETURN */ int ncolors; { - register int i; - xrgb *color; - xQueryColorsReply rep; - long nbytes; - register xQueryColorsReq *req; + long max; + XColor *next; + unsigned int rest; LockDisplay(dpy); - GetReq(QueryColors, req); - req->cmap = cmap; - req->length += ncolors; /* each pixel is a CARD32 */ - - for (i = 0; i < ncolors; i++) - Data32 (dpy, (long *)&defs[i].pixel, 4L); - /* XXX this isn't very efficient */ - - if (_XReply(dpy, (xReply *) &rep, 0, xFalse) != 0) { - if ((color = (xrgb *) - Xmalloc((unsigned) (nbytes = (long) ncolors * SIZEOF(xrgb))))) { - - _XRead(dpy, (char *) color, nbytes); - - for (i = 0; i < ncolors; i++) { - register XColor *def = &defs[i]; - register xrgb *rgb = &color[i]; - def->red = rgb->red; - def->green = rgb->green; - def->blue = rgb->blue; - def->flags = DoRed | DoGreen | DoBlue; + max = dpy->max_request_size - (sizeof (xQueryColorsReq) >> 2); + if (max > 65535) + max = 65535; + + next = defs; + rest = ncolors; + while (rest) { + register unsigned int i; + xrgb *color; + xQueryColorsReply rep; + long nbytes; + register xQueryColorsReq *req; + unsigned int npixels; + + GetReq(QueryColors, req); + + req->cmap = cmap; + if (rest > max) + npixels = max; + else + npixels = rest; + req->length += npixels; + rest -= npixels; + + for (i = 0; i < npixels; i++) + Data32 (dpy, (long *)&next[i].pixel, 4L); + /* XXX this isn't very efficient */ + + if (_XReply(dpy, (xReply *) &rep, 0, xFalse) != 0) { + if ((color = (xrgb *) + Xmalloc((unsigned) (nbytes = (long) npixels * SIZEOF(xrgb))))) { + + _XRead(dpy, (char *) color, nbytes); + + for (i = 0; i < npixels; i++) { + register XColor *def = &next[i]; + register xrgb *rgb = &color[i]; + def->red = rgb->red; + def->green = rgb->green; + def->blue = rgb->blue; + def->flags = DoRed | DoGreen | DoBlue; + } + Xfree((char *)color); } - Xfree((char *)color); + else _XEatData(dpy, (unsigned long) nbytes); + + next += npixels; } - else _XEatData(dpy, (unsigned long) nbytes); } + UnlockDisplay(dpy); SyncHandle(); return 1;