From eca5e4598a8d6623acb30e28bb023186d8f69bcc Mon Sep 17 00:00:00 2001 From: Lancelot SIX Date: Sat, 23 Nov 2013 12:03:55 +0100 Subject: [PATCH] libi3/root_atom_contents: handle data of arbitrary length 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. --- common.mk | 2 +- libi3/root_atom_contents.c | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/common.mk b/common.mk index 0214abfa..e3c92fa1 100644 --- a/common.mk +++ b/common.mk @@ -144,7 +144,7 @@ PANGO_LIBS := $(call ldflags_for_lib, cairo) PANGO_LIBS += $(call ldflags_for_lib, pangocairo) # libi3 -LIBS = -L$(TOPDIR) -li3 +LIBS = -L$(TOPDIR) -li3 -lm ## Platform-specific flags diff --git a/libi3/root_atom_contents.c b/libi3/root_atom_contents.c index 236f1b99..00b74005 100644 --- a/libi3/root_atom_contents.c +++ b/libi3/root_atom_contents.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,7 @@ char *root_atom_contents(const char *atomname, xcb_connection_t *provided_conn, xcb_intern_atom_cookie_t atom_cookie; xcb_intern_atom_reply_t *atom_reply; char *content; + size_t content_max_words = 256; xcb_connection_t *conn = provided_conn; if (provided_conn == NULL && @@ -50,12 +52,26 @@ char *root_atom_contents(const char *atomname, xcb_connection_t *provided_conn, xcb_get_property_cookie_t prop_cookie; xcb_get_property_reply_t *prop_reply; prop_cookie = xcb_get_property_unchecked(conn, false, root, atom_reply->atom, - XCB_GET_PROPERTY_TYPE_ANY, 0, PATH_MAX); + XCB_GET_PROPERTY_TYPE_ANY, 0, content_max_words); prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL); if (prop_reply == NULL) { free(atom_reply); return NULL; } + if (xcb_get_property_value_length(prop_reply) > 0 && prop_reply->bytes_after > 0) { + /* We received an incomplete value. Ask again but with a properly + * adjusted size. */ + content_max_words += ceil(prop_reply->bytes_after / 4.0); + /* Repeat the request, with adjusted size */ + free(prop_reply); + prop_cookie = xcb_get_property_unchecked(conn, false, root, atom_reply->atom, + XCB_GET_PROPERTY_TYPE_ANY, 0, content_max_words); + prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL); + if (prop_reply == NULL) { + free(atom_reply); + return NULL; + } + } if (xcb_get_property_value_length(prop_reply) == 0) { free(atom_reply); free(prop_reply);