diff options
author | Nick Mathewson <nickm@torproject.org> | 2014-09-10 23:57:31 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2014-09-10 23:57:31 -0400 |
commit | d2463c0cfee066111c3a72d188cd897957aa2988 (patch) | |
tree | aa7ae9404818663427882a61f59a03ab6434ba55 /src/test/test_util.c | |
parent | 3c2c6a61163cd6a42cc0eeee9fc43200b9f08503 (diff) | |
download | tor-d2463c0cfee066111c3a72d188cd897957aa2988.tar.gz tor-d2463c0cfee066111c3a72d188cd897957aa2988.zip |
Avoid overflows and underflows in sscanf and friends
(Patch from teor on 13104)
Diffstat (limited to 'src/test/test_util.c')
-rw-r--r-- | src/test/test_util.c | 167 |
1 files changed, 154 insertions, 13 deletions
diff --git a/src/test/test_util.c b/src/test/test_util.c index 151ec69127..16a2927e4d 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -1672,6 +1672,7 @@ static void test_util_sscanf(void) { unsigned u1, u2, u3; + unsigned long ulng; char s1[20], s2[10], s3[10], ch; int r; long lng1,lng2; @@ -1713,11 +1714,6 @@ test_util_sscanf(void) test_eq(0, tor_sscanf("", "%u", &u1)); /* absent number */ test_eq(0, tor_sscanf("A", "%u", &u1)); /* bogus number */ test_eq(0, tor_sscanf("-1", "%u", &u1)); /* negative number */ - test_eq(1, tor_sscanf("4294967295", "%u", &u1)); /* UINT32_MAX should work */ - test_eq(4294967295u, u1); - test_eq(0, tor_sscanf("4294967296", "%u", &u1)); /* But not at 32 bits */ - test_eq(1, tor_sscanf("4294967296", "%9u", &u1)); /* but parsing only 9... */ - test_eq(429496729u, u1); /* Numbers with size (eg. %2u) */ test_eq(0, tor_sscanf("-1", "%2u", &u1)); @@ -1812,46 +1808,191 @@ test_util_sscanf(void) test_eq(int2, -1); #if SIZEOF_INT == 4 + /* %u */ + /* UINT32_MAX should work */ + test_eq(1, tor_sscanf("4294967295", "%u", &u1)); + test_eq(4294967295U, u1); + + /* But UINT32_MAX + 1 shouldn't work */ + test_eq(0, tor_sscanf("4294967296", "%u", &u1)); + /* but parsing only 9... */ + test_eq(1, tor_sscanf("4294967296", "%9u", &u1)); + test_eq(429496729U, u1); + + /* %x */ + /* UINT32_MAX should work */ + test_eq(1, tor_sscanf("FFFFFFFF", "%x", &u1)); + test_eq(0xFFFFFFFF, u1); + + /* But UINT32_MAX + 1 shouldn't work */ + test_eq(0, tor_sscanf("100000000", "%x", &u1)); + + /* %d */ + /* INT32_MIN and INT32_MAX should work */ r = tor_sscanf("-2147483648. 2147483647.", "%d. %d.", &int1, &int2); test_eq(r,2); - test_eq(int1, -2147483647-1); + test_eq(int1, -2147483647 - 1); test_eq(int2, 2147483647); - r = tor_sscanf("-2147483679.", "%d.", &int1); + /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */ + r = tor_sscanf("-2147483649.", "%d.", &int1); test_eq(r,0); - r = tor_sscanf("2147483678.", "%d.", &int1); + r = tor_sscanf("2147483648.", "%d.", &int1); + test_eq(r,0); + + /* and the first failure stops further processing */ + r = tor_sscanf("-2147483648. 2147483648.", + "%d. %d.", &int1, &int2); + test_eq(r,1); + + r = tor_sscanf("-2147483649. 2147483647.", + "%d. %d.", &int1, &int2); + test_eq(r,0); + + r = tor_sscanf("2147483648. -2147483649.", + "%d. %d.", &int1, &int2); test_eq(r,0); #elif SIZEOF_INT == 8 + /* %u */ + /* UINT64_MAX should work */ + test_eq(1, tor_sscanf("18446744073709551615", "%u", &u1)); + test_eq(18446744073709551615U, u1); + + /* But UINT64_MAX + 1 shouldn't work */ + test_eq(0, tor_sscanf("18446744073709551616", "%u", &u1)); + /* but parsing only 19... */ + test_eq(1, tor_sscanf("18446744073709551616", "%19u", &u1)); + test_eq(1844674407370955161U, u1); + + /* %x */ + /* UINT64_MAX should work */ + test_eq(1, tor_sscanf("FFFFFFFFFFFFFFFF", "%x", &u1)); + test_eq(0xFFFFFFFFFFFFFFFF, u1); + + /* But UINT64_MAX + 1 shouldn't work */ + test_eq(0, tor_sscanf("10000000000000000", "%x", &u1)); + + /* %d */ + /* INT64_MIN and INT64_MAX should work */ r = tor_sscanf("-9223372036854775808. 9223372036854775807.", "%d. %d.", &int1, &int2); test_eq(r,2); - test_eq(int1, -9223372036854775807-1); + test_eq(int1, -9223372036854775807 - 1); test_eq(int2, 9223372036854775807); + /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */ r = tor_sscanf("-9223372036854775809.", "%d.", &int1); test_eq(r,0); r = tor_sscanf("9223372036854775808.", "%d.", &int1); test_eq(r,0); + + /* and the first failure stops further processing */ + r = tor_sscanf("-9223372036854775808. 9223372036854775808.", + "%d. %d.", &int1, &int2); + test_eq(r,1); + + r = tor_sscanf("-9223372036854775809. 9223372036854775807.", + "%d. %d.", &int1, &int2); + test_eq(r,0); + + r = tor_sscanf("9223372036854775808. -9223372036854775809.", + "%d. %d.", &int1, &int2); + test_eq(r,0); #endif #if SIZEOF_LONG == 4 + /* %lu */ + /* UINT32_MAX should work */ + test_eq(1, tor_sscanf("4294967295", "%lu", &ulng)); + test_eq(4294967295UL, ulng); + + /* But UINT32_MAX + 1 shouldn't work */ + test_eq(0, tor_sscanf("4294967296", "%lu", &ulng)); + /* but parsing only 9... */ + test_eq(1, tor_sscanf("4294967296", "%9lu", &ulng)); + test_eq(429496729UL, ulng); + + /* %lx */ + /* UINT32_MAX should work */ + test_eq(1, tor_sscanf("FFFFFFFF", "%lx", &ulng)); + test_eq(0xFFFFFFFFUL, ulng); + + /* But UINT32_MAX + 1 shouldn't work */ + test_eq(0, tor_sscanf("100000000", "%lx", &ulng)); + + /* %ld */ + /* INT32_MIN and INT32_MAX should work */ r = tor_sscanf("-2147483648. 2147483647.", "%ld. %ld.", &lng1, &lng2); test_eq(r,2); - test_eq(lng1, -2147483647 - 1); - test_eq(lng2, 2147483647); + test_eq(lng1, -2147483647L - 1L); + test_eq(lng2, 2147483647L); + + /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */ + r = tor_sscanf("-2147483649.", "%ld.", &lng1); + test_eq(r,0); + + r = tor_sscanf("2147483648.", "%ld.", &lng1); + test_eq(r,0); + + /* and the first failure stops further processing */ + r = tor_sscanf("-2147483648. 2147483648.", + "%ld. %ld.", &lng1, &lng2); + test_eq(r,1); + + r = tor_sscanf("-2147483649. 2147483647.", + "%ld. %ld.", &lng1, &lng2); + test_eq(r,0); + + r = tor_sscanf("2147483648. -2147483649.", + "%ld. %ld.", &lng1, &lng2); + test_eq(r,0); #elif SIZEOF_LONG == 8 + /* %lu */ + /* UINT64_MAX should work */ + test_eq(1, tor_sscanf("18446744073709551615", "%lu", &ulng)); + test_eq(18446744073709551615UL, ulng); + + /* But UINT64_MAX + 1 shouldn't work */ + test_eq(0, tor_sscanf("18446744073709551616", "%lu", &ulng)); + /* but parsing only 19... */ + test_eq(1, tor_sscanf("18446744073709551616", "%19lu", &ulng)); + test_eq(1844674407370955161UL, ulng); + + /* %lx */ + /* UINT64_MAX should work */ + test_eq(1, tor_sscanf("FFFFFFFFFFFFFFFF", "%lx", &ulng)); + test_eq(0xFFFFFFFFFFFFFFFFUL, ulng); + + /* But UINT64_MAX + 1 shouldn't work */ + test_eq(0, tor_sscanf("10000000000000000", "%lx", &ulng)); + + /* %ld */ + /* INT64_MIN and INT64_MAX should work */ r = tor_sscanf("-9223372036854775808. 9223372036854775807.", "%ld. %ld.", &lng1, &lng2); test_eq(r,2); - test_eq(lng1, -9223372036854775807L - 1); + test_eq(lng1, -9223372036854775807L - 1L); test_eq(lng2, 9223372036854775807L); + /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */ + r = tor_sscanf("-9223372036854775809.", "%ld.", &lng1); + test_eq(r,0); + + r = tor_sscanf("9223372036854775808.", "%ld.", &lng1); + test_eq(r,0); + + /* and the first failure stops further processing */ r = tor_sscanf("-9223372036854775808. 9223372036854775808.", "%ld. %ld.", &lng1, &lng2); test_eq(r,1); - r = tor_sscanf("-9223372036854775809. 9223372036854775808.", + + r = tor_sscanf("-9223372036854775809. 9223372036854775807.", + "%ld. %ld.", &lng1, &lng2); + test_eq(r,0); + + r = tor_sscanf("9223372036854775808. -9223372036854775809.", "%ld. %ld.", &lng1, &lng2); test_eq(r,0); #endif |