]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Added some tests for the new strnum _hex() and _oct() function variants.
authorStephan Bosch <stephan@rename-it.nl>
Mon, 7 Sep 2015 22:27:18 +0000 (01:27 +0300)
committerStephan Bosch <stephan@rename-it.nl>
Mon, 7 Sep 2015 22:27:18 +0000 (01:27 +0300)
src/lib/test-strnum.c

index 19d5fc4332efdb76120389e6186b4b1d0fc9b6d4..569551afd229b759aa408976d10bae2611ecb61a 100644 (file)
@@ -23,7 +23,6 @@ static int crappy_uintmax_to_str(char *into, uintmax_t val)
 #undef STRINGIFY
 #undef BIGBASE
 }
-
 static void test_str_to_uintmax(void)
 {
        unsigned int i=0;
@@ -73,12 +72,158 @@ static void test_str_to_uintmax(void)
                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 @@ void test_strnum(void)
 {
        /* 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();