From 8f6ca4c787210df90e5e371a3cafe54400785252 Mon Sep 17 00:00:00 2001 From: "raveit65 (via Travis CI)" <15132211195@163.com> Date: Fri, 21 Jul 2023 03:09:56 +0000 Subject: Deploy mate-desktop/mate-netbook to github.com/mate-desktop/mate-netbook.git:gh-pages --- .../index.html | 140 +++ .../report-076df9.html | 1008 ++++++++++++++++++++ .../report-153039.html | 1008 ++++++++++++++++++++ .../report-26ef1a.html | 1008 ++++++++++++++++++++ .../report-295e70.html | 900 +++++++++++++++++ .../report-3500a3.html | 1008 ++++++++++++++++++++ .../report-39c9c4.html | 900 +++++++++++++++++ .../report-3fa9c9.html | 1008 ++++++++++++++++++++ .../report-532882.html | 1008 ++++++++++++++++++++ .../report-5fee6c.html | 1008 ++++++++++++++++++++ .../report-71d389.html | 1008 ++++++++++++++++++++ .../report-75a183.html | 846 ++++++++++++++++ .../report-94cbc5.html | 1008 ++++++++++++++++++++ .../report-cba9e3.html | 1008 ++++++++++++++++++++ .../report-ecd83c.html | 1008 ++++++++++++++++++++ .../report-efae04.html | 1008 ++++++++++++++++++++ .../scanview.css | 62 ++ .../sorttable.js | 492 ++++++++++ 18 files changed, 15436 insertions(+) create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/index.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-076df9.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-153039.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-26ef1a.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-295e70.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-3500a3.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-39c9c4.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-3fa9c9.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-532882.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-5fee6c.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-71d389.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-75a183.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-94cbc5.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-cba9e3.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-ecd83c.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-efae04.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/scanview.css create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/sorttable.js (limited to '2022-02-13-183617-5516-1@becf3036fb90_master') diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/index.html b/2022-02-13-183617-5516-1@becf3036fb90_master/index.html new file mode 100644 index 0000000..733114f --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/index.html @@ -0,0 +1,140 @@ + + +rootdir - scan-build results + + + + + + +

rootdir - scan-build results

+ + + + + + + +
User:root@1c4ea89342a8
Working Directory:/rootdir
Command Line:make -j 2
Clang Version:clang version 13.0.0 (Fedora 13.0.0-3.fc35) +
Date:Sun Feb 13 18:36:17 2022
+

Bug Summary

+ + + + + + + + +
Bug TypeQuantityDisplay?
All Bugs15
Logic error
Cast from non-struct type to struct type2
Security
Potential insecure memory buffer bounds restriction in call 'strcpy'12
Unused code
Dead nested assignment1
+

