mirror of
git://git.gnupg.org/gnupg.git
synced 2025-05-19 09:02:22 +02:00
Add new functions to convert iso time strings.
This commit is contained in:
parent
cf8878cb18
commit
dfdda3b344
@ -1,3 +1,11 @@
|
|||||||
|
2011-02-27 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* gettime.c (isotime2epoch): Factor check code out to ..
|
||||||
|
(isotime_p): .. new.
|
||||||
|
(isotime_human_p): New.
|
||||||
|
(string2isotime): New.
|
||||||
|
* t-gettime.c (test_string2isotime): New.
|
||||||
|
|
||||||
2011-02-11 Andrey Jivsov <openpgp@brainhub.org>
|
2011-02-11 Andrey Jivsov <openpgp@brainhub.org>
|
||||||
|
|
||||||
* openpgp-oid.c (openpgp_oid_to_str): Use unsigned int for
|
* openpgp-oid.c (openpgp_oid_to_str): Use unsigned int for
|
||||||
|
163
common/gettime.c
163
common/gettime.c
@ -1,5 +1,5 @@
|
|||||||
/* gettime.c - Wrapper for time functions
|
/* gettime.c - Wrapper for time functions
|
||||||
* Copyright (C) 1998, 2002, 2007 Free Software Foundation, Inc.
|
* Copyright (C) 1998, 2002, 2007, 2011 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -179,29 +179,162 @@ scan_isodatestr( const char *string )
|
|||||||
return stamp;
|
return stamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scan am ISO timestamp and return an Epoch based timestamp. The only
|
|
||||||
|
int
|
||||||
|
isotime_p (const char *string)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!*string)
|
||||||
|
return 0;
|
||||||
|
for (s=string, i=0; i < 8; i++, s++)
|
||||||
|
if (!digitp (s))
|
||||||
|
return 0;
|
||||||
|
if (*s != 'T')
|
||||||
|
return 0;
|
||||||
|
for (s++, i=9; i < 15; i++, s++)
|
||||||
|
if (!digitp (s))
|
||||||
|
return 0;
|
||||||
|
if ( !(!*s || (isascii (*s) && isspace(*s)) || *s == ':' || *s == ','))
|
||||||
|
return 0; /* Wrong delimiter. */
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Scan a string and return true if the string represents the human
|
||||||
|
readable format of an ISO time. This format is:
|
||||||
|
yyyy-mm-dd[ hh[:mm[:ss]]]
|
||||||
|
Scanning stops at the second space or at a comma. */
|
||||||
|
int
|
||||||
|
isotime_human_p (const char *string)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!*string)
|
||||||
|
return 0;
|
||||||
|
for (s=string, i=0; i < 4; i++, s++)
|
||||||
|
if (!digitp (s))
|
||||||
|
return 0;
|
||||||
|
if (*s != '-')
|
||||||
|
return 0;
|
||||||
|
s++;
|
||||||
|
if (!digitp (s) || !digitp (s+1) || s[2] != '-')
|
||||||
|
return 0;
|
||||||
|
i = atoi_2 (s);
|
||||||
|
if (i < 1 || i > 12)
|
||||||
|
return 0;
|
||||||
|
s += 3;
|
||||||
|
if (!digitp (s) || !digitp (s+1))
|
||||||
|
return 0;
|
||||||
|
i = atoi_2 (s);
|
||||||
|
if (i < 1 || i > 31)
|
||||||
|
return 0;
|
||||||
|
s += 2;
|
||||||
|
if (!*s || *s == ',')
|
||||||
|
return 1; /* Okay; only date given. */
|
||||||
|
if (!spacep (s))
|
||||||
|
return 0;
|
||||||
|
s++;
|
||||||
|
if (spacep (s))
|
||||||
|
return 1; /* Okay, second space stops scanning. */
|
||||||
|
if (!digitp (s) || !digitp (s+1))
|
||||||
|
return 0;
|
||||||
|
i = atoi_2 (s);
|
||||||
|
if (i < 0 || i > 23)
|
||||||
|
return 0;
|
||||||
|
s += 2;
|
||||||
|
if (!*s || *s == ',')
|
||||||
|
return 1; /* Okay; only date and hour given. */
|
||||||
|
if (*s != ':')
|
||||||
|
return 0;
|
||||||
|
s++;
|
||||||
|
if (!digitp (s) || !digitp (s+1))
|
||||||
|
return 0;
|
||||||
|
i = atoi_2 (s);
|
||||||
|
if (i < 0 || i > 59)
|
||||||
|
return 0;
|
||||||
|
s += 2;
|
||||||
|
if (!*s || *s == ',')
|
||||||
|
return 1; /* Okay; only date, hour and minute given. */
|
||||||
|
if (*s != ':')
|
||||||
|
return 0;
|
||||||
|
s++;
|
||||||
|
if (!digitp (s) || !digitp (s+1))
|
||||||
|
return 0;
|
||||||
|
i = atoi_2 (s);
|
||||||
|
if (i < 0 || i > 60)
|
||||||
|
return 0;
|
||||||
|
s += 2;
|
||||||
|
if (!*s || *s == ',' || spacep (s))
|
||||||
|
return 1; /* Okay; date, hour and minute and second given. */
|
||||||
|
|
||||||
|
return 0; /* Unexpected delimiter. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert a standard isotime or a human readable variant into an
|
||||||
|
isotime structure. The allowed formats are those described by
|
||||||
|
isotime_p and isotime_human_p. The function returns 0 on failure
|
||||||
|
or the length of the scanned string on success. */
|
||||||
|
size_t
|
||||||
|
string2isotime (gnupg_isotime_t atime, const char *string)
|
||||||
|
{
|
||||||
|
gnupg_isotime_t dummyatime;
|
||||||
|
|
||||||
|
if (!atime)
|
||||||
|
atime = dummyatime;
|
||||||
|
|
||||||
|
atime[0] = 0;
|
||||||
|
if (isotime_p (string))
|
||||||
|
{
|
||||||
|
memcpy (atime, string, 15);
|
||||||
|
atime[15] = 0;
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
if (!isotime_human_p (string))
|
||||||
|
return 0;
|
||||||
|
atime[0] = string[0];
|
||||||
|
atime[1] = string[1];
|
||||||
|
atime[2] = string[2];
|
||||||
|
atime[3] = string[3];
|
||||||
|
atime[4] = string[5];
|
||||||
|
atime[5] = string[6];
|
||||||
|
atime[6] = string[8];
|
||||||
|
atime[7] = string[9];
|
||||||
|
atime[8] = 'T';
|
||||||
|
memset (atime+9, '0', 6);
|
||||||
|
atime[15] = 0;
|
||||||
|
if (!spacep (string+10))
|
||||||
|
return 10;
|
||||||
|
if (spacep (string+11))
|
||||||
|
return 11; /* As per def, second space stops scanning. */
|
||||||
|
atime[9] = string[11];
|
||||||
|
atime[10] = string[12];
|
||||||
|
if (string[13] != ':')
|
||||||
|
return 13;
|
||||||
|
atime[11] = string[14];
|
||||||
|
atime[12] = string[15];
|
||||||
|
if (string[16] != ':')
|
||||||
|
return 16;
|
||||||
|
atime[13] = string[17];
|
||||||
|
atime[14] = string[18];
|
||||||
|
return 19;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Scan an ISO timestamp and return an Epoch based timestamp. The only
|
||||||
supported format is "yyyymmddThhmmss" delimited by white space, nul, a
|
supported format is "yyyymmddThhmmss" delimited by white space, nul, a
|
||||||
colon or a comma. Returns (time_t)(-1) for an invalid string. */
|
colon or a comma. Returns (time_t)(-1) for an invalid string. */
|
||||||
time_t
|
time_t
|
||||||
isotime2epoch (const char *string)
|
isotime2epoch (const char *string)
|
||||||
{
|
{
|
||||||
const char *s;
|
|
||||||
int year, month, day, hour, minu, sec;
|
int year, month, day, hour, minu, sec;
|
||||||
struct tm tmbuf;
|
struct tm tmbuf;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!*string)
|
if (!isotime_p (string))
|
||||||
return (time_t)(-1);
|
return (time_t)(-1);
|
||||||
for (s=string, i=0; i < 8; i++, s++)
|
|
||||||
if (!digitp (s))
|
|
||||||
return (time_t)(-1);
|
|
||||||
if (*s != 'T')
|
|
||||||
return (time_t)(-1);
|
|
||||||
for (s++, i=9; i < 15; i++, s++)
|
|
||||||
if (!digitp (s))
|
|
||||||
return (time_t)(-1);
|
|
||||||
if ( !(!*s || (isascii (*s) && isspace(*s)) || *s == ':' || *s == ','))
|
|
||||||
return (time_t)(-1); /* Wrong delimiter. */
|
|
||||||
|
|
||||||
year = atoi_4 (string);
|
year = atoi_4 (string);
|
||||||
month = atoi_2 (string + 4);
|
month = atoi_2 (string + 4);
|
||||||
|
@ -34,6 +34,9 @@ void gnupg_set_time (time_t newtime, int freeze);
|
|||||||
int gnupg_faked_time_p (void);
|
int gnupg_faked_time_p (void);
|
||||||
u32 make_timestamp (void);
|
u32 make_timestamp (void);
|
||||||
u32 scan_isodatestr (const char *string);
|
u32 scan_isodatestr (const char *string);
|
||||||
|
int isotime_p (const char *string);
|
||||||
|
int isotime_human_p (const char *string);
|
||||||
|
size_t string2isotime (gnupg_isotime_t atime, const char *string);
|
||||||
time_t isotime2epoch (const char *string);
|
time_t isotime2epoch (const char *string);
|
||||||
void epoch2isotime (gnupg_isotime_t timebuf, time_t atime);
|
void epoch2isotime (gnupg_isotime_t timebuf, time_t atime);
|
||||||
u32 add_days_to_timestamp (u32 stamp, u16 days);
|
u32 add_days_to_timestamp (u32 stamp, u16 days);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* t-gettime.c - Module test for gettime.c
|
/* t-gettime.c - Module test for gettime.c
|
||||||
* Copyright (C) 2007 Free Software Foundation, Inc.
|
* Copyright (C) 2007, 2011 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -89,6 +89,90 @@ test_isotime2epoch (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_string2isotime (void)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
const char *string;
|
||||||
|
size_t result;
|
||||||
|
const char *expected;
|
||||||
|
} array [] = {
|
||||||
|
{ "19700101T000001", 15, "19700101T000001" },
|
||||||
|
{ "19700101T235959", 15, "19700101T235959" },
|
||||||
|
{ "19980815T143712", 15, "19980815T143712" },
|
||||||
|
{ "19700101T000000", 15, "19700101T000000" },
|
||||||
|
{ "19691231T235959", 15, "19691231T235959" },
|
||||||
|
{ "19000101T000000", 15, "19000101T000000" },
|
||||||
|
{ "", 0, "" },
|
||||||
|
{ "19000101T00000", 0, "" },
|
||||||
|
{ "20010101t123456", 0, "" },
|
||||||
|
{ "20010101T123456", 15, "20010101T123456" },
|
||||||
|
{ "20070629T160000", 15, "20070629T160000" },
|
||||||
|
{ "20070629T160000:", 15, "20070629T160000" },
|
||||||
|
{ "20070629T160000,", 15, "20070629T160000" },
|
||||||
|
{ "20070629T160000 ", 15, "20070629T160000" },
|
||||||
|
{ "20070629T160000\n", 15,"20070629T160000" },
|
||||||
|
{ "20070629T160000.", 0, "" },
|
||||||
|
{ "1066-03-20", 10, "10660320T000000" },
|
||||||
|
{ "1066-03-20,", 10, "10660320T000000" },
|
||||||
|
{ "1066-03-20:", 0, "" },
|
||||||
|
{ "1066-03-20 00", 13, "10660320T000000" },
|
||||||
|
{ "1066-03-20 01", 13, "10660320T010000" },
|
||||||
|
{ "1066-03-20 23", 13, "10660320T230000" },
|
||||||
|
{ "1066-03-20 24", 0, "" },
|
||||||
|
{ "1066-03-20 00:", 0, "" },
|
||||||
|
{ "1066-03-20 00:3", 0, "" },
|
||||||
|
{ "1066-03-20 00:31", 16, "10660320T003100" },
|
||||||
|
{ "1066-03-20 00:31:47", 19, "10660320T003147" },
|
||||||
|
{ "1066-03-20 00:31:47 ", 19, "10660320T003147" },
|
||||||
|
{ "1066-03-20 00:31:47,", 19, "10660320T003147" },
|
||||||
|
{ "1066-03-20 00:31:47:", 0, "" },
|
||||||
|
{ "1-03-20 00:31:47:", 0, "" },
|
||||||
|
{ "10-03-20 00:31:47:", 0, "" },
|
||||||
|
{ "106-03-20 00:31:47:", 0, "" },
|
||||||
|
{ "1066-23-20 00:31:47:", 0, "" },
|
||||||
|
{ "1066-00-20 00:31:47:", 0, "" },
|
||||||
|
{ "1066-0-20 00:31:47:", 0, "" },
|
||||||
|
{ "1066-01-2 00:31:47:", 0, "" },
|
||||||
|
{ "1066-01-2 00:31:47:", 0, "" },
|
||||||
|
{ "1066-01-32 00:31:47:", 0, "" },
|
||||||
|
{ "1066-01-00 00:31:47:", 0, "" },
|
||||||
|
{ "1066-03-20 00:31:47:",11, "10660320T000000" },
|
||||||
|
{ "1066-03-2000:31:47:", 0, "" },
|
||||||
|
{ "10666-03-20 00:31:47:", 0, "" },
|
||||||
|
{ NULL, 0 }
|
||||||
|
};
|
||||||
|
int idx;
|
||||||
|
size_t result;
|
||||||
|
gnupg_isotime_t tbuf;
|
||||||
|
|
||||||
|
for (idx=0; array[idx].string; idx++)
|
||||||
|
{
|
||||||
|
result = string2isotime (tbuf, array[idx].string);
|
||||||
|
if (result != array[idx].result)
|
||||||
|
{
|
||||||
|
fail (idx);
|
||||||
|
if (verbose)
|
||||||
|
fprintf (stderr, "string `%s' expected: %d, got: %d\n",
|
||||||
|
array[idx].string, (int)array[idx].result, (int)result);
|
||||||
|
}
|
||||||
|
else if (result && strlen (tbuf) != 15)
|
||||||
|
{
|
||||||
|
fail (idx);
|
||||||
|
if (verbose)
|
||||||
|
fprintf (stderr, "string `%s' invalid isotime returned\n",
|
||||||
|
array[idx].string);
|
||||||
|
}
|
||||||
|
else if (result && strcmp (array[idx].expected, tbuf))
|
||||||
|
{
|
||||||
|
fail (idx);
|
||||||
|
if (verbose)
|
||||||
|
fprintf (stderr, "string `%s' bad isotime '%s' returned\n",
|
||||||
|
array[idx].string, tbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
@ -97,6 +181,7 @@ main (int argc, char **argv)
|
|||||||
verbose = 1;
|
verbose = 1;
|
||||||
|
|
||||||
test_isotime2epoch ();
|
test_isotime2epoch ();
|
||||||
|
test_string2isotime ();
|
||||||
|
|
||||||
return !!errcount;
|
return !!errcount;
|
||||||
}
|
}
|
||||||
|
10
common/tlv.c
10
common/tlv.c
@ -238,14 +238,14 @@ _parse_ber_header (unsigned char const **buffer, size_t *size,
|
|||||||
is the pointer to the S-expression and BUFLEN is a pointer to the
|
is the pointer to the S-expression and BUFLEN is a pointer to the
|
||||||
length of this S-expression (used to validate the syntax). Both
|
length of this S-expression (used to validate the syntax). Both
|
||||||
are updated to reflect the new position. The token itself is
|
are updated to reflect the new position. The token itself is
|
||||||
returned as a pointer into the orginal buffer at TOK and TOKLEN.
|
returned as a pointer into the original buffer at TOK and TOKLEN.
|
||||||
If a parentheses is the next token, TOK will be set to NULL.
|
If a parentheses is the next token, TOK will be set to NULL.
|
||||||
TOKLEN is checked to be within the bounds. On error a error code
|
TOKLEN is checked to be within the bounds. On error an error code
|
||||||
is returned and all pointers should are not guaranteed to point to
|
is returned and no pointer is not guaranteed to point to
|
||||||
a meanigful value. DEPTH should be initialized to 0 and will
|
a meaningful value. DEPTH should be initialized to 0 and will
|
||||||
reflect on return the actual depth of the tree. To detect the end
|
reflect on return the actual depth of the tree. To detect the end
|
||||||
of the S-expression it is advisable to check DEPTH after a
|
of the S-expression it is advisable to check DEPTH after a
|
||||||
successful return:
|
successful return.
|
||||||
|
|
||||||
depth = 0;
|
depth = 0;
|
||||||
while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
|
while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
|
||||||
|
10
common/tlv.h
10
common/tlv.h
@ -90,15 +90,15 @@ gpg_error_t _parse_ber_header (unsigned char const **buffer, size_t *size,
|
|||||||
GPG_ERR_SOURCE_DEFAULT)
|
GPG_ERR_SOURCE_DEFAULT)
|
||||||
|
|
||||||
|
|
||||||
/* Return the next token of an canconical encoded S-expression. BUF
|
/* Return the next token of an canonical encoded S-expression. BUF
|
||||||
is the pointer to the S-expression and BUFLEN is a pointer to the
|
is the pointer to the S-expression and BUFLEN is a pointer to the
|
||||||
length of this S-expression (used to validate the syntax). Both
|
length of this S-expression (used to validate the syntax). Both
|
||||||
are updated to reflect the new position. The token itself is
|
are updated to reflect the new position. The token itself is
|
||||||
returned as a pointer into the orginal buffer at TOK and TOKLEN.
|
returned as a pointer into the original buffer at TOK and TOKLEN.
|
||||||
If a parentheses is the next token, TOK will be set to NULL.
|
If a parentheses is the next token, TOK will be set to NULL.
|
||||||
TOKLEN is checked to be within the bounds. On error a error code
|
TOKLEN is checked to be within the bounds. On error an error code
|
||||||
is returned and all pointers should are not guaranteed to point to
|
is returned and no pointer is not guaranteed to point to
|
||||||
a meanigful value. DEPTH should be initialized to 0 and will
|
a meaningful value. DEPTH should be initialized to 0 and will
|
||||||
reflect on return the actual depth of the tree. To detect the end
|
reflect on return the actual depth of the tree. To detect the end
|
||||||
of the S-expression it is advisable to check DEPTH after a
|
of the S-expression it is advisable to check DEPTH after a
|
||||||
successful return. */
|
successful return. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user