x11xlibicccm

Is reading a X11 Property of type UTF8_STRING guaranteed to end with NULL?


I have the following code:

static Atom _NET_WM_NAME = XInternAtom( display, "_NET_WM_NAME", false );

unsigned char* wm_data = NULL;
Atom wm_type;
int wm_format;
unsigned long wm_nitems, wm_bytes;

std::string title;

int ret = XGetWindowProperty( display, window, _NET_WM_NAME, 0, 512,
    false, utf8_string, &wm_type, &wm_format, &wm_nitems, &wm_bytes, &wm_data);

if( ret == Success && wm_nitems != 0 && wm_data != NULL ) {
    title = (const char*)wm_data;  // [1]
}

The _NET_WM_NAME property is a UTF8_STRING, as per the spec

So, in my code above, [1] assumes that the received data will always be NULL terminated. The code as it is works, but the returned byte amount (wm_nitems) does not include the NULL terminator, it is always the same as the actual string length. This is what makes me uncertain.

So my questions are:

  1. Is guaranteed that a read of a UTF8_STRING property will always return the string INCLUDING the NULL terminator?
  2. If so, why is the NULL terminator not included as part of the wm_nitems count?
  3. Can somebody point where this is specified in the spec?
  4. And in particular, is the above snippet correct for reading the _NET_WM_NAME property?

Solution

  • XGetWindowProperty

    "XGetWindowProperty() always allocates one extra byte in prop_return (even if the property is zero length) and sets it to zero so that simple properties consisting of characters do not have to be copied into yet another string before use."


    wm_nitems

    nitems_return: Returns the actual number of 8-bit, 16-bit, or 32-bit items stored in the prop_return data

    Why should the null terminator count as data. It is the courtesy of XGetWindowProperty to automagically return a null terminated string (see above), but the nul character is not part of the actual data (e.g., it is absolutely possible to set the window name without an ending nul char).

    To put it differently: strlen doesn't count the terminating null character either, right?


    Another thing, C strings are null terminated character arrays. The symbol NULL is the null pointer and has a special meaning in the C environment (see: https://en.cppreference.com/w/c/types/NULL).