Bug Summary

File:ctk/ctkactionable.c
Warning:line 78, column 27
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-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ctkactionable.c -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 pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/ctk -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -D G_LOG_DOMAIN="Ctk" -D G_LOG_USE_STRUCTURED=1 -D CTK_VERSION="3.25.5" -D CTK_BINARY_VERSION="3.0.0" -D CTK_COMPILATION -D CTK_PRINT_BACKEND_ENABLE_UNSUPPORTED -D CTK_LIBDIR="/usr/lib" -D CTK_LOCALEDIR="/usr/share/locale" -D CTK_DATADIR="/usr/share" -D CTK_DATA_PREFIX="/usr" -D CTK_SYSCONFDIR="/usr/etc" -D CTK_HOST="x86_64-pc-linux-gnu" -D CTK_PRINT_BACKENDS="file,cups" -D X11_DATA_PREFIX="/usr" -D ISO_CODES_PREFIX="" -I .. -I ../ctk -I .. -I ../cdk -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -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/cairo -I /usr/include/pixman-1 -I /usr/include/atk-1.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gio-unix-2.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/pango-1.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/ctk -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -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-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-09-19-171836-43636-1 -x c ctkactionable.c
1/*
2 * Copyright © 2012 Canonical Limited
3 *
4 * This library is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * licence or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Ryan Lortie <desrt@desrt.ca>
18 */
19
20#include "config.h"
21
22#include "ctkactionable.h"
23
24#include "ctkwidget.h"
25#include "ctkintl.h"
26
27/**
28 * SECTION:ctkactionable
29 * @title: CtkActionable
30 * @short_description: An interface for widgets that can be associated
31 * with actions
32 *
33 * This interface provides a convenient way of associating widgets with
34 * actions on a #CtkApplicationWindow or #CtkApplication.
35 *
36 * It primarily consists of two properties: #CtkActionable:action-name
37 * and #CtkActionable:action-target. There are also some convenience APIs
38 * for setting these properties.
39 *
40 * The action will be looked up in action groups that are found among
41 * the widgets ancestors. Most commonly, these will be the actions with
42 * the “win.” or “app.” prefix that are associated with the #CtkApplicationWindow
43 * or #CtkApplication, but other action groups that are added with
44 * ctk_widget_insert_action_group() will be consulted as well.
45 *
46 * Since: 3.4
47 **/
48
49/**
50 * CtkActionable:
51 *
52 * An opaque pointer type.
53 **/
54
55/**
56 * CtkActionableInterface:
57 * @get_action_name: virtual function for ctk_actionable_get_action_name()
58 * @set_action_name: virtual function for ctk_actionable_set_action_name()
59 * @get_action_target_value: virtual function for ctk_actionable_get_action_target_value()
60 * @set_action_target_value: virtual function for ctk_actionable_set_action_target_value()
61 *
62 * The interface vtable for #CtkActionable.
63 **/
64
65G_DEFINE_INTERFACE (CtkActionable, ctk_actionable, CTK_TYPE_WIDGET)static void ctk_actionable_default_init (CtkActionableInterface
*klass); GType ctk_actionable_get_type (void) { static GType
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_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= g_type_register_static_simple (((GType) ((2) << (2))
), g_intern_static_string ("CtkActionable"), sizeof (CtkActionableInterface
), (GClassInitFunc)(void (*)(void)) ctk_actionable_default_init
, 0, (GInstanceInitFunc)((void*)0), (GTypeFlags) 0); if ((ctk_widget_get_type
()) != ((GType) ((0) << (2)))) g_type_interface_add_prerequisite
(g_define_type_id, (ctk_widget_get_type ())); { {;;} } (__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_pointer ((&static_g_define_type_id
), (gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id
; }
66
67static void
68ctk_actionable_default_init (CtkActionableInterface *iface)
69{
70 g_object_interface_install_property (iface,
71 g_param_spec_string ("action-name", P_("Action name")g_dgettext("ctk30" "-properties","Action name"),
72 P_("The name of the associated action, like 'app.quit'")g_dgettext("ctk30" "-properties","The name of the associated action, like 'app.quit'"
)
,
73 NULL((void*)0), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
));
74
75 g_object_interface_install_property (iface,
76 g_param_spec_variant ("action-target", P_("Action target value")g_dgettext("ctk30" "-properties","Action target value"),
77 P_("The parameter for action invocations")g_dgettext("ctk30" "-properties","The parameter for action invocations"
)
,
78 G_VARIANT_TYPE_ANY((const GVariantType *) "*"), NULL((void*)0), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
));
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
79}
80
81/**
82 * ctk_actionable_get_action_name:
83 * @actionable: a #CtkActionable widget
84 *
85 * Gets the action name for @actionable.
86 *
87 * See ctk_actionable_set_action_name() for more information.
88 *
89 * Returns: (nullable): the action name, or %NULL if none is set
90 *
91 * Since: 3.4
92 **/
93const gchar *
94ctk_actionable_get_action_name (CtkActionable *actionable)
95{
96 g_return_val_if_fail (CTK_IS_ACTIONABLE (actionable), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((actionable)); GType __t = ((ctk_actionable_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; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_ACTIONABLE (actionable)"); return (((
void*)0)); } } while (0)
;
97
98 return CTK_ACTIONABLE_GET_IFACE (actionable)((((CtkActionableInterface*) g_type_interface_peek (((GTypeInstance
*) ((actionable)))->g_class, ((ctk_actionable_get_type ())
)))))
99 ->get_action_name (actionable);
100}
101
102/**
103 * ctk_actionable_set_action_name:
104 * @actionable: a #CtkActionable widget
105 * @action_name: (nullable): an action name, or %NULL
106 *
107 * Specifies the name of the action with which this widget should be
108 * associated. If @action_name is %NULL then the widget will be
109 * unassociated from any previous action.
110 *
111 * Usually this function is used when the widget is located (or will be
112 * located) within the hierarchy of a #CtkApplicationWindow.
113 *
114 * Names are of the form “win.save” or “app.quit” for actions on the
115 * containing #CtkApplicationWindow or its associated #CtkApplication,
116 * respectively. This is the same form used for actions in the #GMenu
117 * associated with the window.
118 *
119 * Since: 3.4
120 **/
121void
122ctk_actionable_set_action_name (CtkActionable *actionable,
123 const gchar *action_name)
124{
125 g_return_if_fail (CTK_IS_ACTIONABLE (actionable))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((actionable)); GType __t = ((ctk_actionable_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; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_ACTIONABLE (actionable)"); return; } }
while (0)
;
126
127 CTK_ACTIONABLE_GET_IFACE (actionable)((((CtkActionableInterface*) g_type_interface_peek (((GTypeInstance
*) ((actionable)))->g_class, ((ctk_actionable_get_type ())
)))))
128 ->set_action_name (actionable, action_name);
129}
130
131/**
132 * ctk_actionable_get_action_target_value:
133 * @actionable: a #CtkActionable widget
134 *
135 * Gets the current target value of @actionable.
136 *
137 * See ctk_actionable_set_action_target_value() for more information.
138 *
139 * Returns: (transfer none): the current target value
140 *
141 * Since: 3.4
142 **/
143GVariant *
144ctk_actionable_get_action_target_value (CtkActionable *actionable)
145{
146 g_return_val_if_fail (CTK_IS_ACTIONABLE (actionable), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((actionable)); GType __t = ((ctk_actionable_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; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_ACTIONABLE (actionable)"); return (((
void*)0)); } } while (0)
;
147
148 return CTK_ACTIONABLE_GET_IFACE (actionable)((((CtkActionableInterface*) g_type_interface_peek (((GTypeInstance
*) ((actionable)))->g_class, ((ctk_actionable_get_type ())
)))))
149 ->get_action_target_value (actionable);
150}
151
152/**
153 * ctk_actionable_set_action_target_value:
154 * @actionable: a #CtkActionable widget
155 * @target_value: (nullable): a #GVariant to set as the target value, or %NULL
156 *
157 * Sets the target value of an actionable widget.
158 *
159 * If @target_value is %NULL then the target value is unset.
160 *
161 * The target value has two purposes. First, it is used as the
162 * parameter to activation of the action associated with the
163 * #CtkActionable widget. Second, it is used to determine if the widget
164 * should be rendered as “active” — the widget is active if the state
165 * is equal to the given target.
166 *
167 * Consider the example of associating a set of buttons with a #GAction
168 * with string state in a typical “radio button” situation. Each button
169 * will be associated with the same action, but with a different target
170 * value for that action. Clicking on a particular button will activate
171 * the action with the target of that button, which will typically cause
172 * the action’s state to change to that value. Since the action’s state
173 * is now equal to the target value of the button, the button will now
174 * be rendered as active (and the other buttons, with different targets,
175 * rendered inactive).
176 *
177 * Since: 3.4
178 **/
179void
180ctk_actionable_set_action_target_value (CtkActionable *actionable,
181 GVariant *target_value)
182{
183 g_return_if_fail (CTK_IS_ACTIONABLE (actionable))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((actionable)); GType __t = ((ctk_actionable_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; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_ACTIONABLE (actionable)"); return; } }
while (0)
;
184
185 CTK_ACTIONABLE_GET_IFACE (actionable)((((CtkActionableInterface*) g_type_interface_peek (((GTypeInstance
*) ((actionable)))->g_class, ((ctk_actionable_get_type ())
)))))
186 ->set_action_target_value (actionable, target_value);
187}
188
189/**
190 * ctk_actionable_set_action_target:
191 * @actionable: a #CtkActionable widget
192 * @format_string: a GVariant format string
193 * @...: arguments appropriate for @format_string
194 *
195 * Sets the target of an actionable widget.
196 *
197 * This is a convenience function that calls g_variant_new() for
198 * @format_string and uses the result to call
199 * ctk_actionable_set_action_target_value().
200 *
201 * If you are setting a string-valued target and want to set the action
202 * name at the same time, you can use
203 * ctk_actionable_set_detailed_action_name ().
204 *
205 * Since: 3.4
206 **/
207void
208ctk_actionable_set_action_target (CtkActionable *actionable,
209 const gchar *format_string,
210 ...)
211{
212 va_list ap;
213
214 va_start (ap, format_string)__builtin_va_start(ap, format_string);
215 ctk_actionable_set_action_target_value (actionable, g_variant_new_va (format_string, NULL((void*)0), &ap));
216 va_end (ap)__builtin_va_end(ap);
217}
218
219/**
220 * ctk_actionable_set_detailed_action_name:
221 * @actionable: a #CtkActionable widget
222 * @detailed_action_name: the detailed action name
223 *
224 * Sets the action-name and associated string target value of an
225 * actionable widget.
226 *
227 * @detailed_action_name is a string in the format accepted by
228 * g_action_parse_detailed_name().
229 *
230 * (Note that prior to version 3.22.25,
231 * this function is only usable for actions with a simple "s" target, and
232 * @detailed_action_name must be of the form `"action::target"` where
233 * `action` is the action name and `target` is the string to use
234 * as the target.)
235 *
236 * Since: 3.4
237 **/
238void
239ctk_actionable_set_detailed_action_name (CtkActionable *actionable,
240 const gchar *detailed_action_name)
241{
242 GError *error = NULL((void*)0);
243 GVariant *target;
244 gchar *name;
245
246 if (detailed_action_name == NULL((void*)0))
247 {
248 ctk_actionable_set_action_name (actionable, NULL((void*)0));
249 ctk_actionable_set_action_target_value (actionable, NULL((void*)0));
250 return;
251 }
252
253 if (!g_action_parse_detailed_name (detailed_action_name, &name, &target, &error))
254 g_error ("ctk_actionable_set_detailed_action_name: %s", error->message);
255
256 ctk_actionable_set_action_name (actionable, name);
257 ctk_actionable_set_action_target_value (actionable, target);
258
259 if (target)
260 g_variant_unref (target);
261 g_free (name);
262}
263