summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2023-10-14 17:06:51 +0200
committerWerner Koch <wk@gnupg.org>2023-10-14 17:14:22 +0200
commita17363e992943244987dbab754b112c77d938b5d (patch)
tree51b2f749ed5c1dc67e937112cc3fef1728e9c024
parentgpgsm: Improvements for NDEF in the pkcs#12 parser (diff)
downloadgnupg2-a17363e992943244987dbab754b112c77d938b5d.tar.xz
gnupg2-a17363e992943244987dbab754b112c77d938b5d.zip
common: New function scan_secondsstr.
* common/gettime.c (scan_secondsstr): New. * common/t-gettime.c (test_scan_secondsstr): (main): Call it.
-rw-r--r--common/gettime.c23
-rw-r--r--common/gettime.h1
-rw-r--r--common/stringhelp.c2
-rw-r--r--common/t-gettime.c52
4 files changed, 76 insertions, 2 deletions
diff --git a/common/gettime.c b/common/gettime.c
index 2a9b71779..c3b0c6c6c 100644
--- a/common/gettime.c
+++ b/common/gettime.c
@@ -37,6 +37,7 @@
#ifdef HAVE_LANGINFO_H
#include <langinfo.h>
#endif
+#include <stdint.h> /* We use uint64_t. */
#include "util.h"
#include "i18n.h"
@@ -172,6 +173,28 @@ make_timestamp (void)
}
+/* Specialized version of atoi which returns an u32 instead of an int
+ * and caps the result at 2^32-2. Leading white space is skipped,
+ * scanning stops at at the first non-convertable byte. Note that we
+ * do not cap at 2^32-1 because that value is often used as error
+ * return. */
+u32
+scan_secondsstr (const char *string)
+{
+ uint64_t value = 0;
+
+ while (*string == ' ' || *string == '\t')
+ string++;
+ for (; *string >= '0' && *string <= '9'; string++)
+ {
+ value *= 10;
+ value += atoi_1 (string);
+ if (value >= (u32)(-1))
+ return (u32)(-1) - 1;
+ }
+ return (u32)value;
+}
+
/****************
* Scan a date string and return a timestamp.
diff --git a/common/gettime.h b/common/gettime.h
index 4f7199f92..18f65ab1a 100644
--- a/common/gettime.h
+++ b/common/gettime.h
@@ -51,6 +51,7 @@ int gnupg_faked_time_p (void);
u32 make_timestamp (void);
char *elapsed_time_string (time_t since, time_t now);
+u32 scan_secondsstr (const char *string);
u32 scan_isodatestr (const char *string);
int isotime_p (const char *string);
int isotime_human_p (const char *string, int date_only);
diff --git a/common/stringhelp.c b/common/stringhelp.c
index 5407653de..9a2265258 100644
--- a/common/stringhelp.c
+++ b/common/stringhelp.c
@@ -725,7 +725,7 @@ compare_filenames (const char *a, const char *b)
/* Convert a base-10 number in STRING into a 64 bit unsigned int
* value. Leading white spaces are skipped but no error checking is
- * done. Thus it is similar to atoi(). */
+ * done. Thus it is similar to atoi(). See also scan_secondsstr. */
uint64_t
string_to_u64 (const char *string)
{
diff --git a/common/t-gettime.c b/common/t-gettime.c
index 13cb1a2f7..76c305204 100644
--- a/common/t-gettime.c
+++ b/common/t-gettime.c
@@ -44,6 +44,56 @@ static int errcount;
static void
+test_scan_secondsstr (void)
+{
+ struct { const char *string; u32 expected; } array [] = {
+ { "", 0 },
+ { "0", 0 },
+ { " 0", 0 },
+ { " 0x", 0 },
+ { " 1", 1 },
+ { "-1", 0 },
+ { " -1", 0 },
+ { "2", 2 },
+ { "11", 11 },
+ { "011", 11 },
+ { "3600 ", 3600 },
+ { "65535", 65535 },
+ { "65536", 65536 },
+ { "65537", 65537 },
+ { "4294967289", 4294967289 },
+ { "4294967290", 4294967290 },
+ { "4294967293", 4294967293 },
+ { "4294967295", 4294967294 },
+ { "4294967296", 4294967294 },
+ { "4294967297", 4294967294 },
+ { "4294967298", 4294967294 },
+ { "4294967299", 4294967294 },
+ { "4294967300", 4294967294 },
+ { "5294967300", 4294967294 },
+ { "9999999999", 4294967294 },
+ { "99999999999",4294967294 },
+ { NULL, 0 }
+ };
+ int idx;
+ u32 val;
+
+ for (idx=0; array[idx].string; idx++)
+ {
+ val = scan_secondsstr (array[idx].string);
+ if (val != array[idx].expected )
+ {
+ fail (idx);
+ if (verbose)
+ fprintf (stderr, "string '%s' exp: %ld got: %ld\n",
+ array[idx].string, (unsigned long)array[idx].expected,
+ (unsigned long)val);
+ }
+ }
+}
+
+
+static void
test_isotime2epoch (void)
{
struct { const char *string; time_t expected; } array [] = {
@@ -103,7 +153,6 @@ test_isotime2epoch (void)
}
-
static void
test_string2isotime (void)
{
@@ -269,6 +318,7 @@ main (int argc, char **argv)
if (argc > 1 && !strcmp (argv[1], "--verbose"))
verbose = 1;
+ test_scan_secondsstr ();
test_isotime2epoch ();
test_string2isotime ();
test_isodate_human_to_tm ();