diff options
author | Werner Koch <[email protected]> | 2008-09-03 09:37:32 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2008-09-03 09:37:32 +0000 |
commit | 5a8bf0bec6e63ebd57d0064be65c08ac331ac9e3 (patch) | |
tree | 187e260d1af072d35a529fd43b765e71bab34108 /common | |
parent | 2008-08-30 Moritz <[email protected]> (diff) | |
download | gnupg-5a8bf0bec6e63ebd57d0064be65c08ac331ac9e3.tar.gz gnupg-5a8bf0bec6e63ebd57d0064be65c08ac331ac9e3.zip |
Fix gpg-preset-passphrase bug.
Cleanups
Diffstat (limited to 'common')
-rw-r--r-- | common/ChangeLog | 6 | ||||
-rw-r--r-- | common/convert.c | 89 | ||||
-rw-r--r-- | common/t-convert.c | 171 | ||||
-rw-r--r-- | common/util.h | 3 |
4 files changed, 266 insertions, 3 deletions
diff --git a/common/ChangeLog b/common/ChangeLog index 3842b9c68..e517872d2 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,9 @@ +2008-09-03 Werner Koch <[email protected]> + + * convert.c (hex2str): New. + (hex2str_alloc): New. + * t-convert.c (test_hex2str): New. + 2008-08-19 Werner Koch <[email protected]> * iobuf.c: Avoid passing a NULL (iobuf_t)->desc to the log diff --git a/common/convert.c b/common/convert.c index 7aa6354d6..c946b81b1 100644 --- a/common/convert.c +++ b/common/convert.c @@ -1,5 +1,5 @@ /* convert.c - Hex conversion functions. - * Copyright (C) 2006 Free Software Foundation, Inc. + * Copyright (C) 2006, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -30,7 +30,7 @@ /* Convert STRING consisting of hex characters into its binary representation and store that at BUFFER. BUFFER needs to be of - LENGTH bytes. The function check that the STRING will convert + LENGTH bytes. The function checks that the STRING will convert exactly to LENGTH bytes. The string is delimited by either end of string or a white space character. The function returns -1 on error or the length of the parsed string. */ @@ -100,6 +100,7 @@ hexcolon2bin (const char *string, void *buffer, size_t length) } + static char * do_bin2hex (const void *buffer, size_t length, char *stringbuf, int with_colon) { @@ -160,3 +161,87 @@ bin2hexcolon (const void *buffer, size_t length, char *stringbuf) } + +/* Convert HEXSTRING consisting of hex characters into string and + store that at BUFFER. HEXSTRING is either delimited by end of + string or a white space character. The function makes sure that + the resulting string in BUFFER is terminated by a Nul character. + BUFSIZE is the availabe length of BUFFER; if the converted result + plus a possible required Nul character does not fit into this + buffer, the function returns NULL and won't change the existing + conent of buffer. In-place conversion is possible as long as + BUFFER points to HEXSTRING. + + If BUFFER is NULL and bufsize is 0 the function scans HEXSTRING but + does not store anything. This may be used to find the end of + hexstring. + + On sucess the function returns a pointer to the next character + after HEXSTRING (which is either end-of-string or a the next white + space). If BUFLEN is not NULL the strlen of buffer is stored + there; this will even be done if BUFFER has been passed as NULL. */ +const char * +hex2str (const char *hexstring, char *buffer, size_t bufsize, size_t *buflen) +{ + const char *s = hexstring; + int idx, count; + int need_nul = 0; + + if (buflen) + *buflen = 0; + + for (s=hexstring, count=0; hexdigitp (s) && hexdigitp (s+1); s += 2, count++) + ; + if (*s && (!isascii (*s) || !isspace (*s)) ) + return NULL; /* Not followed by Nul or white space. */ + need_nul = !(s[-2] == '0' && s[-1] == '0'); + if (need_nul) + count++; + + if (buffer) + { + if (count > bufsize) + return NULL; /* Too long. */ + + for (s=hexstring, idx=0; hexdigitp (s) && hexdigitp (s+1); s += 2) + ((unsigned char*)buffer)[idx++] = xtoi_2 (s); + if (need_nul) + buffer[idx] = 0; + } + + if (buflen) + *buflen = count - 1; + return s; +} + + +/* Same as hex2str but this function allocated a new string. Returns + NULL on error. If R_COUNT is not NULL, the number of scanned bytes + will be stored there. ERRNO is set on error. */ +char * +hex2str_alloc (const char *hexstring, size_t *r_count) +{ + const char *tail; + size_t nbytes; + char *result; + + tail = hex2str (hexstring, NULL, 0, &nbytes); + if (!tail) + { + if (r_count) + *r_count = 0; + errno = EINVAL; + return NULL; + } + if (r_count) + *r_count = tail - hexstring; + result = xtrymalloc (nbytes+1); + if (!result) + return NULL; + if (!hex2str (hexstring, result, nbytes+1, NULL)) + BUG (); + return result; +} + + + diff --git a/common/t-convert.c b/common/t-convert.c index ede1e463d..caf743f1f 100644 --- a/common/t-convert.c +++ b/common/t-convert.c @@ -1,5 +1,5 @@ /* t-convert.c - Module test for convert.c - * Copyright (C) 2006 Free Software Foundation, Inc. + * Copyright (C) 2006, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -20,6 +20,7 @@ #include <config.h> #include <stdio.h> #include <stdlib.h> +#include <assert.h> #include "util.h" @@ -275,6 +276,173 @@ test_bin2hexcolon (void) +static void +test_hex2str (void) +{ + static struct { + const char *hex; + const char *str; + int off; + int no_alloc_test; + } tests[] = { + /* Simple tests. */ + { "112233445566778899aabbccddeeff1122", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 34 }, + { "112233445566778899aabbccddeeff1122 blah", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 34 }, + { "112233445566778899aabbccddeeff1122\tblah", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 34 }, + { "112233445566778899aabbccddeeff1122\nblah", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 34 }, + /* Valid tests yielding an empty string. */ + { "00", + "", + 2 }, + { "00 x", + "", + 2 }, + { "", + "", + 0 }, + { " ", + "", + 0 }, + /* Test trailing Nul feature. */ + { "112233445566778899aabbccddeeff112200", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 36 }, + { "112233445566778899aabbccddeeff112200 ", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 36 }, + /* Test buffer size. (buffer is of length 20) */ + { "6162636465666768696A6b6c6D6e6f70717273", + "abcdefghijklmnopqrs", + 38 }, + { "6162636465666768696A6b6c6D6e6f7071727300", + "abcdefghijklmnopqrs", + 40 }, + { "6162636465666768696A6b6c6D6e6f7071727374", + NULL, + 0, 1 }, + { "6162636465666768696A6b6c6D6e6f707172737400", + NULL, + 0, 1 }, + { "6162636465666768696A6b6c6D6e6f707172737475", + NULL, + 0, 1 }, + + /* Invalid tests. */ + { "112233445566778899aabbccddeeff1122334", NULL, 0 }, + { "112233445566778899AABBCCDDEEFF1122334", NULL, 0 }, + { "112233445566778899AABBCCDDEEFG11223344", NULL, 0 }, + { "0:0112233445566778899aabbccddeeff11223344", NULL, 0 }, + { "112233445566778899aabbccddeeff11223344:", NULL, 0 }, + { "112233445566778899aabbccddeeff112233445", NULL, 0 }, + { "112233445566778899aabbccddeeff1122334455", NULL, 0, 1 }, + { "112233445566778899aabbccddeeff11223344blah", NULL, 0 }, + { "0", NULL, 0 }, + { "00:", NULL, 0 }, + { "00x", NULL, 0 }, + + { NULL, NULL, 0 } + }; + + int idx; + char buffer[20]; + const char *tail; + size_t count; + char *result; + + for (idx=0; tests[idx].hex; idx++) + { + tail = hex2str (tests[idx].hex, buffer, sizeof buffer, &count); + if (tests[idx].str) + { + /* Good case test. */ + if (!tail) + fail (idx); + else if (strcmp (tests[idx].str, buffer)) + fail (idx); + else if (tail - tests[idx].hex != tests[idx].off) + fail (idx); + else if (strlen (buffer) != count) + fail (idx); + } + else + { + /* Bad case test. */ + if (tail) + fail (idx); + } + } + + /* Same tests again using in-place conversion. */ + for (idx=0; tests[idx].hex; idx++) + { + char tmpbuf[100]; + + assert (strlen (tests[idx].hex)+1 < sizeof tmpbuf); + strcpy (tmpbuf, tests[idx].hex); + + /* Note: we still need to use 20 as buffer length because our + tests assume that. */ + tail = hex2str (tmpbuf, tmpbuf, 20, &count); + if (tests[idx].str) + { + /* Good case test. */ + if (!tail) + fail (idx); + else if (strcmp (tests[idx].str, tmpbuf)) + fail (idx); + else if (tail - tmpbuf != tests[idx].off) + fail (idx); + else if (strlen (tmpbuf) != count) + fail (idx); + } + else + { + /* Bad case test. */ + if (tail) + fail (idx); + if (strcmp (tmpbuf, tests[idx].hex)) + fail (idx); /* Buffer was modified. */ + } + } + + /* Test the allocation variant. */ + for (idx=0; tests[idx].hex; idx++) + { + if (tests[idx].no_alloc_test) + continue; + + result = hex2str_alloc (tests[idx].hex, &count); + if (tests[idx].str) + { + /* Good case test. */ + if (!result) + fail (idx); + else if (strcmp (tests[idx].str, result)) + fail (idx); + else if (count != tests[idx].off) + fail (idx); + } + else + { + /* Bad case test. */ + if (result) + fail (idx); + } + xfree (result); + } +} + + + + int main (int argc, char **argv) @@ -284,6 +452,7 @@ main (int argc, char **argv) test_hexcolon2bin (); test_bin2hex (); test_bin2hexcolon (); + test_hex2str (); return 0; } diff --git a/common/util.h b/common/util.h index 5b564a2c6..572fa1a6a 100644 --- a/common/util.h +++ b/common/util.h @@ -189,6 +189,9 @@ int hex2bin (const char *string, void *buffer, size_t length); int hexcolon2bin (const char *string, void *buffer, size_t length); char *bin2hex (const void *buffer, size_t length, char *stringbuf); char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf); +const char *hex2str (const char *hexstring, + char *buffer, size_t bufsize, size_t *buflen); +char *hex2str_alloc (const char *hexstring, size_t *r_count); /*-- homedir.c --*/ |