From dcad99c98616a6031ddfde313c920339e4012378 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 29 Apr 2016 15:41:10 +0200 Subject: [PATCH] gpg: Factor some code code out of tofu.c * g10/tofu.c (string_to_long): New. (string_to_ulong): New. (get_single_unsigned_long_cb): Replace strtol/strtoul by new function. (get_single_long_cb): Ditto. (signature_stats_collect_cb): Ditto. (get_policy): Ditto. (show_statistics): Ditto. Uese es_free instead of free. -- There is one minor semantic change: We now accept "nnn.0" always. The old code did not checked for ".0: in show_statistics. Signed-off-by: Werner Koch --- g10/tofu.c | 164 ++++++++++++++++++++++++++--------------------------- 1 file changed, 82 insertions(+), 82 deletions(-) diff --git a/g10/tofu.c b/g10/tofu.c index a24c52ee6..e3218b9a2 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -1,5 +1,5 @@ /* tofu.c - TOFU trust model. - * Copyright (C) 2015 g10 Code GmbH + * Copyright (C) 2015, 2016 g10 Code GmbH * * This file is part of GnuPG. * @@ -398,7 +398,66 @@ tofu_end_batch_update (void) end_transaction (db, 1); } } + + + +/* Wrapper around strtol which prints a warning in case of a + * conversion error. On success the converted value is stored at + * R_VALUE and 0 is returned; on error FALLBACK is stored at R_VALUE + * and an error code is returned. */ +static gpg_error_t +string_to_long (long *r_value, const char *string, long fallback, int line) +{ + gpg_error_t err; + char *tail = NULL; + + gpg_err_set_errno (0); + *r_value = strtol (string, &tail, 0); + if (errno || !(!strcmp (tail, ".0") || !*tail)) + { + err = errno? gpg_error_from_errno (errno) : gpg_error (GPG_ERR_BAD_DATA); + log_debug ("%s:%d: " + "strtol failed for DB returned string (tail=%.10s): %s\n", + __FILE__, line, tail, gpg_strerror (err)); + *r_value = fallback; + } + else + err = 0; + + return err; +} + + +/* Wrapper around strtoul which prints a warning in case of a + * conversion error. On success the converted value is stored at + * R_VALUE and 0 is returned; on error FALLBACK is stored at R_VALUE + * and an error code is returned. */ +static gpg_error_t +string_to_ulong (unsigned long *r_value, const char *string, + unsigned long fallback, int line) +{ + gpg_error_t err; + char *tail = NULL; + + gpg_err_set_errno (0); + *r_value = strtoul (string, &tail, 0); + if (errno || !(!strcmp (tail, ".0") || !*tail)) + { + err = errno? gpg_error_from_errno (errno) : gpg_error (GPG_ERR_BAD_DATA); + log_debug ("%s:%d: " + "strtoul failed for DB returned string (tail=%.10s): %s\n", + __FILE__, line, tail, gpg_strerror (err)); + *r_value = fallback; + } + else + err = 0; + + return err; +} + + + /* Collect results of a select count (*) ...; style query. Aborts if the argument is not a valid integer (or real of the form X.0). */ static int @@ -406,17 +465,13 @@ get_single_unsigned_long_cb (void *cookie, int argc, char **argv, char **azColName) { unsigned long int *count = cookie; - char *tail = NULL; (void) azColName; log_assert (argc == 1); - errno = 0; - *count = strtoul (argv[0], &tail, 0); - if (errno || ! (strcmp (tail, ".0") == 0 || *tail == '\0')) - /* Abort. */ - return 1; + if (string_to_ulong (count, argv[0], 0, __LINE__)) + return 1; /* Abort. */ return 0; } @@ -1055,17 +1110,14 @@ static int get_single_long_cb (void *cookie, int argc, char **argv, char **azColName) { long *count = cookie; - char *tail = NULL; (void) azColName; log_assert (argc == 1); - errno = 0; - *count = strtol (argv[0], &tail, 0); - if (errno || ! (strcmp (tail, ".0") == 0 || *tail == '\0')) - /* Abort. */ - return 1; + if (string_to_long (count, argv[0], 0, __LINE__)) + return 1; /* Abort. */ + return 0; } @@ -1356,43 +1408,28 @@ signature_stats_collect_cb (void *cookie, int argc, char **argv, char **azColName, sqlite3_stmt *stmt) { struct signature_stats **statsp = cookie; - char *tail; int i = 0; enum tofu_policy policy; long time_ago; unsigned long count; + long along; (void) azColName; (void) stmt; i ++; - tail = NULL; - errno = 0; - policy = strtol (argv[i], &tail, 0); - if (errno || ! (strcmp (tail, ".0") == 0 || *tail == '\0')) - { - /* Abort. */ - log_error ("%s: Error converting %s to an integer (tail = '%s')\n", - __func__, argv[i], tail); - return 1; - } + if (string_to_long (&along, argv[i], 0, __LINE__)) + return 1; /* Abort */ + policy = along; i ++; if (! argv[i]) time_ago = 0; else { - tail = NULL; - errno = 0; - time_ago = strtol (argv[i], &tail, 0); - if (errno || ! (strcmp (tail, ".0") == 0 || *tail == '\0')) - { - /* Abort. */ - log_error ("%s: Error converting %s to an integer (tail = '%s')\n", - __func__, argv[i], tail); - return 1; - } + if (string_to_long (&time_ago, argv[i], 0, __LINE__)) + return 1; /* Abort. */ } i ++; @@ -1402,16 +1439,8 @@ signature_stats_collect_cb (void *cookie, int argc, char **argv, count = 0; else { - tail = NULL; - errno = 0; - count = strtoul (argv[i], &tail, 0); - if (errno || ! (strcmp (tail, ".0") == 0 || *tail == '\0')) - { - /* Abort. */ - log_error ("%s: Error converting %s to an integer (tail = '%s')\n", - __func__, argv[i], tail); - return 1; - } + if (string_to_ulong (&count, argv[i], 0, __LINE__)) + return 1; /* Abort */ } i ++; @@ -1449,8 +1478,8 @@ get_policy (struct dbs *dbs, const char *fingerprint, const char *email, int rc; char *err = NULL; strlist_t strlist = NULL; - char *tail = NULL; enum tofu_policy policy = _tofu_GET_POLICY_ERROR; + long along; db = getdb (dbs, email, DB_EMAIL); if (! db) @@ -1494,15 +1523,14 @@ get_policy (struct dbs *dbs, const char *fingerprint, const char *email, /* The result has the right form. */ - errno = 0; - policy = strtol (strlist->d, &tail, 0); - if (errno || *tail != '\0') + if (string_to_long (&along, strlist->d, 0, __LINE__)) { log_error (_("error reading TOFU database: %s\n"), gpg_strerror (GPG_ERR_BAD_DATA)); print_further_info ("bad value for policy: %s", strlist->d); goto out; } + policy = along; if (! (policy == TOFU_POLICY_AUTO || policy == TOFU_POLICY_GOOD @@ -2347,52 +2375,24 @@ show_statistics (struct dbs *dbs, const char *fingerprint, fingerprint_pp); else { - char *tail = NULL; signed long messages; signed long first_seen_ago; signed long most_recent_seen_ago; log_assert (strlist_length (strlist) == 3); - errno = 0; - messages = strtol (strlist->d, &tail, 0); - if (errno || *tail != '\0') - /* Abort. */ - { - log_debug ("%s:%d: Couldn't convert %s (messages) to an int: %s.\n", - __func__, __LINE__, strlist->d, strerror (errno)); - messages = -1; - } + string_to_long (&messages, strlist->d, -1, __LINE__); if (messages == 0 && *strlist->next->d == '\0') - /* min(NULL) => NULL => "". */ - { + { /* min(NULL) => NULL => "". */ first_seen_ago = -1; most_recent_seen_ago = -1; } else { - errno = 0; - first_seen_ago = strtol (strlist->next->d, &tail, 0); - if (errno || *tail != '\0') - /* Abort. */ - { - log_debug ("%s:%d: Couldn't convert %s (first_seen) to an int: %s.\n", - __func__, __LINE__, - strlist->next->d, strerror (errno)); - first_seen_ago = 0; - } - - errno = 0; - most_recent_seen_ago = strtol (strlist->next->next->d, &tail, 0); - if (errno || *tail != '\0') - /* Abort. */ - { - log_debug ("%s:%d: Couldn't convert %s (most_recent_seen) to an int: %s.\n", - __func__, __LINE__, - strlist->next->next->d, strerror (errno)); - most_recent_seen_ago = 0; - } + string_to_long (&first_seen_ago, strlist->next->d, 0, __LINE__); + string_to_long (&most_recent_seen_ago, strlist->next->next->d, 0, + __LINE__); } if (messages == -1 || first_seen_ago == 0) @@ -2493,7 +2493,7 @@ show_statistics (struct dbs *dbs, const char *fingerprint, xfree (tmp); log_info ("%s", text); xfree (text); - free (set_policy_command); + es_free (set_policy_command); } } }