| File: | shell/ev-bookmarks.c |
| Warning: | line 131, column 36 Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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 | |
| 27 | enum { |
| 28 | PROP_0, |
| 29 | PROP_METADATA |
| 30 | }; |
| 31 | |
| 32 | enum { |
| 33 | CHANGED, |
| 34 | N_SIGNALS |
| 35 | }; |
| 36 | |
| 37 | struct _EvBookmarks { |
| 38 | GObject base; |
| 39 | |
| 40 | EvMetadata *metadata; |
| 41 | GList *items; |
| 42 | }; |
| 43 | |
| 44 | struct _EvBookmarksClass { |
| 45 | GObjectClass base_class; |
| 46 | |
| 47 | void (*changed) (EvBookmarks *bookmarks); |
| 48 | }; |
| 49 | |
| 50 | G_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 | |
| 52 | static guint signals[N_SIGNALS]; |
| 53 | |
| 54 | static gint |
| 55 | ev_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 | |
| 65 | static void |
| 66 | ev_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 | |
| 75 | static void |
| 76 | ev_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 | |
| 93 | static void |
| 94 | ev_bookmarks_init (EvBookmarks *bookmarks) |
| 95 | { |
| 96 | } |
| 97 | |
| 98 | static void |
| 99 | ev_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 | |
| 115 | static void |
| 116 | ev_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)", |
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption | |
| 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 | |
| 155 | static void |
| 156 | ev_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 | |
| 182 | EvBookmarks * |
| 183 | ev_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 | |
| 191 | static void |
| 192 | ev_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*")); |
| 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 | |
| 218 | GList * |
| 219 | ev_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 | |
| 226 | void |
| 227 | ev_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 | |
| 245 | void |
| 246 | ev_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 | |
| 262 | void |
| 263 | ev_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 | } |