test-strnum.c revision b800cdab69e2dfe6bf1b35f7dd836e9b8d512cc3
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2014-2014 Dovecot authors, see the included COPYING file */
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen#define VALID(n) { #n, 0, n }
31fd39a3a3d544b1a8afb9aef07f180d0d40fda2Timo Sirainen/* always pads with leading zeros to a size of 9 digits */
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainenstatic int crappy_uintmax_to_str(char *into, uintmax_t val)
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen len = crappy_uintmax_to_str(into, val/BIGBASE);
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen i_snprintf(into + len, 10, "%09lu", (unsigned long)(val % BIGBASE));
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainenstatic void test_str_to_uintmax(void)
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen unsigned int i=0;
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen int randrange = rand()%15+1; /* when 1, will max out on 1s */
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen char buff[50]; /* totally assumes < 159 bits */
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen value -= rand()%randrange; /* don't always test the same numbers */
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen /* test with trailing noise */
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen buff[len] = 'x'; /* don't even null-terminate, let's be evil */
b215322367dbd94df3e2e4bb643b53460e6adc51Timo Sirainen test_assert_idx(value_back == 0x1234567890123456, i);
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen ret = str_parse_uintmax(buff, &value_back, &endp);
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen /* not knowing exactly how large a uintmax_t is, we have to construct
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen the troublesome near-10/9*MAX strings manually by appending digits
b10c3f9ed997748fdbb03b9daadc8c31eed02120Timo Sirainen to a MAX/9 string which we can easily create. Do a wider range
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen of 30 rather than the obvious 10, just in case - all are too large.*/
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen test_begin("str_to_uintmax overflow corner case");
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen for(i = 0; i <= 30; ++i) {
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen test_assert_idx(ret < 0 && value == UINTMAX_MAX/9-1, i);
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainenstatic void test_str_to_u64(void)
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen unsigned int i;
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen const struct {
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen VALID(000000000000000000000000000000000000000000000000000000000000000),
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen { "000000000000000000000000000000000000000000000000000001000000001", 0, 1000000001 },
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen { "18446744073709551615", 0, 18446744073709551615ULL },
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen INVALID(20496382304121724010), /* 2^64*10/9 doesn't wrap */
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen INVALID(20496382304121724017), /* 2^64*10/9 wraps only after addition */
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen INVALID(20496382304121724020), /* 2^64*10/9 wraps on multiply*/
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen int ret = str_to_uint64(u64tests[i].input, &val);
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen test_assert_idx(val == 0xBADBEEF15BADF00D, i);
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen const char *longer = t_strconcat(u64tests[i].input, "x", NULL);
e18e90938ffd9e31c796c405404be0b7dcd5c807Timo Sirainenstatic void test_str_to_u32(void)
e18e90938ffd9e31c796c405404be0b7dcd5c807Timo Sirainen unsigned int i;
e18e90938ffd9e31c796c405404be0b7dcd5c807Timo Sirainen const struct {
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen int ret = str_to_uint32(u32tests[i].input, &val);
e18e90938ffd9e31c796c405404be0b7dcd5c807Timo Sirainen/* Assumes long long is 64 bit, 2's complement */
e18e90938ffd9e31c796c405404be0b7dcd5c807Timo Sirainenstatic void test_str_to_llong(void)
e18e90938ffd9e31c796c405404be0b7dcd5c807Timo Sirainen unsigned int i;
e18e90938ffd9e31c796c405404be0b7dcd5c807Timo Sirainen const struct {
31fd39a3a3d544b1a8afb9aef07f180d0d40fda2Timo Sirainen { "-9223372036854775808", 0, -9223372036854775807-1 },
31fd39a3a3d544b1a8afb9aef07f180d0d40fda2Timo Sirainen int ret = str_to_llong(i64tests[i].input, &val);
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen/* Assumes int is 32 bit, 2's complement */
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainenstatic void test_str_to_i32(void)
e18e90938ffd9e31c796c405404be0b7dcd5c807Timo Sirainen unsigned int i;
b10c3f9ed997748fdbb03b9daadc8c31eed02120Timo Sirainen const struct {
2f19f8ff906a0017b906763e0f7675d49ab0e58fTimo Sirainen int ret = str_to_int(i32tests[i].input, &val);
c8593b070319d0ff83f8d6c4b5ed5abf2d578a06Timo Sirainen /* If the above isn't true, then we do expect some failures possibly */