Reports

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bug GroupBug Type ▾FileFunction/MethodLinePath Length
Logic errorCast from non-struct type to struct typemaximus-app.cwnck_window_is_decorated1201View Report
Logic errorCast from non-struct type to struct typemaximus-app.cgdk_window_set_mwm_hints1621View Report
Unused codeDead nested assignmentmaximus-bind.cmaximus_bind_init4641View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4281View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4431View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4571View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4131View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4531View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4081View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4181View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4231View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4331View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4481View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4031View Report
SecurityPotential insecure memory buffer bounds restriction in call 'strcpy'eggaccelerators.cegg_virtual_accelerator_name4381View Report
+ + diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-076df9.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-076df9.html new file mode 100644 index 0000000..77bce5a --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-076df9.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 428, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-153039.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-153039.html new file mode 100644 index 0000000..bf6b563 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-153039.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 443, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-26ef1a.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-26ef1a.html new file mode 100644 index 0000000..2f4637c --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-26ef1a.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 457, column 3
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-295e70.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-295e70.html new file mode 100644 index 0000000..244f063 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-295e70.html @@ -0,0 +1,900 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 120, column 11
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c maximus-app.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-3500a3.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-3500a3.html new file mode 100644 index 0000000..e9853bf --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-3500a3.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 413, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-39c9c4.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-39c9c4.html new file mode 100644 index 0000000..915385e --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-39c9c4.html @@ -0,0 +1,900 @@ + + + +maximus-app.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-app.c
Warning:line 162, column 13
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-app.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c maximus-app.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24
25#include <gtk/gtk.h>
26#include <gdk/gdkx.h>
27#include <gio/gio.h>
28
29#include "maximus-app.h"
30#include "maximus-bind.h"
31#include "xutils.h"
32
33/* GSettings schemas and keys */
34#define APP_SCHEMA"org.mate.maximus" "org.mate.maximus"
35#define APP_EXCLUDE_CLASS"exclude-class" "exclude-class"
36#define APP_UNDECORATE"undecorate" "undecorate"
37#define APP_NO_MAXIMIZE"no-maximize" "no-maximize"
38
39/* A set of default exceptions */
40static gchar *default_exclude_classes[] =
41{
42 "Apport-gtk",
43 "Bluetooth-properties",
44 "Bluetooth-wizard",
45 "Download", /* Firefox Download Window */
46 "Ekiga",
47 "Extension", /* Firefox Add-Ons/Extension Window */
48 "Gcalctool",
49 "Gimp",
50 "Global", /* Firefox Error Console Window */
51 "Mate-dictionary",
52 "Mate-language-selector",
53 "Mate-nettool",
54 "Mate-volume-control",
55 "Kiten",
56 "Kmplot",
57 "Nm-editor",
58 "Pidgin",
59 "Polkit-mate-authorization",
60 "Update-manager",
61 "Skype",
62 "Toplevel", /* Firefox "Clear Private Data" Window */
63 "Transmission"
64};
65
66struct _MaximusAppPrivate
67{
68 MaximusBind *bind;
69 WnckScreen *screen;
70 GSettings *settings;
71
72 gchar **exclude_class_list;
73 gboolean undecorate;
74 gboolean no_maximize;
75};
76
77static GQuark was_decorated = 0;
78
79/* <TAKEN FROM GDK> */
80typedef struct {
81 unsigned long flags;
82 unsigned long functions;
83 unsigned long decorations;
84 long input_mode;
85 unsigned long status;
86} MotifWmHints, MwmHints;
87
88#define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0)
89#define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1)
90#define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS"
91
92G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init
(MaximusAppClass *klass); static GType maximus_app_get_type_once
(void); static gpointer maximus_app_parent_class = ((void*)0
); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init
(gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent
(klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MaximusApp_private_offset); maximus_app_class_init
((MaximusAppClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer maximus_app_get_instance_private (MaximusApp
*self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset
)))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_app_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_app_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusApp"
), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void))
maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc
)(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate
)); };} } return g_define_type_id; }
;
93
94static gboolean
95wnck_window_is_decorated (WnckWindow *window)
96{
97 GdkDisplay *display = gdk_display_get_default();
98 Atom hints_atom = None0L;
99 guchar *data = NULL((void*)0);
100 MotifWmHints *hints = NULL((void*)0);
101 Atom type = None0L;
102 gint format;
103 gulong nitems;
104 gulong bytes_after;
105 gboolean retval;
106
107 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
108
109 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
110 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
111
112 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
113 wnck_window_get_xid (window),
114 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
115 False0, AnyPropertyType0L, &type, &format, &nitems,
116 &bytes_after, &data);
117
118 if (type == None0L || !data) return TRUE(!(0));
119
120 hints = (MotifWmHints *)data;
121
122 retval = hints->decorations;
123
124 if (data)
125 XFree (data);
126
127 return retval;
128}
129
130static void
131gdk_window_set_mwm_hints (WnckWindow *window,
132 MotifWmHints *new_hints)
133{
134 GdkDisplay *display = gdk_display_get_default();
135 Atom hints_atom = None0L;
136 guchar *data = NULL((void*)0);
137 MotifWmHints *hints = NULL((void*)0);
138 Atom type = None0L;
139 gint format;
140 gulong nitems;
141 gulong bytes_after;
142
143 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
144 g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((gdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while
(0)
;
145
146 hints_atom = gdk_x11_get_xatom_by_name_for_display (display,
147 _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
148
149 gdk_x11_display_error_trap_push (display);
150 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
151 wnck_window_get_xid (window),
152 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
153 False0, AnyPropertyType0L, &type, &format, &nitems,
154 &bytes_after, &data);
155 if (gdk_x11_display_error_trap_pop (display))
156 return;
157
158 if (type != hints_atom || !data)
159 hints = new_hints;
160 else
161 {
162 hints = (MotifWmHints *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
163
164 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
165 {
166 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
167 hints->functions = new_hints->functions;
168 }
169 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
170 {
171 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
172 hints->decorations = new_hints->decorations;
173 }
174 }
175
176 _wnck_error_trap_push ();
177 XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)),
178 wnck_window_get_xid (window),
179 hints_atom, hints_atom, 32, PropModeReplace0,
180 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
181 gdk_display_flush (display);
182 _wnck_error_trap_pop ();
183
184 if (data)
185 XFree (data);
186}
187
188static void
189_window_set_decorations (WnckWindow *window,
190 GdkWMDecoration decorations)
191{
192 MotifWmHints *hints;
193
194 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
195
196 /* initialize to zero to avoid writing uninitialized data to socket */
197 hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
198 hints->flags = MWM_HINTS_DECORATIONS(1L << 1);
199 hints->decorations = decorations;
200
201 gdk_window_set_mwm_hints (window, hints);
202
203 g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else
(void) ((MotifWmHints*) 0 == (hints)); } while (0)
;
204}
205
206/* </TAKEN FROM GDK> */
207
208gboolean
209window_is_too_large_for_screen (WnckWindow *window)
210{
211 static GdkScreen *screen = NULL((void*)0);
212 gint x=0, y=0, w=0, h=0;
213
214 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
215
216 if (screen == NULL((void*)0))
217 screen = gdk_screen_get_default ();
218
219 wnck_window_get_geometry (window, &x, &y, &w, &h);
220
221 /* some wiggle room */
222 return (screen &&
223 (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) ||
224 h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20)));
225}
226
227static gboolean
228on_window_maximised_changed (WnckWindow *window)
229{
230 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
231
232 if (window_is_too_large_for_screen (window))
233 {
234 _window_set_decorations (window, 1);
235 wnck_window_unmaximize (window);
236 }
237 else
238 {
239 _window_set_decorations (window, 0);
240 }
241 return FALSE(0);
242}
243
244static gboolean
245enable_window_decorations (WnckWindow *window)
246{
247 g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while
(0)
;
248
249 _window_set_decorations (window, 1);
250 return FALSE(0);
251}
252
253static void
254on_window_state_changed (WnckWindow *window,
255 WnckWindowState change_mask,
256 WnckWindowState new_state,
257 MaximusApp *app)
258{
259 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
260
261 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
262 return;
263
264 if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY
265 || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)
266 {
267 if (wnck_window_is_maximized (window) && app->priv->undecorate)
268 {
269 g_idle_add ((GSourceFunc)on_window_maximised_changed, window);
270 }
271 else
272 {
273 g_idle_add ((GSourceFunc)enable_window_decorations, window);
274 }
275 }
276}
277
278static gboolean
279is_excluded (MaximusApp *app, WnckWindow *window)
280{
281 MaximusAppPrivate *priv;
282 WnckWindowType type;
283 WnckWindowActions actions;
284 gchar *res_name;
285 gchar *class_name;
286 gint i;
287
288 g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while
(0)
;
289 g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); }
} while (0)
;
290 priv = app->priv;
291
292 type = wnck_window_get_window_type (window);
293 if (type != WNCK_WINDOW_NORMAL)
294 return TRUE(!(0));
295
296 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast
((GTypeInstance*) ((window)), (((GType) ((20) << (2)))
))))), "exclude")))
==1)
297 return TRUE(!(0));
298
299 /* Ignore if the window is already fullscreen */
300 if (wnck_window_is_fullscreen (window))
301 {
302 g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window));
303 return TRUE(!(0));
304 }
305
306 /* Make sure the window supports maximising */
307 actions = wnck_window_get_actions (window);
308 if (actions & WNCK_WINDOW_ACTION_RESIZE
309 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY
310 && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY
311 && actions & WNCK_WINDOW_ACTION_MAXIMIZE)
312 ; /* Is good to maximise */
313 else
314 return TRUE(!(0));
315
316 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
317
318 g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name);
319
320 /* Check internal list of class_ids */
321 for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes
)[0]))
; i++)
322 {
323 if ((class_name && default_exclude_classes[i]
324 && strstr (class_name, default_exclude_classes[i]))
325 || (res_name && default_exclude_classes[i] && strstr (res_name,
326 default_exclude_classes[i])))
327 {
328 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
329 return TRUE(!(0));
330 }
331 }
332
333 /* Check user list */
334 for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++)
335 {
336 if ((class_name && strstr (class_name, priv->exclude_class_list[i]))
337 || (res_name && strstr (res_name, priv->exclude_class_list[i]) ))
338 {
339 g_debug ("Excluding: %s\n", wnck_window_get_name (window));
340 return TRUE(!(0));
341 }
342 }
343
344 g_free (res_name);
345 g_free (class_name);
346 return FALSE(0);
347}
348
349extern gboolean no_maximize;
350
351static void
352on_window_opened (WnckScreen *screen,
353 WnckWindow *window,
354 MaximusApp *app)
355{
356 MaximusAppPrivate *priv;
357 WnckWindowType type;
358 gint exclude = 0;
359 GdkDisplay *gdk_display = gdk_display_get_default ();
360
361 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
362 g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((wnck_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while (
0)
;
363 priv = app->priv;
364
365 type = wnck_window_get_window_type (window);
366 if (type != WNCK_WINDOW_NORMAL)
367 return;
368
369 /* Ignore undecorated windows */
370 gdk_x11_display_error_trap_push (gdk_display);
371 exclude = wnck_window_is_decorated (window) ? 0 : 1;
372 if (gdk_x11_display_error_trap_pop (gdk_display))
373 return;
374
375 if (wnck_window_is_maximized (window))
376 exclude = 0;
377 g_object_set_data (G_OBJECT (window)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
window)), (((GType) ((20) << (2))))))))
, "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude)));
378
379 if (is_excluded (app, window))
380 {
381 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
382 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
383 return;
384 }
385
386 if (no_maximize || priv->no_maximize)
387 {
388 if (wnck_window_is_maximized(window) && priv->undecorate)
389 {
390 _window_set_decorations (window, 0);
391 gdk_display_flush (gdk_display);
392 }
393 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
394 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
395 return;
396 }
397
398 if (priv->undecorate)
399 {
400 /* Only undecorate right now if the window is smaller than the screen */
401 if (!window_is_too_large_for_screen (window))
402 {
403 _window_set_decorations (window, 0);
404 gdk_display_flush (gdk_display);
405 }
406 }
407
408 wnck_window_maximize (window);
409
410 g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
411 G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback
) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags
) 0)
;
412}
413
414/* GSettings Callbacks */
415static void
416on_app_no_maximize_changed (GSettings *settings,
417 gchar *key,
418 MaximusApp *app)
419{
420 MaximusAppPrivate *priv;
421
422 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
423 priv = app->priv;
424 priv->no_maximize = g_settings_get_boolean (settings, key);
425}
426
427static void
428on_exclude_class_changed (GSettings *settings,
429 gchar *key,
430 MaximusApp *app)
431{
432 MaximusAppPrivate *priv;
433
434 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
435 priv = app->priv;
436
437 if (priv->exclude_class_list)
438 g_strfreev (priv->exclude_class_list);
439
440 priv->exclude_class_list= g_settings_get_strv (settings,
441 APP_EXCLUDE_CLASS"exclude-class");
442}
443
444static gboolean
445show_desktop (WnckScreen *screen)
446{
447 g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while
(0)
;
448
449 wnck_screen_toggle_showing_desktop (screen, TRUE(!(0)));
450 return FALSE(0);
451}
452
453static void
454on_app_undecorate_changed (GSettings *settings,
455 gchar *key,
456 MaximusApp *app)
457{
458 MaximusAppPrivate *priv;
459 GList *windows, *w;
460
461 g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((app)); GType __t = ((maximus_app_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0)
;
462 priv = app->priv;
463 g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((priv->screen)); GType __t = ((wnck_screen_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0),
((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)"
); return; } } while (0)
;
464
465 priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate");
466 g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating");
467
468 windows = wnck_screen_get_windows (priv->screen);
469 for (w = windows; w; w = w->next)
470 {
471 WnckWindow *window = w->data;
472
473 if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
474 continue;
475
476 if (no_maximize || priv->no_maximize)
477 {
478 if (!wnck_window_is_maximized(window))
479 continue;
480 }
481
482 if (!is_excluded (app, window))
483 {
484 GdkDisplay *gdk_display = gdk_display_get_default ();
485
486 gdk_x11_display_error_trap_push (gdk_display);
487 _window_set_decorations (window, priv->undecorate ? 0 : 1);
488 wnck_window_unmaximize (window);
489 wnck_window_maximize (window);
490 gdk_display_flush (gdk_display);
491 gdk_x11_display_error_trap_pop_ignored (gdk_display);
492
493 sleep (1);
494 }
495 }
496 /* We want the user to be left on the launcher/desktop after switching modes*/
497 g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen);
498}
499
500/* GObject stuff */
501static void
502maximus_app_class_init (MaximusAppClass *klass)
503{
504}
505
506static void
507maximus_app_init (MaximusApp *app)
508{
509 MaximusAppPrivate *priv;
510 WnckScreen *screen;
511
512 priv = app->priv = maximus_app_get_instance_private (app);
513
514 priv->bind = maximus_bind_get_default ();
515
516 was_decorated = g_quark_from_static_string ("was-decorated");
517
518 priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus");
519
520 g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
521 G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class"
), (((GCallback) (on_exclude_class_changed))), (app), ((void*
)0), (GConnectFlags) 0)
;
522 g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
523 G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate"
), (((GCallback) (on_app_undecorate_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
524 g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
525 G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize"
), (((GCallback) (on_app_no_maximize_changed))), (app), ((void
*)0), (GConnectFlags) 0)
;
526
527 priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class");
528 priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate");
529 priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize");
530 g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false");
531
532 priv->screen = screen = wnck_screen_get_default ();
533 g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
534 G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback
) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0)
;
535}
536
537MaximusApp *
538maximus_app_get_default (void)
539
540{
541 static MaximusApp *app = NULL((void*)0);
542
543 if (!app)
544 app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()),
545 NULL((void*)0));
546
547 return app;
548}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-3fa9c9.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-3fa9c9.html new file mode 100644 index 0000000..56f8a34 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-3fa9c9.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 453, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-532882.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-532882.html new file mode 100644 index 0000000..67975b2 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-532882.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 408, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-5fee6c.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-5fee6c.html new file mode 100644 index 0000000..be4b690 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-5fee6c.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 418, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-71d389.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-71d389.html new file mode 100644 index 0000000..7dc0eb8 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-71d389.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 423, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-75a183.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-75a183.html new file mode 100644 index 0000000..b21c8b0 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-75a183.html @@ -0,0 +1,846 @@ + + + +maximus-bind.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:maximus-bind.c
Warning:line 464, column 18
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name maximus-bind.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c maximus-bind.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2008 Canonical Ltd
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
23
24#include <gtk/gtk.h>
25#include <gdk/gdkx.h>
26
27#include <gdk/gdkkeysyms.h>
28
29#include <gio/gio.h>
30
31#define WNCK_I_KNOW_THIS_IS_UNSTABLE
32#include <libwnck/libwnck.h>
33
34#include <X11/Xlib.h>
35#include <X11/Xresource.h>
36#include <X11/Xutil.h>
37#include <X11/extensions/XTest.h>
38#include <X11/keysymdef.h>
39#include <X11/keysym.h>
40
41#include <fakekey/fakekey.h>
42
43#include "maximus-bind.h"
44
45#include "tomboykeybinder.h"
46#include "eggaccelerators.h"
47
48#define KEY_RELEASE_TIMEOUT300 300
49#define STATE_CHANGED_SLEEP0.5 0.5
50
51/* GSettings schemas and keys */
52#define BIND_SCHEMA"org.mate.maximus" "org.mate.maximus"
53#define BIND_EXCLUDE_CLASS"binding" "binding"
54
55#define SYSRULESDIR"/usr/local/etc""/maximus" SYSCONFDIR"/usr/local/etc""/maximus"
56
57#ifdef __GNUC__4
58#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
59#else
60#define UNUSED_VARIABLE__attribute__ ((unused))
61#endif
62
63struct _MaximusBindPrivate
64{
65 FakeKey *fk;
66 WnckScreen *screen;
67 GSettings *settings;
68
69 gchar *binding;
70
71 GList *rules;
72};
73
74typedef struct
75{
76 gchar *wm_class;
77 gchar *fullscreen;
78 gchar *unfullscreen;
79} MaximusRule;
80
81G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT)static void maximus_bind_init (MaximusBind *self); static void
maximus_bind_class_init (MaximusBindClass *klass); static GType
maximus_bind_get_type_once (void); static gpointer maximus_bind_parent_class
= ((void*)0); static gint MaximusBind_private_offset; static
void maximus_bind_class_intern_init (gpointer klass) { maximus_bind_parent_class
= g_type_class_peek_parent (klass); if (MaximusBind_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &MaximusBind_private_offset
); maximus_bind_class_init ((MaximusBindClass*) klass); } __attribute__
((__unused__)) static inline gpointer maximus_bind_get_instance_private
(MaximusBind *self) { return (((gpointer) ((guint8*) (self) +
(glong) (MaximusBind_private_offset)))); } GType maximus_bind_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = maximus_bind_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType maximus_bind_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MaximusBind"
), sizeof (MaximusBindClass), (GClassInitFunc)(void (*)(void)
) maximus_bind_class_intern_init, sizeof (MaximusBind), (GInstanceInitFunc
)(void (*)(void)) maximus_bind_init, (GTypeFlags) 0); { {{ MaximusBind_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (MaximusBindPrivate
)); };} } return g_define_type_id; }
;
82
83static const gchar *
84get_fullscreen_keystroke (GList *rules, WnckWindow *window)
85{
86 WnckClassGroup *group;
87 const gchar *class_name;
88 GList *r;
89
90 group = wnck_window_get_class_group (window);
91 class_name = wnck_class_group_get_name (group);
92
93 g_debug ("Searching rules for %s:\n", wnck_window_get_name (window));
94
95 for (r = rules; r; r = r->next)
96 {
97 MaximusRule *rule = r->data;
98
99 g_debug ("\t%s ?= %s", class_name, rule->wm_class);
100
101 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
102 {
103 g_debug ("\tYES!\n");
104 return rule->fullscreen;
105 }
106 g_debug ("\tNO!\n");
107 }
108
109 return NULL((void*)0);
110}
111
112static const gchar *
113get_unfullscreen_keystroke (GList *rules, WnckWindow *window)
114{
115 WnckClassGroup *group;
116 const gchar *class_name;
117 GList *r;
118
119 group = wnck_window_get_class_group (window);
120 class_name = wnck_class_group_get_name (group);
121
122 for (r = rules; r; r = r->next)
123 {
124 MaximusRule *rule = r->data;
125
126 if (class_name && rule->wm_class && strstr (class_name, rule->wm_class))
127 {
128 return rule->unfullscreen;
129 }
130 }
131
132 return NULL((void*)0);
133}
134static gboolean
135real_fullscreen (MaximusBind *bind)
136{
137 MaximusBindPrivate *priv;
138 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
139 WnckWindow *active;
140 const gchar *keystroke;
141
142 priv = bind->priv;
143
144 display = gdk_display_get_default ();
145 active = wnck_screen_get_active_window (priv->screen);
146
147 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
148 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
149 return FALSE(0);
150
151 keystroke = get_fullscreen_keystroke (priv->rules, active);
152
153 if (keystroke)
154 {
155 guint keysym = 0;
156 EggVirtualModifierType modifiers = 0;
157
158 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
159 {
160 guint mods = 0;
161
162 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
163 mods |= FAKEKEYMOD_SHIFT;
164 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
165 mods |= FAKEKEYMOD_CONTROL;
166 if (modifiers & EGG_VIRTUAL_ALT_MASK)
167 mods |= FAKEKEYMOD_ALT;
168 if (modifiers & EGG_VIRTUAL_META_MASK)
169 mods |= FAKEKEYMOD_META;
170
171 g_debug ("Sending fullscreen special event: %s = %d %d",
172 keystroke, keysym, mods);
173 fakekey_press_keysym (priv->fk, keysym, mods);
174 fakekey_release (priv->fk);
175
176 return FALSE(0);
177 }
178 }
179
180 if (!wnck_window_is_fullscreen (active))
181 {
182 g_debug ("Sending fullscreen F11 event");
183 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
184 fakekey_release (priv->fk);
185 }
186
187 sleep (STATE_CHANGED_SLEEP0.5);
188
189 if (!wnck_window_is_fullscreen (active))
190 {
191 g_debug ("Forcing fullscreen wnck event");
192 wnck_window_set_fullscreen (active, TRUE(!(0)));
193 }
194
195 return FALSE(0);
196}
197
198static void
199fullscreen (MaximusBind *bind, WnckWindow *window)
200{
201 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
202
203 priv = bind->priv;
204
205 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_fullscreen, bind);
206}
207
208static gboolean
209real_unfullscreen (MaximusBind *bind)
210{
211 MaximusBindPrivate *priv;
212 GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display;
213 WnckWindow *active;
214 const gchar *keystroke;
215
216 priv = bind->priv;
217
218 display = gdk_display_get_default ();
219 active = wnck_screen_get_active_window (priv->screen);
220
221 if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(active)); GType __t = ((wnck_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
222 || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
223 return FALSE(0);
224
225 keystroke = get_unfullscreen_keystroke (priv->rules, active);
226
227 if (keystroke)
228 {
229 guint keysym = 0;
230 EggVirtualModifierType modifiers = 0;
231
232 if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers))
233 {
234 guint mods = 0;
235
236 if (modifiers & EGG_VIRTUAL_SHIFT_MASK)
237 mods |= FAKEKEYMOD_SHIFT;
238 if (modifiers & EGG_VIRTUAL_CONTROL_MASK)
239 mods |= FAKEKEYMOD_CONTROL;
240 if (modifiers & EGG_VIRTUAL_ALT_MASK)
241 mods |= FAKEKEYMOD_ALT;
242 if (modifiers & EGG_VIRTUAL_META_MASK)
243 mods |= FAKEKEYMOD_META;
244
245 g_debug ("Sending fullscreen special event: %s = %d %d",
246 keystroke, keysym, mods);
247 fakekey_press_keysym (priv->fk, keysym, mods);
248 fakekey_release (priv->fk);
249
250 return FALSE(0);
251 }
252 }
253 if (wnck_window_is_fullscreen (active))
254 {
255 g_debug ("Sending un-fullscreen F11 event");
256 fakekey_press_keysym (priv->fk, XK_F110xffc8, 0);
257 fakekey_release (priv->fk);
258 }
259
260 sleep (STATE_CHANGED_SLEEP0.5);
261
262 if (wnck_window_is_fullscreen (active))
263 {
264 g_debug ("Forcing un-fullscreen wnck event");
265 wnck_window_set_fullscreen (active, FALSE(0));
266 }
267
268 return FALSE(0);
269}
270
271static void
272unfullscreen (MaximusBind *bind, WnckWindow *window)
273{
274 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
275
276 priv = bind->priv;
277
278 g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_unfullscreen, bind);
279}
280
281static void
282on_binding_activated (gchar *keystring, MaximusBind *bind)
283{
284 MaximusBindPrivate *priv;
285 WnckWindow *active;
286
287 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
288 priv = bind->priv;
289
290 active = wnck_screen_get_active_window (priv->screen);
291
292 if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL)
293 return;
294
295 if (wnck_window_is_fullscreen (active))
296 {
297 unfullscreen (bind, active);
298 }
299 else
300 {
301 fullscreen (bind, active);
302 }
303}
304
305/* Callbacks */
306static gboolean
307binding_is_valid (const gchar *binding)
308{
309 gboolean retval = TRUE(!(0));
310
311 if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0)
312 retval = FALSE(0);
313
314 return retval;
315}
316
317static void
318on_binding_changed (GSettings *settings,
319 gchar *key,
320 MaximusBind *bind)
321{
322 MaximusBindPrivate *priv;
323
324 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
325 priv = bind->priv;
326
327 if (binding_is_valid (priv->binding))
328 tomboy_keybinder_unbind (priv->binding,
329 (TomboyBindkeyHandler)on_binding_changed);
330 g_free (priv->binding);
331
332 priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS"binding");
333
334 if (binding_is_valid (priv->binding))
335 tomboy_keybinder_bind (priv->binding,
336 (TomboyBindkeyHandler)on_binding_activated,
337 bind);
338
339 g_print ("Binding changed: %s\n", priv->binding);
340}
341
342/* GObject stuff */
343static void
344create_rule (MaximusBind *bind, const gchar *filename)
345{
346#define RULE_GROUP"Fullscreening" "Fullscreening"
347#define RULE_WMCLASS"WMClass" "WMClass"
348#define RULE_FULLSCREEN"Fullscreen" "Fullscreen"
349#define RULE_UNFULLSCREEN"Unfullscreen" "Unfullscreen"
350 MaximusBindPrivate *priv;
351 GKeyFile *file;
352 GError *error = NULL((void*)0);
353 MaximusRule *rule;
354
355 priv = bind->priv;
356
357 file = g_key_file_new ();
358 g_key_file_load_from_file (file, filename, 0, &error);
359 if (error)
360 {
361 g_warning ("Unable to load %s: %s\n", filename, error->message);
362 g_error_free (error);
363 g_key_file_free (file);
364 return;
365 }
366
367 rule = g_slice_new0 (MaximusRule)(MaximusRule *) (__extension__ ({ gsize __s = sizeof (MaximusRule
); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s
); __p; }))
;
368
369 rule->wm_class = g_key_file_get_string (file,
370 RULE_GROUP"Fullscreening", RULE_WMCLASS"WMClass",
371 NULL((void*)0));
372 rule->fullscreen = g_key_file_get_string (file,
373 RULE_GROUP"Fullscreening", RULE_FULLSCREEN"Fullscreen",
374 NULL((void*)0));
375 rule->unfullscreen = g_key_file_get_string (file,
376 RULE_GROUP"Fullscreening", RULE_UNFULLSCREEN"Unfullscreen",
377 NULL((void*)0));
378 if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen)
379 {
380 g_free (rule->wm_class);
381 g_free (rule->fullscreen);
382 g_free (rule->unfullscreen);
383 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
384
385 g_warning ("Unable to load %s, missing strings", filename);
386 }
387 else
388 priv->rules = g_list_append (priv->rules, rule);
389
390 g_key_file_free (file);
391}
392
393static void
394load_rules (MaximusBind *bind, const gchar *path)
395{
396 MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv;
397 GDir *dir;
398 const gchar *name;
399
400 priv = bind->priv;
401
402 dir = g_dir_open (path, 0, NULL((void*)0));
403
404 if (!dir)
405 return;
406
407 while ((name = g_dir_read_name (dir)))
408 {
409 gchar *filename;
410
411 filename= g_build_filename (path, name, NULL((void*)0));
412
413 create_rule (bind, filename);
414
415 g_free (filename);
416 }
417
418 g_dir_close (dir);
419}
420
421static void
422maximus_bind_finalize (GObject *obj)
423{
424 MaximusBind *bind = MAXIMUS_BIND (obj)((((MaximusBind*) g_type_check_instance_cast ((GTypeInstance*
) ((obj)), ((maximus_bind_get_type ()))))))
;
425 MaximusBindPrivate *priv;
426 GList *r;
427
428 g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while (
0)
;
429 priv = bind->priv;
430
431 for (r = priv->rules; r; r = r->next)
432 {
433 MaximusRule *rule = r->data;
434
435 g_free (rule->wm_class);
436 g_free (rule->fullscreen);
437 g_free (rule->unfullscreen);
438
439 g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else
(void) ((MaximusRule*) 0 == (rule)); } while (0)
;
440 }
441 g_free (priv->binding);
442
443 G_OBJECT_CLASS (maximus_bind_parent_class)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((maximus_bind_parent_class
)), (((GType) ((20) << (2))))))))
->finalize (obj);
444}
445
446static void
447maximus_bind_class_init (MaximusBindClass *klass)
448{
449 GObjectClass *obj_class = G_OBJECT_CLASS (klass)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((klass
)), (((GType) ((20) << (2))))))))
;
450
451 obj_class->finalize = maximus_bind_finalize;
452}
453
454static void
455maximus_bind_init (MaximusBind *bind)
456{
457 MaximusBindPrivate *priv;
458 GdkDisplay *display = gdk_display_get_default ();
459 WnckScreen *screen;
460
461 priv = bind->priv = maximus_bind_get_instance_private (bind);
462
463 priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)));
464 priv->screen = screen = wnck_screen_get_default ();
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen'
465 priv->rules = NULL((void*)0);
466 priv->settings = g_settings_new (BIND_SCHEMA"org.mate.maximus");
467
468 tomboy_keybinder_init ();
469
470 g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
471 G_CALLBACK (on_binding_changed), bind)g_signal_connect_data ((priv->settings), ("changed::" "binding"
), (((GCallback) (on_binding_changed))), (bind), ((void*)0), (
GConnectFlags) 0)
;
472
473 priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS"binding");
474
475 if (binding_is_valid (priv->binding))
476 tomboy_keybinder_bind (priv->binding,
477 (TomboyBindkeyHandler)on_binding_activated,
478 bind);
479
480 load_rules (bind, SYSRULESDIR"/usr/local/etc""/maximus");
481}
482
483MaximusBind *
484maximus_bind_get_default (void)
485
486{
487 static MaximusBind *bind = NULL((void*)0);
488
489 if (!bind)
490 bind = g_object_new (MAXIMUS_TYPE_BIND(maximus_bind_get_type ()),
491 NULL((void*)0));
492
493 return bind;
494}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-94cbc5.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-94cbc5.html new file mode 100644 index 0000000..12fcf09 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-94cbc5.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 433, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-cba9e3.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-cba9e3.html new file mode 100644 index 0000000..d412c57 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-cba9e3.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 448, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-ecd83c.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-ecd83c.html new file mode 100644 index 0000000..88bbd49 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-ecd83c.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 403, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/report-efae04.html b/2022-02-13-183617-5516-1@becf3036fb90_master/report-efae04.html new file mode 100644 index 0000000..e10ce15 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/report-efae04.html @@ -0,0 +1,1008 @@ + + + +eggaccelerators.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:eggaccelerators.c
Warning:line 438, column 7
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name eggaccelerators.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/maximus -resource-dir /usr/lib64/clang/13.0.0 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I /usr/include/at-spi-2.0 -I /usr/include/libwnck-3.0 -I /usr/include/startup-notification-1.0 -I .. -I .. -I ../tidy -D _GNU_SOURCE -D PKGDATADIR="/usr/local/share/mate-maximus" -D DATADIR="/usr/local/share" -D SYSCONFDIR="/usr/local/etc" -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/maximus -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-02-13-183617-5516-1 -x c eggaccelerators.c +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* eggaccelerators.c
2 * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
3 * Copyright (C) 2012-2021 MATE Developers
4 * Developed by Havoc Pennington, Tim Janik
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21#include "eggaccelerators.h"
22
23#include <string.h>
24#include <gdk/gdkx.h>
25#include <gdk/gdkkeysyms.h>
26
27enum
28{
29 EGG_MODMAP_ENTRY_SHIFT = 0,
30 EGG_MODMAP_ENTRY_LOCK = 1,
31 EGG_MODMAP_ENTRY_CONTROL = 2,
32 EGG_MODMAP_ENTRY_MOD1 = 3,
33 EGG_MODMAP_ENTRY_MOD2 = 4,
34 EGG_MODMAP_ENTRY_MOD3 = 5,
35 EGG_MODMAP_ENTRY_MOD4 = 6,
36 EGG_MODMAP_ENTRY_MOD5 = 7,
37 EGG_MODMAP_ENTRY_LAST = 8
38};
39
40#define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x))
41
42typedef struct
43{
44 EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
45
46} EggModmap;
47
48const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
49
50static inline gboolean
51is_alt (const gchar *string)
52{
53 return ((string[0] == '<') &&
54 (string[1] == 'a' || string[1] == 'A') &&
55 (string[2] == 'l' || string[2] == 'L') &&
56 (string[3] == 't' || string[3] == 'T') &&
57 (string[4] == '>'));
58}
59
60static inline gboolean
61is_ctl (const gchar *string)
62{
63 return ((string[0] == '<') &&
64 (string[1] == 'c' || string[1] == 'C') &&
65 (string[2] == 't' || string[2] == 'T') &&
66 (string[3] == 'l' || string[3] == 'L') &&
67 (string[4] == '>'));
68}
69
70static inline gboolean
71is_modx (const gchar *string)
72{
73 return ((string[0] == '<') &&
74 (string[1] == 'm' || string[1] == 'M') &&
75 (string[2] == 'o' || string[2] == 'O') &&
76 (string[3] == 'd' || string[3] == 'D') &&
77 (string[4] >= '1' && string[4] <= '5') &&
78 (string[5] == '>'));
79}
80
81static inline gboolean
82is_ctrl (const gchar *string)
83{
84 return ((string[0] == '<') &&
85 (string[1] == 'c' || string[1] == 'C') &&
86 (string[2] == 't' || string[2] == 'T') &&
87 (string[3] == 'r' || string[3] == 'R') &&
88 (string[4] == 'l' || string[4] == 'L') &&
89 (string[5] == '>'));
90}
91
92static inline gboolean
93is_shft (const gchar *string)
94{
95 return ((string[0] == '<') &&
96 (string[1] == 's' || string[1] == 'S') &&
97 (string[2] == 'h' || string[2] == 'H') &&
98 (string[3] == 'f' || string[3] == 'F') &&
99 (string[4] == 't' || string[4] == 'T') &&
100 (string[5] == '>'));
101}
102
103static inline gboolean
104is_shift (const gchar *string)
105{
106 return ((string[0] == '<') &&
107 (string[1] == 's' || string[1] == 'S') &&
108 (string[2] == 'h' || string[2] == 'H') &&
109 (string[3] == 'i' || string[3] == 'I') &&
110 (string[4] == 'f' || string[4] == 'F') &&
111 (string[5] == 't' || string[5] == 'T') &&
112 (string[6] == '>'));
113}
114
115static inline gboolean
116is_control (const gchar *string)
117{
118 return ((string[0] == '<') &&
119 (string[1] == 'c' || string[1] == 'C') &&
120 (string[2] == 'o' || string[2] == 'O') &&
121 (string[3] == 'n' || string[3] == 'N') &&
122 (string[4] == 't' || string[4] == 'T') &&
123 (string[5] == 'r' || string[5] == 'R') &&
124 (string[6] == 'o' || string[6] == 'O') &&
125 (string[7] == 'l' || string[7] == 'L') &&
126 (string[8] == '>'));
127}
128
129static inline gboolean
130is_release (const gchar *string)
131{
132 return ((string[0] == '<') &&
133 (string[1] == 'r' || string[1] == 'R') &&
134 (string[2] == 'e' || string[2] == 'E') &&
135 (string[3] == 'l' || string[3] == 'L') &&
136 (string[4] == 'e' || string[4] == 'E') &&
137 (string[5] == 'a' || string[5] == 'A') &&
138 (string[6] == 's' || string[6] == 'S') &&
139 (string[7] == 'e' || string[7] == 'E') &&
140 (string[8] == '>'));
141}
142
143static inline gboolean
144is_meta (const gchar *string)
145{
146 return ((string[0] == '<') &&
147 (string[1] == 'm' || string[1] == 'M') &&
148 (string[2] == 'e' || string[2] == 'E') &&
149 (string[3] == 't' || string[3] == 'T') &&
150 (string[4] == 'a' || string[4] == 'A') &&
151 (string[5] == '>'));
152}
153
154static inline gboolean
155is_super (const gchar *string)
156{
157 return ((string[0] == '<') &&
158 (string[1] == 's' || string[1] == 'S') &&
159 (string[2] == 'u' || string[2] == 'U') &&
160 (string[3] == 'p' || string[3] == 'P') &&
161 (string[4] == 'e' || string[4] == 'E') &&
162 (string[5] == 'r' || string[5] == 'R') &&
163 (string[6] == '>'));
164}
165
166static inline gboolean
167is_hyper (const gchar *string)
168{
169 return ((string[0] == '<') &&
170 (string[1] == 'h' || string[1] == 'H') &&
171 (string[2] == 'y' || string[2] == 'Y') &&
172 (string[3] == 'p' || string[3] == 'P') &&
173 (string[4] == 'e' || string[4] == 'E') &&
174 (string[5] == 'r' || string[5] == 'R') &&
175 (string[6] == '>'));
176}
177
178/**
179 * egg_accelerator_parse_virtual:
180 * @accelerator: string representing an accelerator
181 * @accelerator_key: return location for accelerator keyval
182 * @accelerator_mods: return location for accelerator modifier mask
183 *
184 * Parses a string representing a virtual accelerator. The format
185 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
186 * "&lt;Release&gt;z" (the last one is for key release). The parser
187 * is fairly liberal and allows lower or upper case, and also
188 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
189 *
190 * If the parse fails, @accelerator_key and @accelerator_mods will
191 * be set to 0 (zero) and %FALSE will be returned. If the string contains
192 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
193 * returned.
194 *
195 * The virtual vs. concrete accelerator distinction is a relic of
196 * how the X Window System works; there are modifiers Mod2-Mod5 that
197 * can represent various keyboard keys (numlock, meta, hyper, etc.),
198 * the virtual modifier represents the keyboard key, the concrete
199 * modifier the actual Mod2-Mod5 bits in the key press event.
200 *
201 * Returns: %TRUE on success.
202 */
203gboolean
204egg_accelerator_parse_virtual (const gchar *accelerator,
205 guint *accelerator_key,
206 EggVirtualModifierType *accelerator_mods)
207{
208 guint keyval;
209 GdkModifierType mods;
210 gint len;
211 gboolean bad_keyval;
212
213 if (accelerator_key)
214 *accelerator_key = 0;
215 if (accelerator_mods)
216 *accelerator_mods = 0;
217
218 g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL"
); return ((0)); } } while (0)
;
219
220 bad_keyval = FALSE(0);
221
222 keyval = 0;
223 mods = 0;
224 len = strlen (accelerator);
225 while (len)
226 {
227 if (*accelerator == '<')
228 {
229 if (len >= 9 && is_release (accelerator))
230 {
231 accelerator += 9;
232 len -= 9;
233 mods |= EGG_VIRTUAL_RELEASE_MASK;
234 }
235 else if (len >= 9 && is_control (accelerator))
236 {
237 accelerator += 9;
238 len -= 9;
239 mods |= EGG_VIRTUAL_CONTROL_MASK;
240 }
241 else if (len >= 7 && is_shift (accelerator))
242 {
243 accelerator += 7;
244 len -= 7;
245 mods |= EGG_VIRTUAL_SHIFT_MASK;
246 }
247 else if (len >= 6 && is_shft (accelerator))
248 {
249 accelerator += 6;
250 len -= 6;
251 mods |= EGG_VIRTUAL_SHIFT_MASK;
252 }
253 else if (len >= 6 && is_ctrl (accelerator))
254 {
255 accelerator += 6;
256 len -= 6;
257 mods |= EGG_VIRTUAL_CONTROL_MASK;
258 }
259 else if (len >= 6 && is_modx (accelerator))
260 {
261 static const guint mod_vals[] = {
262 EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
263 EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
264 };
265
266 len -= 6;
267 accelerator += 4;
268 mods |= mod_vals[*accelerator - '1'];
269 accelerator += 2;
270 }
271 else if (len >= 5 && is_ctl (accelerator))
272 {
273 accelerator += 5;
274 len -= 5;
275 mods |= EGG_VIRTUAL_CONTROL_MASK;
276 }
277 else if (len >= 5 && is_alt (accelerator))
278 {
279 accelerator += 5;
280 len -= 5;
281 mods |= EGG_VIRTUAL_ALT_MASK;
282 }
283 else if (len >= 6 && is_meta (accelerator))
284 {
285 accelerator += 6;
286 len -= 6;
287 mods |= EGG_VIRTUAL_META_MASK;
288 }
289 else if (len >= 7 && is_hyper (accelerator))
290 {
291 accelerator += 7;
292 len -= 7;
293 mods |= EGG_VIRTUAL_HYPER_MASK;
294 }
295 else if (len >= 7 && is_super (accelerator))
296 {
297 accelerator += 7;
298 len -= 7;
299 mods |= EGG_VIRTUAL_SUPER_MASK;
300 }
301 else
302 {
303 gchar last_ch;
304
305 last_ch = *accelerator;
306 while (last_ch && last_ch != '>')
307 {
308 last_ch = *accelerator;
309 accelerator += 1;
310 len -= 1;
311 }
312 }
313 }
314 else
315 {
316 keyval = gdk_keyval_from_name (accelerator);
317
318 if (keyval == 0)
319 bad_keyval = TRUE(!(0));
320
321 accelerator += len;
322 len -= len;
323 }
324 }
325
326 if (accelerator_key)
327 *accelerator_key = gdk_keyval_to_lower (keyval);
328 if (accelerator_mods)
329 *accelerator_mods = mods;
330
331 return !bad_keyval;
332}
333
334/**
335 * egg_virtual_accelerator_name:
336 * @accelerator_key: accelerator keyval
337 * @accelerator_mods: accelerator modifier mask
338 * @returns: a newly-allocated accelerator name
339 *
340 * Converts an accelerator keyval and modifier mask
341 * into a string parseable by egg_accelerator_parse_virtual().
342 * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
343 * this function returns "&lt;Control&gt;q".
344 *
345 * The caller of this function must free the returned string.
346 */
347gchar*
348egg_virtual_accelerator_name (guint accelerator_key,
349 EggVirtualModifierType accelerator_mods)
350{
351 static const gchar text_release[] = "<Release>";
352 static const gchar text_shift[] = "<Shift>";
353 static const gchar text_control[] = "<Control>";
354 static const gchar text_mod1[] = "<Alt>";
355 static const gchar text_mod2[] = "<Mod2>";
356 static const gchar text_mod3[] = "<Mod3>";
357 static const gchar text_mod4[] = "<Mod4>";
358 static const gchar text_mod5[] = "<Mod5>";
359 static const gchar text_meta[] = "<Meta>";
360 static const gchar text_super[] = "<Super>";
361 static const gchar text_hyper[] = "<Hyper>";
362 guint l;
363 gchar *keyval_name;
364 gchar *accelerator;
365
366 accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
367
368 keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
369 if (!keyval_name)
370 keyval_name = "";
371
372 l = 0;
373 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
374 l += sizeof (text_release) - 1;
375 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
376 l += sizeof (text_shift) - 1;
377 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
378 l += sizeof (text_control) - 1;
379 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
380 l += sizeof (text_mod1) - 1;
381 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
382 l += sizeof (text_mod2) - 1;
383 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
384 l += sizeof (text_mod3) - 1;
385 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
386 l += sizeof (text_mod4) - 1;
387 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
388 l += sizeof (text_mod5) - 1;
389 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
390 l += sizeof (text_meta) - 1;
391 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
392 l += sizeof (text_hyper) - 1;
393 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
394 l += sizeof (text_super) - 1;
395 l += strlen (keyval_name);
396
397 accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize
__s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p;
}))
;
398
399 l = 0;
400 accelerator[l] = 0;
401 if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
402 {
403 strcpy (accelerator + l, text_release);
404 l += sizeof (text_release) - 1;
405 }
406 if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
407 {
408 strcpy (accelerator + l, text_shift);
409 l += sizeof (text_shift) - 1;
410 }
411 if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
412 {
413 strcpy (accelerator + l, text_control);
414 l += sizeof (text_control) - 1;
415 }
416 if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
417 {
418 strcpy (accelerator + l, text_mod1);
419 l += sizeof (text_mod1) - 1;
420 }
421 if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
422 {
423 strcpy (accelerator + l, text_mod2);
424 l += sizeof (text_mod2) - 1;
425 }
426 if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
427 {
428 strcpy (accelerator + l, text_mod3);
429 l += sizeof (text_mod3) - 1;
430 }
431 if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
432 {
433 strcpy (accelerator + l, text_mod4);
434 l += sizeof (text_mod4) - 1;
435 }
436 if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
437 {
438 strcpy (accelerator + l, text_mod5);
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
439 l += sizeof (text_mod5) - 1;
440 }
441 if (accelerator_mods & EGG_VIRTUAL_META_MASK)
442 {
443 strcpy (accelerator + l, text_meta);
444 l += sizeof (text_meta) - 1;
445 }
446 if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
447 {
448 strcpy (accelerator + l, text_hyper);
449 l += sizeof (text_hyper) - 1;
450 }
451 if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
452 {
453 strcpy (accelerator + l, text_super);
454 l += sizeof (text_super) - 1;
455 }
456
457 strcpy (accelerator + l, keyval_name);
458
459 return accelerator;
460}
461
462void
463egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
464 EggVirtualModifierType virtual_mods,
465 GdkModifierType *concrete_mods)
466{
467 GdkModifierType concrete;
468 int i;
469 const EggModmap *modmap;
470
471 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
472 g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL"
); return; } } while (0)
;
473
474 modmap = egg_keymap_get_modmap (keymap);
475
476 /* Not so sure about this algorithm. */
477
478 concrete = 0;
479 i = 0;
480 while (i < EGG_MODMAP_ENTRY_LAST)
481 {
482 if (modmap->mapping[i] & virtual_mods)
483 concrete |= (1 << i);
484
485 ++i;
486 }
487
488 *concrete_mods = concrete;
489}
490
491void
492egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
493 GdkModifierType concrete_mods,
494 EggVirtualModifierType *virtual_mods)
495{
496 GdkModifierType virtual;
497 int i;
498 const EggModmap *modmap;
499
500 g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { }
else { g_return_if_fail_warning (((gchar*) 0), ((const char*
) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while (
0)
;
501 g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL"
); return; } } while (0)
;
502
503 modmap = egg_keymap_get_modmap (keymap);
504
505 /* Not so sure about this algorithm. */
506
507 virtual = 0;
508 i = 0;
509 while (i < EGG_MODMAP_ENTRY_LAST)
510 {
511 if ((1 << i) & concrete_mods)
512 {
513 EggVirtualModifierType cleaned;
514
515 cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
516 EGG_VIRTUAL_MOD3_MASK |
517 EGG_VIRTUAL_MOD4_MASK |
518 EGG_VIRTUAL_MOD5_MASK);
519
520 if (cleaned != 0)
521 {
522 virtual |= cleaned;
523 }
524 else
525 {
526 /* Rather than dropping mod2->mod5 if not bound,
527 * go ahead and use the concrete names
528 */
529 virtual |= modmap->mapping[i];
530 }
531 }
532
533 ++i;
534 }
535
536 *virtual_mods = virtual;
537}
538
539static void
540reload_modmap (GdkKeymap *keymap,
541 EggModmap *modmap)
542{
543 XModifierKeymap *xmodmap;
544 int map_size;
545 int i;
546
547 /* FIXME multihead */
548 xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
549
550 memset (modmap->mapping, 0, sizeof (modmap->mapping));
551
552 /* there are 8 modifiers, and the first 3 are shift, shift lock,
553 * and control
554 */
555 map_size = 8 * xmodmap->max_keypermod;
556 i = 3 * xmodmap->max_keypermod;
557 while (i < map_size)
558 {
559 /* get the key code at this point in the map,
560 * see if its keysym is one we're interested in
561 */
562 int keycode = xmodmap->modifiermap[i];
563 GdkKeymapKey *keys;
564 guint *keyvals;
565 int n_entries;
566 int j;
567 EggVirtualModifierType mask;
568
569 keys = NULL((void*)0);
570 keyvals = NULL((void*)0);
571 n_entries = 0;
572
573 gdk_keymap_get_entries_for_keycode (keymap,
574 keycode,
575 &keys, &keyvals, &n_entries);
576
577 mask = 0;
578 j = 0;
579 while (j < n_entries)
580 {
581 if (keyvals[j] == GDK_KEY_Num_Lock0xff7f)
582 mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
583 else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14)
584 mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
585 else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 ||
586 keyvals[j] == GDK_KEY_Meta_R0xffe8)
587 mask |= EGG_VIRTUAL_META_MASK;
588 else if (keyvals[j] == GDK_KEY_Hyper_L0xffed ||
589 keyvals[j] == GDK_KEY_Hyper_R0xffee)
590 mask |= EGG_VIRTUAL_HYPER_MASK;
591 else if (keyvals[j] == GDK_KEY_Super_L0xffeb ||
592 keyvals[j] == GDK_KEY_Super_R0xffec)
593 mask |= EGG_VIRTUAL_SUPER_MASK;
594 else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e)
595 mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
596
597 ++j;
598 }
599
600 /* Mod1Mask is 1 << 3 for example, i.e. the
601 * fourth modifier, i / keyspermod is the modifier
602 * index
603 */
604 modmap->mapping[i/xmodmap->max_keypermod] |= mask;
605
606 g_free (keyvals);
607 g_free (keys);
608
609 ++i;
610 }
611
612 /* Add in the not-really-virtual fixed entries */
613 modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
614 modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
615 modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
616 modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
617 modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
618 modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
619 modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
620 modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
621
622 XFreeModifiermap (xmodmap);
623}
624
625const EggModmap*
626egg_keymap_get_modmap (GdkKeymap *keymap)
627{
628 EggModmap *modmap;
629
630 /* This is all a hack, much simpler when we can just
631 * modify GDK directly.
632 */
633
634 modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
635 "egg-modmap");
636
637 if (modmap == NULL((void*)0))
638 {
639 modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize
__s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
640
641 /* FIXME modify keymap change events with an event filter
642 * and force a reload if we get one
643 */
644
645 reload_modmap (keymap, modmap);
646
647 g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((
keymap)), (((GType) ((20) << (2))))))))
,
648 "egg-modmap",
649 modmap,
650 g_free);
651 }
652
653 g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr
(((gchar*) 0), "eggaccelerators.c", 653, ((const char*) (__func__
)), "modmap != NULL"); } while (0)
;
654
655 return modmap;
656}
diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/scanview.css b/2022-02-13-183617-5516-1@becf3036fb90_master/scanview.css new file mode 100644 index 0000000..cf8a5a6 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/scanview.css @@ -0,0 +1,62 @@ +body { color:#000000; background-color:#ffffff } +body { font-family: Helvetica, sans-serif; font-size:9pt } +h1 { font-size: 14pt; } +h2 { font-size: 12pt; } +table { font-size:9pt } +table { border-spacing: 0px; border: 1px solid black } +th, table thead { + background-color:#eee; color:#666666; + font-weight: bold; cursor: default; + text-align:center; + font-weight: bold; font-family: Verdana; + white-space:nowrap; +} +.W { font-size:0px } +th, td { padding:5px; padding-left:8px; text-align:left } +td.SUMM_DESC { padding-left:12px } +td.DESC { white-space:pre } +td.Q { text-align:right } +td { text-align:left } +tbody.scrollContent { overflow:auto } + +table.form_group { + background-color: #ccc; + border: 1px solid #333; + padding: 2px; +} + +table.form_inner_group { + background-color: #ccc; + border: 1px solid #333; + padding: 0px; +} + +table.form { + background-color: #999; + border: 1px solid #333; + padding: 2px; +} + +td.form_label { + text-align: right; + vertical-align: top; +} +/* For one line entires */ +td.form_clabel { + text-align: right; + vertical-align: center; +} +td.form_value { + text-align: left; + vertical-align: top; +} +td.form_submit { + text-align: right; + vertical-align: top; +} + +h1.SubmitFail { + color: #f00; +} +h1.SubmitOk { +} diff --git a/2022-02-13-183617-5516-1@becf3036fb90_master/sorttable.js b/2022-02-13-183617-5516-1@becf3036fb90_master/sorttable.js new file mode 100644 index 0000000..32faa07 --- /dev/null +++ b/2022-02-13-183617-5516-1@becf3036fb90_master/sorttable.js @@ -0,0 +1,492 @@ +/* + SortTable + version 2 + 7th April 2007 + Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ + + Instructions: + Download this file + Add to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backward compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write("