1 | /* |
2 | SPDX-FileCopyrightText: 2024 Andreas Hartmetz <ahartmetz@gmail.com> |
3 | |
4 | SPDX-License-Identifier: LGPL-2.0-or-later |
5 | */ |
6 | |
7 | #pragma once |
8 | |
9 | #include <string.h> |
10 | |
11 | /** |
12 | * KXcbEvent allocates an xcb event in a 32 bytes large, zero-initialized buffer to avoid |
13 | * out-of-bounds reads and uninitialized memory reads in xcb_send_event(). According to |
14 | * XCB documentation, the wire size of all XCB events is 32 bytes, and that many bytes will |
15 | * be read by xcb_send_event(). |
16 | */ |
17 | template<class EventType, bool needsPadding = (sizeof(EventType) < 32)> |
18 | struct KXcbEvent; |
19 | |
20 | template<class EventType> |
21 | class KXcbEvent<EventType, false> : public EventType |
22 | { |
23 | public: |
24 | inline KXcbEvent() |
25 | { |
26 | static_assert(sizeof(*this) == s_evtSize); |
27 | memset(this, 0, s_evtSize); |
28 | } |
29 | |
30 | inline const char *buffer() const |
31 | { |
32 | return reinterpret_cast<const char *>(this); |
33 | } |
34 | |
35 | private: |
36 | static constexpr size_t s_evtSize = 32; |
37 | }; |
38 | |
39 | template<class EventType> |
40 | class KXcbEvent<EventType, true> : public EventType |
41 | { |
42 | public: |
43 | inline KXcbEvent() |
44 | { |
45 | static_assert(sizeof(*this) == s_evtSize); |
46 | memset(this, 0, s_evtSize); |
47 | } |
48 | |
49 | inline const char *buffer() const |
50 | { |
51 | return reinterpret_cast<const char *>(this); |
52 | } |
53 | |
54 | private: |
55 | static constexpr size_t s_evtSize = 32; |
56 | char m_filler[s_evtSize - sizeof(EventType)]; |
57 | }; |
58 | |