Bug Summary

File:desktop/cookie_manager.c
Warning:line 856, column 2
Value stored to 'err' is never read

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 cookie_manager.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 pic -pic-level 2 -pic-is-pie -mframe-pointer=none -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=/var/lib/jenkins/workspace/scan-build-netsurf -resource-dir /usr/lib/llvm-14/lib/clang/14.0.6 -I . -I include -I build/Linux-gtk2 -I frontends -I content/handlers -D WITH_JPEG -U WITH_PDF_EXPORT -D LIBICONV_PLUG -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -I /usr/include/x86_64-linux-gnu -D WITH_CURL -D WITH_OPENSSL -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -D UTF8PROC_EXPORTS -D WITH_UTF8PROC -D WITH_WEBP -I /usr/include/libpng16 -D WITH_PNG -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include/ -D WITH_BMP -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -D WITH_GIF -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -D WITH_NS_SVG -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -D WITH_NSSPRITE -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -D WITH_NSPSL -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -D WITH_NSLOG -D NETSURF_UA_FORMAT_STRING="Mozilla/5.0 (%s) NetSurf/%d.%d" -D NETSURF_HOMEPAGE="about:welcome" -D NETSURF_LOG_LEVEL=VERBOSE -D NETSURF_BUILTIN_LOG_FILTER="(level:WARNING || cat:jserrors)" -D NETSURF_BUILTIN_VERBOSE_FILTER="(level:VERBOSE || cat:jserrors)" -D STMTEXPR=1 -I /usr/include/librsvg-2.0 -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/gdk-pixbuf-2.0 -I /usr/include/libpng16 -I /usr/include/x86_64-linux-gnu -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/freetype2 -D WITH_RSVG -I /usr/include/gtk-2.0 -I /usr/lib/x86_64-linux-gnu/gtk-2.0/include -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/atk-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -D gtk -D nsgtk -D G_DISABLE_SINGLE_INCLUDES -D G_DISABLE_DEPRECATED -D GTK_DISABLE_SINGLE_INCLUDES -D GTK_MULTIHEAD_SAFE -D PANGO_DISABLE_DEPRECATED -D GTK_DISABLE_DEPRECATED -D _XOPEN_SOURCE=700 -D _POSIX_C_SOURCE=200809L -D _BSD_SOURCE -D _DEFAULT_SOURCE -D _NETBSD_SOURCE -D GTK_RESPATH="/var/lib/jenkins/artifacts-x86_64-linux-gnu/share/netsurf/:./frontends/gtk/res/" -D WITH_GRESOURCE -D DUK_OPT_HAVE_CUSTOM_H -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.6/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wwrite-strings -Wno-unused-parameter -Wno-unused-but-set-variable -std=c99 -fconst-strings -fdebug-compilation-dir=/var/lib/jenkins/workspace/scan-build-netsurf -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-display-progress -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /var/lib/jenkins/workspace/scan-build-netsurf/clangScanBuildReports/2024-12-27-084849-3370695-1 -x c desktop/cookie_manager.c
1/*
2 * Copyright 2013 Michael Drake <tlsa@netsurf-browser.org>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * \file
21 * Implementation of Cookie Management
22 *
23 * This allows users to view and remove their web cookies.
24 *
25 * \todo the viewing of cookies is pretty basic and it would be good
26 * to apply more processing of the values and perhaps top level domain
27 * suffix highlighting to give a better user information as to how the
28 * cookies interact with the users sessions.
29 *
30 * \todo In addition to removing cookies it might be useful to allow
31 * users to edit them, especially to alter expiry times.
32 */
33
34
35#include <stdlib.h>
36#include <string.h>
37
38#include "utils/messages.h"
39#include "utils/utils.h"
40#include "utils/log.h"
41#include "content/urldb.h"
42
43#include "desktop/cookie_manager.h"
44#include "desktop/treeview.h"
45
46enum cookie_manager_field {
47 COOKIE_M_NAME,
48 COOKIE_M_CONTENT,
49 COOKIE_M_DOMAIN,
50 COOKIE_M_PATH,
51 COOKIE_M_EXPIRES,
52 COOKIE_M_LAST_USED,
53 COOKIE_M_RESTRICTIONS,
54 COOKIE_M_VERSION,
55 COOKIE_M_DOMAIN_FOLDER,
56 COOKIE_M_N_FIELDS
57};
58
59enum cookie_manager_value {
60 COOKIE_M_HTTPS,
61 COOKIE_M_SECURE,
62 COOKIE_M_HTTP,
63 COOKIE_M_NONE,
64 COOKIE_M_NETSCAPE,
65 COOKIE_M_RFC2109,
66 COOKIE_M_RFC2965,
67 COOKIE_M_YES,
68 COOKIE_M_NO,
69 COOKIE_M_N_VALUES
70};
71
72struct cookie_manager_folder {
73 treeview_node *folder;
74 struct treeview_field_data data;
75};
76
77struct cookie_manager_ctx {
78 treeview *tree;
79 struct treeview_field_desc fields[COOKIE_M_N_FIELDS];
80 struct treeview_field_data values[COOKIE_M_N_VALUES];
81 bool_Bool built;
82};
83struct cookie_manager_ctx cm_ctx;
84
85struct cookie_manager_entry {
86 bool_Bool user_delete;
87
88 treeview_node *entry;
89
90 struct treeview_field_data data[COOKIE_M_N_FIELDS - 1];
91};
92
93
94struct treeview_walk_ctx {
95 const char *title;
96 size_t title_len;
97 struct cookie_manager_folder *folder;
98 struct cookie_manager_entry *entry;
99};
100/** Callback for treeview_walk */
101static nserror cookie_manager_walk_cb(void *ctx, void *node_data,
102 enum treeview_node_type type, bool_Bool *abort)
103{
104 struct treeview_walk_ctx *tw = ctx;
105
106 if (type == TREE_NODE_ENTRY) {
107 struct cookie_manager_entry *entry = node_data;
108
109 if (entry->data[COOKIE_M_NAME].value_len == tw->title_len &&
110 strcmp(tw->title,
111 entry->data[COOKIE_M_NAME].value) == 0) {
112 /* Found what we're looking for */
113 tw->entry = entry;
114 *abort = true1;
115 }
116
117 } else if (type == TREE_NODE_FOLDER) {
118 struct cookie_manager_folder *folder = node_data;
119
120 if (folder->data.value_len == tw->title_len &&
121 strcmp(tw->title, folder->data.value) == 0) {
122 /* Found what we're looking for */
123 tw->folder = folder;
124 *abort = true1;
125 }
126 }
127
128 return NSERROR_OK;
129}
130/**
131 * Find a cookie entry in the cookie manager's treeview
132 *
133 * \param root Search root node, or NULL to search from tree's root
134 * \param title ID of the node to look for
135 * \param title_len Byte length of title string
136 * \param found Updated to the matching node's cookie maanger entry
137 * \return NSERROR_OK on success, appropriate error otherwise
138 */
139static nserror cookie_manager_find_entry(treeview_node *root,
140 const char *title, size_t title_len,
141 struct cookie_manager_entry **found)
142{
143 nserror err;
144 struct treeview_walk_ctx tw = {
145 .title = title,
146 .title_len = title_len,
147 .folder = NULL((void*)0),
148 .entry = NULL((void*)0)
149 };
150
151 err = treeview_walk(cm_ctx.tree, root, cookie_manager_walk_cb, NULL((void*)0),
152 &tw, TREE_NODE_ENTRY);
153 if (err != NSERROR_OK)
154 return err;
155
156 *found = tw.entry;
157
158 return NSERROR_OK;
159}
160/**
161 * Find a cookie domain folder in the cookie manager's treeview
162 *
163 * \param root Search root node, or NULL to search from tree's root
164 * \param title ID of the node to look for
165 * \param title_len Byte length of title string
166 * \param found Updated to the matching node's cookie maanger folder
167 * \return NSERROR_OK on success, appropriate error otherwise
168 */
169static nserror cookie_manager_find_folder(treeview_node *root,
170 const char *title, size_t title_len,
171 struct cookie_manager_folder **found)
172{
173 nserror err;
174 struct treeview_walk_ctx tw = {
175 .title = title,
176 .title_len = title_len,
177 .folder = NULL((void*)0),
178 .entry = NULL((void*)0)
179 };
180
181 err = treeview_walk(cm_ctx.tree, root, cookie_manager_walk_cb, NULL((void*)0),
182 &tw, TREE_NODE_FOLDER);
183 if (err != NSERROR_OK)
184 return err;
185
186 *found = tw.folder;
187
188 return NSERROR_OK;
189}
190
191
192/**
193 * Free a cookie manager entry's treeview field data.
194 *
195 * \param e Cookie manager entry to free data from
196 */
197static void cookie_manager_free_treeview_field_data(
198 struct cookie_manager_entry *e)
199{
200 /* Eww */
201 free((void *)e->data[COOKIE_M_NAME].value);
202 free((void *)e->data[COOKIE_M_CONTENT].value);
203 free((void *)e->data[COOKIE_M_DOMAIN].value);
204 free((void *)e->data[COOKIE_M_PATH].value);
205 free((void *)e->data[COOKIE_M_EXPIRES].value);
206 free((void *)e->data[COOKIE_M_LAST_USED].value);
207}
208
209
210/**
211 * Build a cookie manager treeview field from given text
212 *
213 * \param field Cookie manager treeview field to build
214 * \param data Cookie manager entry field data to set
215 * \param value Text to set in field, ownership yielded
216 * \return NSERROR_OK on success, appropriate error otherwise
217 */
218static inline nserror
219cookie_manager_field_builder(enum cookie_manager_field field,
220 struct treeview_field_data *data,
221 const char *value)
222{
223 data->field = cm_ctx.fields[field].field;
224 data->value = value;
225 data->value_len = (value != NULL((void*)0)) ? strlen(value) : 0;
226
227 return NSERROR_OK;
228}
229
230/**
231 * Build a cookie manager treeview field from given time
232 *
233 * The time should be converted to text in the users locacle
234 *
235 * \param field Cookie manager treeview field to build
236 * \param fdata Cookie manager entry field data to set
237 * \param value Time to show in field
238 * \return NSERROR_OK on success, appropriate error otherwise
239 */
240static inline nserror
241cookie_manager_field_builder_time(enum cookie_manager_field field,
242 struct treeview_field_data *fdata,
243 const time_t *value)
244{
245 struct tm *ftime;
246
247 fdata->field = cm_ctx.fields[field].field;
248 fdata->value = NULL((void*)0);
249 fdata->value_len = 0;
250
251 if ((ftime = localtime(value)) != NULL((void*)0)) {
252 const size_t vsize = 256;
253 char *value = malloc(vsize);
254 if (value != NULL((void*)0)) {
255 fdata->value = value;
256 fdata->value_len = strftime(value, vsize,
257 "%a %b %e %H:%M:%S %Y", ftime);
258 }
259 }
260
261 return NSERROR_OK;
262}
263
264
265/**
266 * Set a cookie manager entry's data from the cookie_data.
267 *
268 * \param e Cookie manager entry to set up
269 * \param data Data associated with entry's cookie
270 * \return NSERROR_OK on success, appropriate error otherwise
271 */
272static nserror
273cookie_manager_set_treeview_field_data(struct cookie_manager_entry *e,
274 const struct cookie_data *data)
275{
276 assert(e != NULL)((e != ((void*)0)) ? (void) (0) : __assert_fail ("e != NULL",
"desktop/cookie_manager.c", 276, __extension__ __PRETTY_FUNCTION__
))
;
277 assert(data != NULL)((data != ((void*)0)) ? (void) (0) : __assert_fail ("data != NULL"
, "desktop/cookie_manager.c", 277, __extension__ __PRETTY_FUNCTION__
))
;
278
279 /* Set the fields up */
280 cookie_manager_field_builder(COOKIE_M_NAME,
281 &e->data[COOKIE_M_NAME], strdup(data->name));
282 cookie_manager_field_builder(COOKIE_M_CONTENT,
283 &e->data[COOKIE_M_CONTENT], strdup(data->value));
284 cookie_manager_field_builder(COOKIE_M_DOMAIN,
285 &e->data[COOKIE_M_DOMAIN], strdup(data->domain));
286 cookie_manager_field_builder(COOKIE_M_PATH,
287 &e->data[COOKIE_M_PATH], strdup(data->path));
288
289 /* Set the Expires date field */
290 if (data->expires == -1) {
291 cookie_manager_field_builder(COOKIE_M_EXPIRES,
292 &e->data[COOKIE_M_EXPIRES],
293 strdup(messages_get("CookieManagerSession")));
294 } else {
295 cookie_manager_field_builder_time(COOKIE_M_EXPIRES,
296 &e->data[COOKIE_M_EXPIRES], &data->expires);
297 }
298
299 /* Set the Last used date field */
300 cookie_manager_field_builder_time(COOKIE_M_LAST_USED,
301 &e->data[COOKIE_M_LAST_USED], &data->last_used);
302
303 /* Set the Restrictions text */
304 if (data->secure && data->http_only) {
305 e->data[COOKIE_M_RESTRICTIONS] = cm_ctx.values[COOKIE_M_HTTPS];
306 } else if (data->secure) {
307 e->data[COOKIE_M_RESTRICTIONS] = cm_ctx.values[COOKIE_M_SECURE];
308 } else if (data->http_only) {
309 e->data[COOKIE_M_RESTRICTIONS] = cm_ctx.values[COOKIE_M_HTTP];
310 } else {
311 e->data[COOKIE_M_RESTRICTIONS] = cm_ctx.values[COOKIE_M_NONE];
312 }
313
314 /* Set the Version text */
315 switch (data->version) {
316 case COOKIE_NETSCAPE:
317 e->data[COOKIE_M_VERSION] = cm_ctx.values[COOKIE_M_NETSCAPE];
318 break;
319
320 case COOKIE_RFC2109:
321 e->data[COOKIE_M_VERSION] = cm_ctx.values[COOKIE_M_RFC2109];
322 break;
323
324 case COOKIE_RFC2965:
325 e->data[COOKIE_M_VERSION] = cm_ctx.values[COOKIE_M_RFC2965];
326 break;
327 }
328
329 return NSERROR_OK;
330}
331
332
333/**
334 * Creates an empty tree entry for a cookie, and links it into the tree.
335 *
336 * All information is copied from the cookie_data, and as such can
337 * be edited and should be freed.
338 *
339 * \param parent the node to link to
340 * \param data the cookie data to use
341 * \return NSERROR_OK on success, appropriate error otherwise
342 */
343static nserror cookie_manager_create_cookie_node(
344 struct cookie_manager_folder *parent,
345 const struct cookie_data *data)
346{
347 nserror err;
348 struct cookie_manager_entry *cookie;
349
350 /* Create new cookie manager entry */
351 cookie = malloc(sizeof(struct cookie_manager_entry));
352 if (cookie == NULL((void*)0)) {
353 return NSERROR_NOMEM;
354 }
355
356 cookie->user_delete = false0;
357
358 err = cookie_manager_set_treeview_field_data(cookie, data);
359 if (err != NSERROR_OK) {
360 free(cookie);
361 return err;
362 }
363
364 err = treeview_create_node_entry(cm_ctx.tree,
365 &(cookie->entry),
366 parent->folder,
367 TREE_REL_FIRST_CHILD,
368 cookie->data,
369 cookie,
370 cm_ctx.built ? TREE_OPTION_NONE :
371 TREE_OPTION_SUPPRESS_RESIZE |
372 TREE_OPTION_SUPPRESS_REDRAW);
373 if (err != NSERROR_OK) {
374 cookie_manager_free_treeview_field_data(cookie);
375 free(cookie);
376 return err;
377 }
378
379 return NSERROR_OK;
380}
381
382
383/**
384 * Updates a cookie manager entry for updated cookie_data.
385 *
386 * All information is copied from the cookie_data, and as such can
387 * be edited and should be freed.
388 *
389 * \param e the entry to update
390 * \param data the cookie data to use
391 * \return NSERROR_OK on success, appropriate error otherwise
392 */
393static nserror cookie_manager_update_cookie_node(
394 struct cookie_manager_entry *e,
395 const struct cookie_data *data)
396{
397 nserror err;
398
399 assert(e != NULL)((e != ((void*)0)) ? (void) (0) : __assert_fail ("e != NULL",
"desktop/cookie_manager.c", 399, __extension__ __PRETTY_FUNCTION__
))
;
400
401 /* Reset to defaults */
402 e->user_delete = false0;
403 cookie_manager_free_treeview_field_data(e);
404
405 /* Set new field values from the cookie_data */
406 err = cookie_manager_set_treeview_field_data(e, data);
407 if (err != NSERROR_OK) {
408 return err;
409 }
410
411 /* Update the treeview */
412 err = treeview_update_node_entry(cm_ctx.tree, e->entry, e->data, e);
413 if (err != NSERROR_OK) {
414 return err;
415 }
416
417 return NSERROR_OK;
418}
419
420
421/**
422 * Creates an empty tree folder for a cookie domain, and links it into the tree.
423 *
424 * All information is copied from the cookie_data, and as such can
425 * be edited and should be freed.
426 *
427 * \param folder updated to the new folder
428 * \param data the cookie data to use
429 * \return NSERROR_OK on success, appropriate error otherwise
430 */
431static nserror cookie_manager_create_domain_folder(
432 struct cookie_manager_folder **folder,
433 const struct cookie_data *data)
434{
435 nserror err;
436 struct cookie_manager_folder *f;
437
438 /* Create new cookie manager entry */
439 f = malloc(sizeof(struct cookie_manager_folder));
440 if (f == NULL((void*)0)) {
441 return NSERROR_NOMEM;
442 }
443
444 f->data.field = cm_ctx.fields[COOKIE_M_N_FIELDS - 1].field;
445 f->data.value = strdup(data->domain);
446 f->data.value_len = (f->data.value != NULL((void*)0)) ?
447 strlen(data->domain) : 0;
448
449 err = treeview_create_node_folder(cm_ctx.tree, &(f->folder),
450 NULL((void*)0), TREE_REL_FIRST_CHILD, &f->data, f,
451 cm_ctx.built ? TREE_OPTION_NONE :
452 TREE_OPTION_SUPPRESS_RESIZE |
453 TREE_OPTION_SUPPRESS_REDRAW);
454 if (err != NSERROR_OK) {
455 free((void *)f->data.value);
456 free(f);
457 return err;
458 }
459
460 *folder = f;
461
462 return NSERROR_OK;
463}
464
465
466/* exported interface documented in cookie_manager.h */
467bool_Bool cookie_manager_add(const struct cookie_data *data)
468{
469 struct cookie_manager_folder *parent = NULL((void*)0);
470 struct cookie_manager_entry *cookie = NULL((void*)0);
471 nserror err;
472
473 assert(data != NULL)((data != ((void*)0)) ? (void) (0) : __assert_fail ("data != NULL"
, "desktop/cookie_manager.c", 473, __extension__ __PRETTY_FUNCTION__
))
;
474
475 /* If we don't have a cookie manager at the moment, just return true */
476 if (cm_ctx.tree == NULL((void*)0))
477 return true1;
478
479 err = cookie_manager_find_folder(NULL((void*)0), data->domain,
480 strlen(data->domain), &parent);
481 if (err != NSERROR_OK) {
482 return false0;
483 }
484
485 if (parent == NULL((void*)0)) {
486 /* Need to create domain directory */
487 err = cookie_manager_create_domain_folder(&parent, data);
488 if (err != NSERROR_OK || parent == NULL((void*)0))
489 return false0;
490 }
491
492 /* Create cookie node */
493 err = cookie_manager_find_entry(parent->folder, data->name,
494 strlen(data->name), &cookie);
495 if (err != NSERROR_OK)
496 return false0;
497
498 if (cookie == NULL((void*)0)) {
499 err = cookie_manager_create_cookie_node(parent, data);
500 } else {
501 err = cookie_manager_update_cookie_node(cookie, data);
502 }
503 if (err != NSERROR_OK)
504 return false0;
505
506 return true1;
507}
508
509
510/* exported interface documented in cookie_manager.h */
511void cookie_manager_remove(const struct cookie_data *data)
512{
513 struct cookie_manager_folder *parent = NULL((void*)0);
514 struct cookie_manager_entry *cookie = NULL((void*)0);
515 nserror err;
516
517 assert(data != NULL)((data != ((void*)0)) ? (void) (0) : __assert_fail ("data != NULL"
, "desktop/cookie_manager.c", 517, __extension__ __PRETTY_FUNCTION__
))
;
518
519 /* If we don't have a cookie manager at the moment, just return */
520 if (cm_ctx.tree == NULL((void*)0))
521 return;
522
523 err = cookie_manager_find_folder(NULL((void*)0), data->domain,
524 strlen(data->domain), &parent);
525 if (err != NSERROR_OK || parent == NULL((void*)0)) {
526 /* Nothing to delete */
527 return;
528 }
529
530 err = cookie_manager_find_entry(parent->folder, data->name,
531 strlen(data->name), &cookie);
532 if (err != NSERROR_OK || cookie == NULL((void*)0)) {
533 /* Nothing to delete */
534 return;
535 }
536
537 /* Delete the node */
538 treeview_delete_node(cm_ctx.tree, cookie->entry, TREE_OPTION_NONE);
539}
540
541
542/* exported interface documented in cookie_manager.h */
543nserror cookie_manager_set_search_string(
544 const char *string)
545{
546 /* If we don't have a cookie manager at the moment, just return */
547 if (cm_ctx.tree == NULL((void*)0)) {
548 return NSERROR_NOT_FOUND;
549 }
550
551 return treeview_set_search_string(cm_ctx.tree, string);
552}
553
554
555/**
556 * Initialise the treeview entry feilds
557 *
558 * \return true on success, false on memory exhaustion
559 */
560static nserror cookie_manager_init_entry_fields(void)
561{
562 int i;
563 const char *label;
564
565 for (i = 0; i < COOKIE_M_N_FIELDS; i++)
566 cm_ctx.fields[i].field = NULL((void*)0);
567
568 cm_ctx.fields[COOKIE_M_NAME].flags = TREE_FLAG_DEFAULT;
569 label = "TreeviewLabelName";
570 label = messages_get(label);
571 if (lwc_intern_string(label, strlen(label),
572 &cm_ctx.fields[COOKIE_M_NAME].field) !=
573 lwc_error_ok) {
574 goto error;
575 }
576
577 cm_ctx.fields[COOKIE_M_CONTENT].flags = TREE_FLAG_SHOW_NAME;
578 label = "TreeviewLabelContent";
579 label = messages_get(label);
580 if (lwc_intern_string(label, strlen(label),
581 &cm_ctx.fields[COOKIE_M_CONTENT].field) !=
582 lwc_error_ok) {
583 goto error;
584 }
585
586 cm_ctx.fields[COOKIE_M_DOMAIN].flags =
587 TREE_FLAG_SHOW_NAME |
588 TREE_FLAG_SEARCHABLE;
589 label = "TreeviewLabelDomain";
590 label = messages_get(label);
591 if (lwc_intern_string(label, strlen(label),
592 &cm_ctx.fields[COOKIE_M_DOMAIN].field) !=
593 lwc_error_ok) {
594 goto error;
595 }
596
597 cm_ctx.fields[COOKIE_M_PATH].flags = TREE_FLAG_SHOW_NAME;
598 label = "TreeviewLabelPath";
599 label = messages_get(label);
600 if (lwc_intern_string(label, strlen(label),
601 &cm_ctx.fields[COOKIE_M_PATH].field) !=
602 lwc_error_ok) {
603 goto error;
604 }
605
606 cm_ctx.fields[COOKIE_M_EXPIRES].flags = TREE_FLAG_SHOW_NAME;
607 label = "TreeviewLabelExpires";
608 label = messages_get(label);
609 if (lwc_intern_string(label, strlen(label),
610 &cm_ctx.fields[COOKIE_M_EXPIRES].field) !=
611 lwc_error_ok) {
612 goto error;
613 }
614
615 cm_ctx.fields[COOKIE_M_LAST_USED].flags = TREE_FLAG_SHOW_NAME;
616 label = "TreeviewLabelLastUsed";
617 label = messages_get(label);
618 if (lwc_intern_string(label, strlen(label),
619 &cm_ctx.fields[COOKIE_M_LAST_USED].field) !=
620 lwc_error_ok) {
621 goto error;
622 }
623
624 cm_ctx.fields[COOKIE_M_RESTRICTIONS].flags = TREE_FLAG_SHOW_NAME;
625 label = "TreeviewLabelRestrictions";
626 label = messages_get(label);
627 if (lwc_intern_string(label, strlen(label),
628 &cm_ctx.fields[COOKIE_M_RESTRICTIONS].field) !=
629 lwc_error_ok) {
630 goto error;
631 }
632
633 cm_ctx.fields[COOKIE_M_VERSION].flags = TREE_FLAG_SHOW_NAME;
634 label = "TreeviewLabelVersion";
635 label = messages_get(label);
636 if (lwc_intern_string(label, strlen(label),
637 &cm_ctx.fields[COOKIE_M_VERSION].field) !=
638 lwc_error_ok) {
639 goto error;
640 }
641
642 cm_ctx.fields[COOKIE_M_DOMAIN_FOLDER].flags = TREE_FLAG_DEFAULT;
643 label = "TreeviewLabelDomainFolder";
644 label = messages_get(label);
645 if (lwc_intern_string(label, strlen(label),
646 &cm_ctx.fields[COOKIE_M_DOMAIN_FOLDER].field) !=
647 lwc_error_ok) {
648 return false0;
649 }
650
651 return NSERROR_OK;
652
653error:
654 for (i = 0; i < COOKIE_M_N_FIELDS; i++)
655 if (cm_ctx.fields[i].field != NULL((void*)0))
656 lwc_string_unref(cm_ctx.fields[i].field){ lwc_string *__lwc_s = (cm_ctx.fields[i].field); ((__lwc_s !=
((void*)0)) ? (void) (0) : __assert_fail ("__lwc_s != NULL",
"desktop/cookie_manager.c", 656, __extension__ __PRETTY_FUNCTION__
)); __lwc_s->refcnt--; if ((__lwc_s->refcnt == 0) || ((
__lwc_s->refcnt == 1) && (__lwc_s->insensitive ==
__lwc_s))) lwc_string_destroy(__lwc_s); }
;
657
658 return NSERROR_UNKNOWN;
659}
660
661
662
663/**
664 * Initialise the common entry values
665 *
666 * \return true on success, false on memory exhaustion
667 */
668static nserror cookie_manager_init_common_values(void)
669{
670 const char *temp;
671
672 /* Set the Restrictions text */
673 temp = messages_get("CookieManagerHTTPS");
674 cookie_manager_field_builder(COOKIE_M_RESTRICTIONS,
675 &cm_ctx.values[COOKIE_M_HTTPS], strdup(temp));
676
677 temp = messages_get("CookieManagerSecure");
678 cookie_manager_field_builder(COOKIE_M_RESTRICTIONS,
679 &cm_ctx.values[COOKIE_M_SECURE], strdup(temp));
680
681 temp = messages_get("CookieManagerHTTP");
682 cookie_manager_field_builder(COOKIE_M_RESTRICTIONS,
683 &cm_ctx.values[COOKIE_M_HTTP], strdup(temp));
684
685 temp = messages_get("None");
686 cookie_manager_field_builder(COOKIE_M_RESTRICTIONS,
687 &cm_ctx.values[COOKIE_M_NONE], strdup(temp));
688
689 /* Set the Cookie version text */
690 assert(COOKIE_NETSCAPE == 0)((COOKIE_NETSCAPE == 0) ? (void) (0) : __assert_fail ("COOKIE_NETSCAPE == 0"
, "desktop/cookie_manager.c", 690, __extension__ __PRETTY_FUNCTION__
))
;
691 temp = messages_get("TreeVersion0");
692 cookie_manager_field_builder(COOKIE_M_VERSION,
693 &cm_ctx.values[COOKIE_M_NETSCAPE], strdup(temp));
694
695 assert(COOKIE_RFC2109 == 1)((COOKIE_RFC2109 == 1) ? (void) (0) : __assert_fail ("COOKIE_RFC2109 == 1"
, "desktop/cookie_manager.c", 695, __extension__ __PRETTY_FUNCTION__
))
;
696 temp = messages_get("TreeVersion1");
697 cookie_manager_field_builder(COOKIE_M_VERSION,
698 &cm_ctx.values[COOKIE_M_RFC2109], strdup(temp));
699
700 assert(COOKIE_RFC2965 == 2)((COOKIE_RFC2965 == 2) ? (void) (0) : __assert_fail ("COOKIE_RFC2965 == 2"
, "desktop/cookie_manager.c", 700, __extension__ __PRETTY_FUNCTION__
))
;
701 temp = messages_get("TreeVersion2");
702 cookie_manager_field_builder(COOKIE_M_VERSION,
703 &cm_ctx.values[COOKIE_M_RFC2965], strdup(temp));
704
705 return NSERROR_OK;
706}
707
708
709/**
710 * Delete cookie manager entries (and optionally delete from urldb)
711 *
712 * \param e Cookie manager entry to delete.
713 */
714static void cookie_manager_delete_entry(struct cookie_manager_entry *e)
715{
716 const char *domain;
717 const char *path;
718 const char *name;
719
720 if (e->user_delete) {
721 /* Delete the cookie from URLdb */
722 domain = e->data[COOKIE_M_DOMAIN].value;
723 path = e->data[COOKIE_M_PATH].value;
724 name = e->data[COOKIE_M_NAME].value;
725
726 if ((domain != NULL((void*)0)) && (path != NULL((void*)0)) && (name != NULL((void*)0))) {
727
728 urldb_delete_cookie(domain, path, name);
729 } else {
730 NSLOG(netsurf, INFO,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static
nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf
, NSLOG_LEVEL_INFO, "desktop/cookie_manager.c", sizeof("desktop/cookie_manager.c"
) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 731
, }; nslog__log(&_nslog_ctx, "Delete cookie fail: ""need domain, path, and name."
); } } while(0)
731 "Delete cookie fail: ""need domain, path, and name.")do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static
nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf
, NSLOG_LEVEL_INFO, "desktop/cookie_manager.c", sizeof("desktop/cookie_manager.c"
) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 731
, }; nslog__log(&_nslog_ctx, "Delete cookie fail: ""need domain, path, and name."
); } } while(0)
;
732 }
733 }
734
735 /* Delete the cookie manager entry */
736 cookie_manager_free_treeview_field_data(e);
737 free(e);
738}
739
740
741static nserror cookie_manager_tree_node_folder_cb(
742 struct treeview_node_msg msg, void *data)
743{
744 struct cookie_manager_folder *f = data;
745
746 switch (msg.msg) {
747 case TREE_MSG_NODE_DELETE:
748 free(f);
749 break;
750
751 case TREE_MSG_NODE_EDIT:
752 break;
753
754 case TREE_MSG_NODE_LAUNCH:
755 break;
756 }
757
758 return NSERROR_OK;
759}
760
761
762static nserror cookie_manager_tree_node_entry_cb(
763 struct treeview_node_msg msg, void *data)
764{
765 struct cookie_manager_entry *e = data;
766
767 switch (msg.msg) {
768 case TREE_MSG_NODE_DELETE:
769 e->entry = NULL((void*)0);
770 e->user_delete = msg.data.delete.user;
771 cookie_manager_delete_entry(e);
772 break;
773
774 case TREE_MSG_NODE_EDIT:
775 break;
776
777 case TREE_MSG_NODE_LAUNCH:
778 break;
779 }
780 return NSERROR_OK;
781}
782
783
784struct treeview_callback_table cm_tree_cb_t = {
785 .folder = cookie_manager_tree_node_folder_cb,
786 .entry = cookie_manager_tree_node_entry_cb
787};
788
789
790/* Exported interface, documented in cookie_manager.h */
791nserror cookie_manager_init(void *core_window_handle)
792{
793 nserror err;
794
795 err = treeview_init();
796 if (err != NSERROR_OK) {
797 return err;
798 }
799
800 NSLOG(netsurf, INFO, "Generating cookie manager data")do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static
nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf
, NSLOG_LEVEL_INFO, "desktop/cookie_manager.c", sizeof("desktop/cookie_manager.c"
) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 800
, }; nslog__log(&_nslog_ctx, "Generating cookie manager data"
); } } while(0)
;
801
802 /* Init. cookie manager treeview entry fields */
803 err = cookie_manager_init_entry_fields();
804 if (err != NSERROR_OK) {
805 cm_ctx.tree = NULL((void*)0);
806 return err;
807 }
808
809 /* Init. common treeview field values */
810 err = cookie_manager_init_common_values();
811 if (err != NSERROR_OK) {
812 cm_ctx.tree = NULL((void*)0);
813 return err;
814 }
815
816 /* Create the cookie manager treeview */
817 err = treeview_create(&cm_ctx.tree, &cm_tree_cb_t,
818 COOKIE_M_N_FIELDS, cm_ctx.fields,
819 core_window_handle,
820 TREEVIEW_NO_MOVES |
821 TREEVIEW_DEL_EMPTY_DIRS |
822 TREEVIEW_SEARCHABLE);
823 if (err != NSERROR_OK) {
824 cm_ctx.tree = NULL((void*)0);
825 return err;
826 }
827
828 /* Load the cookies */
829 urldb_iterate_cookies(cookie_manager_add);
830
831 /* Cookie manager is built
832 * We suppress the treeview height callback on entry insertion before
833 * the treeview is built. */
834 cm_ctx.built = true1;
835
836 /* Inform client of window height */
837 treeview_get_height(cm_ctx.tree);
838
839 NSLOG(netsurf, INFO, "Generated cookie manager data")do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static
nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf
, NSLOG_LEVEL_INFO, "desktop/cookie_manager.c", sizeof("desktop/cookie_manager.c"
) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 839
, }; nslog__log(&_nslog_ctx, "Generated cookie manager data"
); } } while(0)
;
840
841 return NSERROR_OK;
842}
843
844
845/* Exported interface, documented in cookie_manager.h */
846nserror cookie_manager_fini(void)
847{
848 int i;
849 nserror err;
850
851 NSLOG(netsurf, INFO, "Finalising cookie manager")do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static
nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf
, NSLOG_LEVEL_INFO, "desktop/cookie_manager.c", sizeof("desktop/cookie_manager.c"
) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 851
, }; nslog__log(&_nslog_ctx, "Finalising cookie manager")
; } } while(0)
;
852
853 cm_ctx.built = false0;
854
855 /* Destroy the cookie manager treeview */
856 err = treeview_destroy(cm_ctx.tree);
Value stored to 'err' is never read
857 cm_ctx.tree = NULL((void*)0);
858
859 /* Free cookie manager treeview entry fields */
860 for (i = 0; i < COOKIE_M_N_FIELDS; i++)
861 if (cm_ctx.fields[i].field != NULL((void*)0))
862 lwc_string_unref(cm_ctx.fields[i].field){ lwc_string *__lwc_s = (cm_ctx.fields[i].field); ((__lwc_s !=
((void*)0)) ? (void) (0) : __assert_fail ("__lwc_s != NULL",
"desktop/cookie_manager.c", 862, __extension__ __PRETTY_FUNCTION__
)); __lwc_s->refcnt--; if ((__lwc_s->refcnt == 0) || ((
__lwc_s->refcnt == 1) && (__lwc_s->insensitive ==
__lwc_s))) lwc_string_destroy(__lwc_s); }
;
863
864 /* Free cookie manager treeview common entry values */
865 for (i = 0; i < COOKIE_M_N_VALUES; i++)
866 if (cm_ctx.values[i].value != NULL((void*)0))
867 free((void *) cm_ctx.values[i].value);
868
869 err = treeview_fini();
870 if (err != NSERROR_OK) {
871 return err;
872 }
873
874 NSLOG(netsurf, INFO, "Finalised cookie manager")do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static
nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf
, NSLOG_LEVEL_INFO, "desktop/cookie_manager.c", sizeof("desktop/cookie_manager.c"
) - 1, __PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, 874
, }; nslog__log(&_nslog_ctx, "Finalised cookie manager");
} } while(0)
;
875
876 return err;
877}
878
879
880/* Exported interface, documented in cookie_manager.h */
881void cookie_manager_redraw(int x, int y, struct rect *clip,
882 const struct redraw_context *ctx)
883{
884 treeview_redraw(cm_ctx.tree, x, y, clip, ctx);
885}
886
887
888/* Exported interface, documented in cookie_manager.h */
889void cookie_manager_mouse_action(enum browser_mouse_state mouse, int x, int y)
890{
891 treeview_mouse_action(cm_ctx.tree, mouse, x, y);
892}
893
894
895/* Exported interface, documented in cookie_manager.h */
896bool_Bool cookie_manager_keypress(uint32_t key)
897{
898 return treeview_keypress(cm_ctx.tree, key);
899}
900
901
902/* Exported interface, documented in cookie_manager.h */
903bool_Bool cookie_manager_has_selection(void)
904{
905 return treeview_has_selection(cm_ctx.tree);
906}
907
908
909/* Exported interface, documented in cookie_manager.h */
910nserror cookie_manager_expand(bool_Bool only_folders)
911{
912 return treeview_expand(cm_ctx.tree, only_folders);
913}
914
915
916/* Exported interface, documented in cookie_manager.h */
917nserror cookie_manager_contract(bool_Bool all)
918{
919 return treeview_contract(cm_ctx.tree, all);
920}
921