libi3/root_atom_contents: handle data of arbitrary length
Patch status: needinfo
Patch by Lancelot SIX
Long description:
Handle data fetched from xcb_get_property_unchecked with arbitrary length. This avoids having to rely on PATH_MAX macro where it is not necessary.
To apply this patch, use:
curl http://cr.i3wm.org/patch/333/raw.patch | git am
b/libi3/root_atom_contents.c
| 17 |
@@ -31,6 +31,11 @@ char *root_atom_contents(const char *atomname, xcb_connection_t *provided_conn, |
| 18 |
xcb_intern_atom_cookie_t atom_cookie; |
| 19 |
xcb_intern_atom_reply_t *atom_reply; |
| 20 |
char *content; |
| 21 |
+ /* xcb_get_property_unsafe needs the size of the required property |
| 22 |
+ * expressed in words (4 bytes). Therefore, content_max_size should always |
| 23 |
+ * be a multiple of 4. */ |
| 24 |
+ size_t content_max_size = 1024; |
| 25 |
+ size_t content_size; |
| 26 |
xcb_connection_t *conn = provided_conn; |
| 27 |
|
| 28 |
if (provided_conn == NULL && |
| 29 |
@@ -50,13 +55,32 @@ char *root_atom_contents(const char *atomname, xcb_connection_t *provided_conn, |
| 30 |
xcb_get_property_cookie_t prop_cookie; |
| 31 |
xcb_get_property_reply_t *prop_reply; |
| 32 |
prop_cookie = xcb_get_property_unchecked(conn, false, root, atom_reply->atom, |
| 33 |
- XCB_GET_PROPERTY_TYPE_ANY, 0, PATH_MAX); |
| 34 |
+ XCB_GET_PROPERTY_TYPE_ANY, 0, (content_max_size / 4)); |
| 35 |
prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL); |
| 36 |
if (prop_reply == NULL) {
|
| 37 |
free(atom_reply); |
| 38 |
return NULL; |
| 39 |
} |
| 40 |
- if (xcb_get_property_value_length(prop_reply) == 0) {
|
| 41 |
+ content_size = xcb_get_property_value_length(prop_reply); |
| 42 |
+ if (content_size > 0 && prop_reply->bytes_after > 0) {
|
| 43 |
+ /* We received an incomplete value. Ask again but with a properly |
| 44 |
+ * adjusted size. */ |
| 45 |
+ content_max_size += prop_reply->bytes_after; |
| 46 |
+ if ((content_max_size % 4) != 0) |
| 47 |
+ content_max_size += 4 - (content_max_size % 4); |
| 48 |
+ |
| 49 |
+ /* Repeat the request, with adjusted size */ |
| 50 |
+ free(prop_reply); |
| 51 |
+ prop_cookie = xcb_get_property_unchecked(conn, false, root, atom_reply->atom, |
| 52 |
+ XCB_GET_PROPERTY_TYPE_ANY, 0, (content_max_size / 4)); |
| 53 |
+ prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL); |
| 54 |
+ if (prop_reply == NULL) {
|
| 55 |
+ free(atom_reply); |
| 56 |
+ return NULL; |
| 57 |
+ } |
| 58 |
+ content_size = xcb_get_property_value_length(prop_reply); |
| 59 |
+ } |
| 60 |
+ if (content_size == 0) {
|
| 61 |
free(atom_reply); |
| 62 |
free(prop_reply); |
| 63 |
return NULL; |