Search code examples
cx11xlib

Correct size of Window type for XGetWindowProperty


I am reading the _NET_ACTIVE_WINDOW atom from the root window, using this code:

Atom actualType;
int actualFormat;
unsigned long nItems, bytesAfter;
unsigned char * value;

if (XGetWindowProperty(display, window, atom, 0, LONG_MAX / 4,
                       False, XA_WINDOW,
                       &actualType, &actualFormat,
                       &nItems, &bytesAfter, &value) != Success ||
    actualType != XA_WINDOW) {
    return NULL;
}

Window result = *(Window*)value;    /*  <=== this line seems dubious */
XFree(value);
return result;

However, although it works, I am pretty sure it is bugged, because adding a few printfs shows that:

  • sizeof(Window) is 8
  • actualFormat is 32
  • nItems is 1

Therefore, according to the documentation, the buffer allocated for the property is 4 bytes long. Reading a Window from it is a blatant overflow.

So what's the deal with that? Is there some flags I miss to make Window only 4 bytes? Should I read the value as an uint32_t and cast it to Window after? Anything else?


Solution

  • The documentation (XGetWindowProperty(3)) states that:

    If the specified format is 32, the property data must be a long array.

    The include file shows Window as a typedef to XID which is a typedef to unsigned long.

    I would guess that the use of 32 is an anachronism and used to mean 32-bits, but now means whatever your compiler chooses to use for unsigned long.