Mercurial > minori
changeset 336:d260549151d6
dep/animone: fix undefined behavior, get correct length value
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Wed, 19 Jun 2024 06:32:25 -0400 |
parents | 5098387a3a46 |
children | a7d4e5107531 |
files | dep/animone/src/win/x11.cc |
diffstat | 1 files changed, 20 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/dep/animone/src/win/x11.cc Wed Jun 19 06:11:38 2024 -0400 +++ b/dep/animone/src/win/x11.cc Wed Jun 19 06:32:25 2024 -0400 @@ -15,6 +15,7 @@ #include <climits> #include <cstdint> #include <cstring> +#include <cstdlib> #include <set> #include <string> #include <memory> @@ -32,12 +33,21 @@ namespace animone::internal::x11 { +template<typename T> +struct XcbDestructor { + using pointer = T*; + void operator()(pointer t) const { std::free(t); }; +}; + +template<typename T> +using XcbPtr = std::unique_ptr<T, XcbDestructor<T>>; + static bool GetAllTopLevelWindowsEWMH(xcb_connection_t* connection, const std::vector<xcb_window_t>& roots, std::set<xcb_window_t>& result) { const xcb_atom_t Atom__NET_CLIENT_LIST = [connection] { static constexpr std::string_view name = "_NET_CLIENT_LIST"; xcb_intern_atom_cookie_t cookie = ::xcb_intern_atom(connection, true, name.size(), name.data()); - std::unique_ptr<xcb_intern_atom_reply_t> reply(::xcb_intern_atom_reply(connection, cookie, NULL)); + XcbPtr<xcb_intern_atom_reply_t> reply(::xcb_intern_atom_reply(connection, cookie, NULL)); xcb_atom_t atom = reply->atom; @@ -55,11 +65,11 @@ cookies.push_back(::xcb_get_property(connection, 0, root, Atom__NET_CLIENT_LIST, XCB_ATOM_ANY, 0L, UINT_MAX)); for (const auto& cookie : cookies) { - std::unique_ptr<xcb_get_property_reply_t> reply(::xcb_get_property_reply(connection, cookie, NULL)); + XcbPtr<xcb_get_property_reply_t> reply(::xcb_get_property_reply(connection, cookie, NULL)); if (reply) { xcb_window_t* value = reinterpret_cast<xcb_window_t*>(::xcb_get_property_value(reply.get())); - int len = ::xcb_get_property_value_length(reply.get()); + int len = ::xcb_get_property_value_length(reply.get()) / sizeof(xcb_window_t); for (size_t i = 0; i < len; i++) result.insert(value[i]); @@ -90,7 +100,7 @@ cookies.push_back(::xcb_query_tree(connection, windows[i])); for (const auto& cookie : cookies) { - std::unique_ptr<xcb_query_tree_reply_t> query_tree_reply(::xcb_query_tree_reply(connection, cookie, NULL)); + XcbPtr<xcb_query_tree_reply_t> query_tree_reply(::xcb_query_tree_reply(connection, cookie, NULL)); xcb_window_t* tree_children = ::xcb_query_tree_children(query_tree_reply.get()); int tree_children_len = ::xcb_query_tree_children_length(query_tree_reply.get()); @@ -103,8 +113,7 @@ ::xcb_get_property(connection, 0, tree_children[i], Atom_WM_STATE, Atom_WM_STATE, 0, 0)); for (int i = 0; i < tree_children_len; i++) { - std::unique_ptr<xcb_get_property_reply_t> get_property_reply( - ::xcb_get_property_reply(connection, state_property_cookies[i], NULL)); + XcbPtr<xcb_get_property_reply_t> get_property_reply(::xcb_get_property_reply(connection, state_property_cookies[i], NULL)); /* X11 is unfriendly here. what this means is "did the property exist?" */ if (get_property_reply->format || get_property_reply->type || get_property_reply->length) { @@ -135,10 +144,10 @@ xcb_atom_t Atom_WM_STATE = [connection] { static constexpr std::string_view name = "WM_STATE"; xcb_intern_atom_cookie_t cookie = ::xcb_intern_atom(connection, true, name.size(), name.data()); - xcb_intern_atom_reply_t* reply = ::xcb_intern_atom_reply(connection, cookie, NULL); + XcbPtr<xcb_intern_atom_reply_t> reply(::xcb_intern_atom_reply(connection, cookie, NULL)); xcb_atom_t atom = reply->atom; - free(reply); + return atom; }(); if (Atom_WM_STATE == XCB_ATOM_NONE) @@ -203,8 +212,7 @@ win.id = window_cookie.window; { /* Class name */ - std::unique_ptr<xcb_get_property_reply_t> reply( - ::xcb_get_property_reply(connection, window_cookie.class_property_cookie, NULL)); + XcbPtr<xcb_get_property_reply_t> reply(::xcb_get_property_reply(connection, window_cookie.class_property_cookie, NULL)); if (reply && reply->format == 8) { const char* data = reinterpret_cast<const char*>(::xcb_get_property_value(reply.get())); @@ -218,8 +226,7 @@ } { /* Title text */ - std::unique_ptr<xcb_get_property_reply_t> reply( - ::xcb_get_property_reply(connection, window_cookie.name_property_cookie, NULL)); + XcbPtr<xcb_get_property_reply_t> reply(::xcb_get_property_reply(connection, window_cookie.name_property_cookie, NULL)); if (reply) { const char* data = reinterpret_cast<const char*>(::xcb_get_property_value(reply.get())); @@ -231,8 +238,7 @@ Process proc = {0}; { /* PID */ - std::unique_ptr<xcb_res_query_client_ids_reply_t> reply( - ::xcb_res_query_client_ids_reply(connection, window_cookie.pid_property_cookie, NULL)); + XcbPtr<xcb_res_query_client_ids_reply_t> reply(::xcb_res_query_client_ids_reply(connection, window_cookie.pid_property_cookie, NULL)); if (reply) { xcb_res_client_id_value_iterator_t it = ::xcb_res_query_client_ids_ids_iterator(reply.get());