test-strnum.c revision 87b4215acbf020aa5b8dea686b23fc664140cda0
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2014-2015 Dovecot authors, see the included COPYING file */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen#define VALID(n) { #n, 0, n }
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen/* always pads with leading zeros to a size of 9 digits */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenstatic int crappy_uintmax_to_str(char *into, uintmax_t val)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen len = crappy_uintmax_to_str(into, val/BIGBASE);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenstatic void test_str_to_uintmax(void)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen unsigned int i=0;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen int randrange = rand()%15+1; /* when 1, will max out on 1s */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen char buff[50]; /* totally assumes < 159 bits */
bd63b5b860658b01b1f46f26d406e1e4a9dc019aTimo Sirainen value -= rand()%randrange; /* don't always test the same numbers */
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen /* test with trailing noise */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen buff[len] = 'x'; /* don't even null-terminate, let's be evil */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen test_assert_idx(value_back == 0x1234567890123456, i);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen ret = str_parse_uintmax(buff, &value_back, &endp);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen /* not knowing exactly how large a uintmax_t is, we have to construct
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen the troublesome near-10/9*MAX strings manually by appending digits
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen to a MAX/9 string which we can easily create. Do a wider range
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen of 30 rather than the obvious 10, just in case - all are too large.*/
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen test_begin("str_to_uintmax overflow corner case");
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen for(i = 0; i <= 30; ++i) {
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen test_assert_idx(ret < 0 && value == UINTMAX_MAX/9-1, i);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen/* always pads with leading zeros to a size of 9 digits */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenstatic int crappy_uintmax_to_str_hex(char *into, uintmax_t val)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen len = crappy_uintmax_to_str_hex(into, val/BIGBASE);
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen unsigned int i=0;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen int randrange = rand()%15+1; /* when 1, will max out on 1s */
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen char buff[52]; /* totally assumes < 200 bits */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen value -= rand()%randrange; /* don't always test the same numbers */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen /* test with trailing noise */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen buff[len] = 'x'; /* don't even null-terminate, let's be evil */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen test_assert_idx(value_back == 0x1234567890123456, i);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen ret = str_parse_uintmax_hex(buff, &value_back, &endp);
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen /* not knowing exactly how large a uintmax_t is, we have to construct
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen the troublesome near-0x10/0x0F*MAX strings manually by appending digits
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen to a MAX/0x0f string which we can easily create. Do a wider range
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen of 0x30 rather than the obvious 0x10, just in case - all are too large.*/
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen test_begin("str_to_uintmax_hex overflow corner case");
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen for(i = 0; i <= 0x30; ++i) {
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen test_assert_idx(ret < 0 && value == UINTMAX_MAX/0x0f-1, i);
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen/* always pads with leading zeros to a size of 9 digits */
ce3faaaaab3e2d45b023396287e02f88e5c76e74Timo Sirainenstatic int crappy_uintmax_to_str_oct(char *into, uintmax_t val)
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen len = crappy_uintmax_to_str_oct(into, val/BIGBASE);
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen unsigned int i=0;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen int randrange = rand()%15+1; /* when 1, will max out on 1s */
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen char buff[69]; /* totally assumes < 200 bits */
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen value -= rand()%randrange; /* don't always test the same numbers */
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen /* test with trailing noise */
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen buff[len] = 'x'; /* don't even null-terminate, let's be evil */
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen test_assert_idx(value_back == 0x1234567890123456, i);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen ret = str_parse_uintmax_oct(buff, &value_back, &endp);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen /* not knowing exactly how large a uintmax_t is, we have to construct
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen the troublesome near-010/007*MAX strings manually by appending digits
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen to a MAX/007 string which we can easily create. Do a wider range
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen of 030 rather than the obvious 010, just in case - all are too large.*/
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen test_begin("str_to_uintmax_oct overflow corner case");
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen for(i = 0; i <= 030; ++i) {
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen test_assert_idx(ret < 0 && value == UINTMAX_MAX/007-1, i);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenstatic void test_str_to_u64(void)
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen unsigned int i;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen const struct {
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen VALID(000000000000000000000000000000000000000000000000000000000000000),
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen { "000000000000000000000000000000000000000000000000000001000000001", 0, 1000000001 },
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen { "18446744073709551615", 0, 18446744073709551615ULL },
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen INVALID(20496382304121724010), /* 2^64*10/9 doesn't wrap */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen INVALID(20496382304121724017), /* 2^64*10/9 wraps only after addition */
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen INVALID(20496382304121724020), /* 2^64*10/9 wraps on multiply*/
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen int ret = str_to_uint64(u64tests[i].input, &val);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen test_assert_idx(val == 0xBADBEEF15BADF00D, i);
bd4d0a1a7c0626452b8d82f37e3ec07267ac9896Timo Sirainen const char *longer = t_strconcat(u64tests[i].input, "x", NULL);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenstatic void test_str_to_u32(void)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen unsigned int i;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen const struct {
56963ffad65b860c827553dfaf09fb766cb7e20eTimo Sirainen int ret = str_to_uint32(u32tests[i].input, &val);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen/* Assumes long long is 64 bit, 2's complement */
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainenstatic void test_str_to_llong(void)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen unsigned int i;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen const struct {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen { "-9223372036854775808", 0, -9223372036854775807-1 },
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen int ret = str_to_llong(i64tests[i].input, &val);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen/* Assumes int is 32 bit, 2's complement */
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainenstatic void test_str_to_i32(void)
b87daa509bf5b306189282a9df795d094a6d7150Timo Sirainen unsigned int i;
b87daa509bf5b306189282a9df795d094a6d7150Timo Sirainen const struct {
eca38954bcf972618f6b85932a3690acbd2b673aTimo Sirainen int ret = str_to_int(i32tests[i].input, &val);
5666a3d6a7ea89362b8d9e8b39b15424cd9d6388Timo Sirainen /* If the above isn't true, then we do expect some failures possibly */