Mercurial > dovecot > core-2.2
changeset 19124:d85bf97ab8b7
lib: Added some tests for the new strnum _hex() and _oct() function variants.
author | Stephan Bosch <stephan@rename-it.nl> |
---|---|
date | Tue, 08 Sep 2015 01:27:18 +0300 |
parents | f6dd24658fb1 |
children | c4932f3f4acd |
files | src/lib/test-strnum.c |
diffstat | 1 files changed, 148 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/test-strnum.c Tue Sep 08 01:20:51 2015 +0300 +++ b/src/lib/test-strnum.c Tue Sep 08 01:27:18 2015 +0300 @@ -23,7 +23,6 @@ #undef STRINGIFY #undef BIGBASE } - static void test_str_to_uintmax(void) { unsigned int i=0; @@ -73,12 +72,158 @@ while (buff[--j] == '9') buff[j] = '0'; buff[j]++; + ret = str_to_uintmax(buff, &value); test_assert_idx(ret < 0 && value == UINTMAX_MAX/9-1, i); } test_end(); } +/* always pads with leading zeros to a size of 9 digits */ +static int crappy_uintmax_to_str_hex(char *into, uintmax_t val) +{ +#define BIGBASE 0x1000000000 +#define STRINGIFY(s) #s +#define STRINGIFY2(s) STRINGIFY(s) + int len = 0; + if(val >= BIGBASE) { + len = crappy_uintmax_to_str_hex(into, val/BIGBASE); + } + i_snprintf(into + len, 10, "%09lx", (unsigned long)(val % BIGBASE)); + return len + strlen(STRINGIFY2(BIGBASE))-3; +#undef STRINGIFY2 +#undef STRINGIFY +#undef BIGBASE +} +static void test_str_to_uintmax_hex(void) +{ + unsigned int i=0; + int randrange = rand()%15+1; /* when 1, will max out on 1s */ + uintmax_t value = 0; + int len, ret; + char buff[52]; /* totally assumes < 200 bits */ + + test_begin("str_to_uintmax_hex in range"); + while (i < sizeof(uintmax_t)*CHAR_BIT) { + uintmax_t value_back; + const char *endp; + + value = (value << 1) + 1; + if (value >= 64) + value -= rand()%randrange; /* don't always test the same numbers */ + len = crappy_uintmax_to_str_hex(buff, value); + ret = str_to_uintmax_hex(buff, &value_back); + test_assert_idx(ret == 0, i); + test_assert_idx(value == value_back, i); + + /* test with trailing noise */ + buff[len] = 'x'; /* don't even null-terminate, let's be evil */ + value_back = 0x1234567890123456; + ret = str_to_uintmax_hex(buff, &value_back); + test_assert_idx(ret < 0, i); + test_assert_idx(value_back == 0x1234567890123456, i); + ret = str_parse_uintmax_hex(buff, &value_back, &endp); + test_assert_idx(ret == 0, i); + test_assert_idx(value_back == value, i); + test_assert_idx(endp == &buff[len], i); + i++; + } + test_end(); + + /* not knowing exactly how large a uintmax_t is, we have to construct + the troublesome near-0x10/0x0F*MAX strings manually by appending digits + to a MAX/0x0f string which we can easily create. Do a wider range + of 0x30 rather than the obvious 0x10, just in case - all are too large.*/ + test_begin("str_to_uintmax_hex overflow corner case"); + value = (UINTMAX_MAX/0x0f)-1; + len = crappy_uintmax_to_str_hex(buff, value); + buff[len] = '0'; + buff[len+1] = '\0'; + for(i = 0; i <= 0x30; ++i) { + int j = len + 1; + while (buff[--j] == 'f') + buff[j] = '0'; + if (buff[j] == '9') + buff[j] = 'a'; + else + buff[j]++; + ret = str_to_uintmax_hex(buff, &value); + test_assert_idx(ret < 0 && value == UINTMAX_MAX/0x0f-1, i); + } + test_end(); +} + +/* always pads with leading zeros to a size of 9 digits */ +static int crappy_uintmax_to_str_oct(char *into, uintmax_t val) +{ +#define BIGBASE 01000000000 +#define STRINGIFY(s) #s +#define STRINGIFY2(s) STRINGIFY(s) + int len = 0; + if(val >= BIGBASE) { + len = crappy_uintmax_to_str_oct(into, val/BIGBASE); + } + i_snprintf(into + len, 10, "%09lo", (unsigned long)(val % BIGBASE)); + return len + strlen(STRINGIFY2(BIGBASE))-2; +#undef STRINGIFY2 +#undef STRINGIFY +#undef BIGBASE +} +static void test_str_to_uintmax_oct(void) +{ + unsigned int i=0; + int randrange = rand()%15+1; /* when 1, will max out on 1s */ + uintmax_t value = 0; + int len, ret; + char buff[69]; /* totally assumes < 200 bits */ + + test_begin("str_to_uintmax_oct in range"); + while (i < sizeof(uintmax_t)*CHAR_BIT) { + uintmax_t value_back; + const char *endp; + + value = (value << 1) + 1; + if (value >= 64) + value -= rand()%randrange; /* don't always test the same numbers */ + len = crappy_uintmax_to_str_oct(buff, value); + ret = str_to_uintmax_oct(buff, &value_back); + test_assert_idx(ret == 0, i); + test_assert_idx(value == value_back, i); + + /* test with trailing noise */ + buff[len] = 'x'; /* don't even null-terminate, let's be evil */ + value_back = 0x1234567890123456; + ret = str_to_uintmax_oct(buff, &value_back); + test_assert_idx(ret < 0, i); + test_assert_idx(value_back == 0x1234567890123456, i); + ret = str_parse_uintmax_oct(buff, &value_back, &endp); + test_assert_idx(ret == 0, i); + test_assert_idx(value_back == value, i); + test_assert_idx(endp == &buff[len], i); + i++; + } + test_end(); + + /* not knowing exactly how large a uintmax_t is, we have to construct + the troublesome near-010/007*MAX strings manually by appending digits + to a MAX/007 string which we can easily create. Do a wider range + of 030 rather than the obvious 010, just in case - all are too large.*/ + test_begin("str_to_uintmax_oct overflow corner case"); + value = (UINTMAX_MAX/007)-1; + len = crappy_uintmax_to_str_oct(buff, value); + buff[len] = '0'; + buff[len+1] = '\0'; + for(i = 0; i <= 030; ++i) { + int j = len + 1; + while (buff[--j] == '7') + buff[j] = '0'; + buff[j]++; + ret = str_to_uintmax_oct(buff, &value); + test_assert_idx(ret < 0 && value == UINTMAX_MAX/007-1, i); + } + test_end(); +} + static void test_str_to_u64(void) { unsigned int i; @@ -213,6 +358,8 @@ { /* If the above isn't true, then we do expect some failures possibly */ test_str_to_uintmax(); + test_str_to_uintmax_hex(); + test_str_to_uintmax_oct(); test_str_to_u64(); test_str_to_u32(); test_str_to_llong();