From 16ce2e9516676e00c0f441a04c3305614de4d32a Mon Sep 17 00:00:00 2001 From: Christian Dywan Date: Mon, 20 Sep 2010 23:33:08 +0200 Subject: [PATCH] Write cookies to a temporary file first, to be safe It may happen that we are running out of space in the middle of writing the file, and fopen deleted it already. --- katze/katze-http-cookies.c | 41 ++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/katze/katze-http-cookies.c b/katze/katze-http-cookies.c index c66ee66c..c52f7886 100644 --- a/katze/katze-http-cookies.c +++ b/katze/katze-http-cookies.c @@ -16,9 +16,13 @@ #include "katze-http-cookies.h" #include +#ifdef HAVE_UNISTD_H + #include +#endif #include #include #include +#include struct _KatzeHttpCookies { @@ -145,12 +149,12 @@ cookie_jar_load (SoupCookieJar* jar, Copyright (C) 2008 Xan Lopez Copyright (C) 2008 Dan Winship Copied from libSoup 2.24, coding style preserved */ -static void +static gboolean write_cookie (FILE *out, SoupCookie *cookie) { fseek (out, 0, SEEK_END); - fprintf (out, "%s%s\t%s\t%s\t%s\t%lu\t%s\t%s\n", + if (fprintf (out, "%s%s\t%s\t%s\t%s\t%lu\t%s\t%s\n", cookie->http_only ? "#HttpOnly_" : "", cookie->domain, *cookie->domain == '.' ? "TRUE" : "FALSE", @@ -158,7 +162,9 @@ write_cookie (FILE *out, SoupCookie *cookie) cookie->secure ? "TRUE" : "FALSE", (gulong)soup_date_to_time_t (cookie->expires), cookie->name, - cookie->value); + cookie->value) < 0) + return FALSE; + return TRUE; } /* Cookie jar saving to Mozilla format @@ -170,18 +176,21 @@ delete_cookie (const char *filename, SoupCookie *cookie) { char *contents = NULL, *line, *p; gsize length = 0; + gint fn = 0; FILE *f; + gchar* temporary_filename = NULL; SoupCookie *c; time_t now = time (NULL); if (!g_file_get_contents (filename, &contents, &length, NULL)) return; - f = fopen (filename, "w"); - if (!f) { - g_free (contents); - return; - } + fn = g_file_open_tmp (NULL, &temporary_filename, NULL); + if (fn == -1) + goto failed; + f = fopen (temporary_filename, "w"); + if (!f) + goto failed; line = contents; for (p = contents; *p; p++) { @@ -200,12 +209,24 @@ delete_cookie (const char *filename, SoupCookie *cookie) c = parse_cookie (line, now); if (c) { if (!soup_cookie_equal (cookie, c)) - write_cookie (f, c); + if (!write_cookie (f, c)) + goto failed; soup_cookie_free (c); } + if (!fclose (f)) + goto failed; + g_free (contents); - fclose (f); + close (fn); + g_rename (temporary_filename, filename); + g_free (temporary_filename); + return; +failed: + g_free (contents); + close (fn); + g_unlink (temporary_filename); + g_free (temporary_filename); } /* Cookie jar saving to Mozilla format