Bug#278984: libx11-6: XQueryColors() doesn't return if ncolors is 65536.
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;
Reply to: