Bug Summary

File:shell/ev-bookmarks.c
Warning:line 204, column 43
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 ev-bookmarks.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 -pic-is-pie -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/shell -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -D LECTORDATADIR="/usr/share/lector" -D CAFEDATADIR="/usr/share" -I .. -I .. -I ../cut-n-paste/zoom-control/ -I ../cut-n-paste/toolbar-editor/ -I ../cut-n-paste/smclient/ -I ../libdocument -I ../libdocument -I ../libview -I ../libview -I ../libmisc -I ../properties -D CAFEICONDIR="/usr/share/pixmaps" -D BINDIR="/usr/bin" -D LIBEXECDIR="/usr/libexec" -D LECTOR_COMPILATION -I /usr/include/libxml2 -I /usr/include/ctk-3.0 -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/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/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -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/libsecret-1 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gio-unix-2.0 -D CDK_MULTIHEAD_SAFE -D CTK_MULTIHEAD_SAFE -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../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/shell -ferror-limit 19 -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-02-21-192548-54189-1 -x c ev-bookmarks.c
1/* ev-bookmarks.c
2 * this file is part of evince, a gnome document viewer
3 *
4 * Copyright (C) 2010 Carlos Garcia Campos <carlosgc@gnome.org>
5 *
6 * Evince is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * Evince is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include "config.h"
22
23#include <string.h>
24
25#include "ev-bookmarks.h"
26
27enum {
28 PROP_0,
29 PROP_METADATA
30};
31
32enum {
33 CHANGED,
34 N_SIGNALS
35};
36
37struct _EvBookmarks {
38 GObject base;
39
40 EvMetadata *metadata;
41 GList *items;
42};
43
44struct _EvBookmarksClass {
45 GObjectClass base_class;
46
47 void (*changed) (EvBookmarks *bookmarks);
48};
49
50G_DEFINE_TYPE (EvBookmarks, ev_bookmarks, G_TYPE_OBJECT)static void ev_bookmarks_init (EvBookmarks *self); static void
ev_bookmarks_class_init (EvBookmarksClass *klass); static GType
ev_bookmarks_get_type_once (void); static gpointer ev_bookmarks_parent_class
= ((void*)0); static gint EvBookmarks_private_offset; static
void ev_bookmarks_class_intern_init (gpointer klass) { ev_bookmarks_parent_class
= g_type_class_peek_parent (klass); if (EvBookmarks_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &EvBookmarks_private_offset
); ev_bookmarks_class_init ((EvBookmarksClass*) klass); } __attribute__
((__unused__)) static inline gpointer ev_bookmarks_get_instance_private
(EvBookmarks *self) { return (((gpointer) ((guint8*) (self) +
(glong) (EvBookmarks_private_offset)))); } GType ev_bookmarks_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 = ev_bookmarks_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 ev_bookmarks_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("EvBookmarks"
), sizeof (EvBookmarksClass), (GClassInitFunc)(void (*)(void)
) ev_bookmarks_class_intern_init, sizeof (EvBookmarks), (GInstanceInitFunc
)(void (*)(void)) ev_bookmarks_init, (GTypeFlags) 0); { {{};}
} return g_define_type_id; }
51
52static guint signals[N_SIGNALS];
53
54static gint
55ev_bookmark_compare (EvBookmark *a,
56 EvBookmark *b)
57{
58 if (a->page < b->page)
59 return -1;
60 if (a->page > b->page)
61 return 1;
62 return 0;
63}
64
65static void
66ev_bookmark_free (EvBookmark *bm)
67{
68 if (G_UNLIKELY(!bm)(!bm))
69 return;
70
71 g_free (bm->title);
72 g_slice_free (EvBookmark, bm)do { if (1) g_slice_free1 (sizeof (EvBookmark), (bm)); else (
void) ((EvBookmark*) 0 == (bm)); } while (0)
;
73}
74
75static void
76ev_bookmarks_finalize (GObject *object)
77{
78 EvBookmarks *bookmarks = EV_BOOKMARKS (object)((((EvBookmarks*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ev_bookmarks_get_type()))))))
;
79
80 if (bookmarks->items) {
81 g_list_free_full (bookmarks->items, (GDestroyNotify)ev_bookmark_free);
82 bookmarks->items = NULL((void*)0);
83 }
84
85 if (bookmarks->metadata) {
86 g_object_unref (bookmarks->metadata);
87 bookmarks->metadata = NULL((void*)0);
88 }
89
90 G_OBJECT_CLASS (ev_bookmarks_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ev_bookmarks_parent_class)), (((GType) ((20) << (2
))))))))
->finalize (object);
91}
92
93static void
94ev_bookmarks_init (EvBookmarks *bookmarks)
95{
96}
97
98static void
99ev_bookmarks_set_property (GObject *object,
100 guint prop_id,
101 const GValue *value,
102 GParamSpec *pspec)
103{
104 EvBookmarks *bookmarks = EV_BOOKMARKS (object)((((EvBookmarks*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ev_bookmarks_get_type()))))))
;
105
106 switch (prop_id) {
107 case PROP_METADATA:
108 bookmarks->metadata = (EvMetadata *)g_value_dup_object (value);
109 break;
110 default:
111 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "ev-bookmarks.c", 111, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
112 }
113}
114
115static void
116ev_bookmarks_constructed (GObject *object)
117{
118 EvBookmarks *bookmarks = EV_BOOKMARKS (object)((((EvBookmarks*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ev_bookmarks_get_type()))))))
;
119 gchar *bm_list_str;
120 GVariant *bm_list;
121 GVariantIter iter;
122 GVariant *child;
123 GError *error = NULL((void*)0);
124
125 if (!ev_metadata_get_string (bookmarks->metadata, "bookmarks", &bm_list_str))
126 return;
127
128 if (!bm_list_str || bm_list_str[0] == '\0')
129 return;
130
131 bm_list = g_variant_parse ((const GVariantType *)"a(us)",
132 bm_list_str, NULL((void*)0), NULL((void*)0),
133 &error);
134 if (!bm_list) {
135 g_warning ("Error getting bookmarks: %s\n", error->message);
136 g_error_free (error);
137
138 return;
139 }
140
141 g_variant_iter_init (&iter, bm_list);
142 while ((child = g_variant_iter_next_value (&iter))) {
143 EvBookmark *bm = g_slice_new (EvBookmark)((EvBookmark*) g_slice_alloc (sizeof (EvBookmark)));
144
145 g_variant_get (child, "(us)", &bm->page, &bm->title);
146 if (bm->title && strlen (bm->title) > 0)
147 bookmarks->items = g_list_prepend (bookmarks->items, bm);
148 g_variant_unref (child);
149 }
150 g_variant_unref (bm_list);
151
152 bookmarks->items = g_list_reverse (bookmarks->items);
153}
154
155static void
156ev_bookmarks_class_init (EvBookmarksClass *klass)
157{
158 GObjectClass *gobject_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
159
160 gobject_class->set_property = ev_bookmarks_set_property;
161 gobject_class->finalize = ev_bookmarks_finalize;
162 gobject_class->constructed = ev_bookmarks_constructed;
163
164 g_object_class_install_property (gobject_class,
165 PROP_METADATA,
166 g_param_spec_object ("metadata",
167 "Metadata",
168 "The document metadata",
169 EV_TYPE_METADATA(ev_metadata_get_type()),
170 G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
171 /* Signals */
172 signals[CHANGED] =
173 g_signal_new ("changed",
174 EV_TYPE_BOOKMARKS(ev_bookmarks_get_type()),
175 G_SIGNAL_RUN_LAST,
176 G_STRUCT_OFFSET (EvBookmarksClass, changed)((glong) __builtin_offsetof(EvBookmarksClass, changed)),
177 NULL((void*)0), NULL((void*)0),
178 g_cclosure_marshal_VOID__VOID,
179 G_TYPE_NONE((GType) ((1) << (2))), 0);
180}
181
182EvBookmarks *
183ev_bookmarks_new (EvMetadata *metadata)
184{
185 g_return_val_if_fail (EV_IS_METADATA (metadata), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((metadata)); GType __t = ((ev_metadata_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 (((gchar*) 0), ((const char*
) (__func__)), "EV_IS_METADATA (metadata)"); return (((void*)
0)); } } while (0)
;
186
187 return EV_BOOKMARKS (g_object_new (EV_TYPE_BOOKMARKS,((((EvBookmarks*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_object_new ((ev_bookmarks_get_type()), "metadata", metadata
, ((void*)0)))), ((ev_bookmarks_get_type()))))))
188 "metadata", metadata, NULL))((((EvBookmarks*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_object_new ((ev_bookmarks_get_type()), "metadata", metadata
, ((void*)0)))), ((ev_bookmarks_get_type()))))))
;
189}
190
191static void
192ev_bookmarks_save (EvBookmarks *bookmarks)
193{
194 GList *l;
195 GVariantBuilder builder;
196 GVariant *bm_list;
197 gchar *bm_list_str;
198
199 if (!bookmarks->items) {
200 ev_metadata_set_string (bookmarks->metadata, "bookmarks", "");
201 return;
202 }
203
204 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY((const GVariantType *) "a*"));
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
205 for (l = bookmarks->items; l; l = g_list_next (l)((l) ? (((GList *)(l))->next) : ((void*)0))) {
206 EvBookmark *bm = (EvBookmark *)l->data;
207
208 g_variant_builder_add (&builder, "(u&s)", bm->page, bm->title);
209 }
210 bm_list = g_variant_builder_end (&builder);
211
212 bm_list_str = g_variant_print (bm_list, FALSE(0));
213 g_variant_unref (bm_list);
214 ev_metadata_set_string (bookmarks->metadata, "bookmarks", bm_list_str);
215 g_free (bm_list_str);
216}
217
218GList *
219ev_bookmarks_get_bookmarks (EvBookmarks *bookmarks)
220{
221 g_return_val_if_fail (EV_IS_BOOKMARKS (bookmarks), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bookmarks)); GType __t = ((ev_bookmarks_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 (((gchar*) 0), ((const char*
) (__func__)), "EV_IS_BOOKMARKS (bookmarks)"); return (((void
*)0)); } } while (0)
;
222
223 return g_list_copy (bookmarks->items);
224}
225
226void
227ev_bookmarks_add (EvBookmarks *bookmarks,
228 EvBookmark *bookmark)
229{
230 EvBookmark *bm;
231
232 g_return_if_fail (EV_IS_BOOKMARKS (bookmarks))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bookmarks)); GType __t = ((ev_bookmarks_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 (((gchar*) 0), ((const char*
) (__func__)), "EV_IS_BOOKMARKS (bookmarks)"); return; } } while
(0)
;
233 g_return_if_fail (bookmark->title != NULL)do { if ((bookmark->title != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "bookmark->title != NULL"
); return; } } while (0)
;
234
235 if (g_list_find_custom (bookmarks->items, bookmark, (GCompareFunc)ev_bookmark_compare))
236 return;
237
238 bm = g_slice_new (EvBookmark)((EvBookmark*) g_slice_alloc (sizeof (EvBookmark)));
239 *bm = *bookmark;
240 bookmarks->items = g_list_append (bookmarks->items, bm);
241 g_signal_emit (bookmarks, signals[CHANGED], 0);
242 ev_bookmarks_save (bookmarks);
243}
244
245void
246ev_bookmarks_delete (EvBookmarks *bookmarks,
247 EvBookmark *bookmark)
248{
249 GList *bm_link;
250
251 g_return_if_fail (EV_IS_BOOKMARKS (bookmarks))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bookmarks)); GType __t = ((ev_bookmarks_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 (((gchar*) 0), ((const char*
) (__func__)), "EV_IS_BOOKMARKS (bookmarks)"); return; } } while
(0)
;
252
253 bm_link = g_list_find_custom (bookmarks->items, bookmark, (GCompareFunc)ev_bookmark_compare);
254 if (!bm_link)
255 return;
256
257 bookmarks->items = g_list_delete_link (bookmarks->items, bm_link);
258 g_signal_emit (bookmarks, signals[CHANGED], 0);
259 ev_bookmarks_save (bookmarks);
260}
261
262void
263ev_bookmarks_update (EvBookmarks *bookmarks,
264 EvBookmark *bookmark)
265{
266 GList *bm_link;
267 EvBookmark *bm;
268
269 g_return_if_fail (EV_IS_BOOKMARKS (bookmarks))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((bookmarks)); GType __t = ((ev_bookmarks_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 (((gchar*) 0), ((const char*
) (__func__)), "EV_IS_BOOKMARKS (bookmarks)"); return; } } while
(0)
;
270 g_return_if_fail (bookmark->title != NULL)do { if ((bookmark->title != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "bookmark->title != NULL"
); return; } } while (0)
;
271
272 bm_link = g_list_find_custom (bookmarks->items, bookmark, (GCompareFunc)ev_bookmark_compare);
273 if (!bm_link)
274 return;
275
276 bm = (EvBookmark *)bm_link->data;
277
278 if (strcmp (bookmark->title, bm->title) == 0)
279 return;
280
281 g_free (bm->title);
282 *bm = *bookmark;
283 g_signal_emit (bookmarks, signals[CHANGED], 0);
284 ev_bookmarks_save (bookmarks);
285}