]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add case that exercises fr_size_to_str() bug and correct the bug. (#4567)
authorJames Jones <jejones3141@gmail.com>
Thu, 16 Jun 2022 13:59:58 +0000 (08:59 -0500)
committerGitHub <noreply@github.com>
Thu, 16 Jun 2022 13:59:58 +0000 (08:59 -0500)
Unfortunately it really needs to know the number of trailing
zeroes in the decimal form as well as binary, which will slow
things to an extent.

src/lib/util/size.c
src/lib/util/size_tests.c

index cf37861a60c8c8e4c51f42e44747af8316de6104..f4fed21499dc7d975f7d765872856eb5b4e4b9ca 100644 (file)
@@ -173,28 +173,22 @@ fr_slen_t fr_size_to_str(fr_sbuff_t *out, size_t in)
                                };
        fr_size_unit_t const *unit = &base10_units[0];
 
-       uint8_t pos = fr_low_bit_pos(in);
+       int8_t pos2 = fr_low_bit_pos(in) - 1;
+       int8_t pos10;
+       size_t temp;
 
        /*
-        *      Fast path - Won't be divisible by 1000
+        *      Fast path - Won't be divisible by a power of 1000 or a power of 1024
         */
-       if (pos < 3) {
-               goto done;
-       } else if ((in % 1000) == 0) {
-                /*
-                 *     For powers of 10, exp equals the
-                 *     number of contiguous zero low order bits.
-                 */
-               unit = &base10_units[(pos - 1) / 3];
+       if (pos2 < 3) goto done;
 
        /*
-        *      Fast path - Won't be divisible by 1024
+        *      Get a count of trailing decimal zeroes.
         */
-       } else if (pos < 10) {
-               goto done;
-       } else if ((in % 1024) == 0) {
-               unit = &base2_units[(pos - 1) / 10];
-       }
+       for (temp = in, pos10 = 0; temp && temp % 10 == 0; pos10++) temp /= 10;
+
+       if (pos10 >= 3) unit = &base10_units[(pos10) / 3];
+       else if (pos2 >= 10) unit = &base2_units[pos2 / 10];
 
 done:
        return fr_sbuff_in_sprintf(&our_out, "%zu%s", in / unit->mul, unit->suffix);
index 5f64da4ff2f04d478075d33e9aaf39cb857b8f36..96e5065cf9bef4d38cb3ed3838d370086cb2e824 100644 (file)
@@ -294,6 +294,9 @@ static void test_size_print_base10(void)
        TEST_CHECK_SLEN(fr_size_to_str(test_out(buff), (size_t)1000 * 1000), 3);
        TEST_CHECK_STRCMP(buff, "1MB");
 
+       TEST_CHECK_SLEN(fr_size_to_str(test_out(buff), (size_t)1000 * 1000 + 64000), 6);
+       TEST_CHECK_STRCMP(buff, "1064KB");
+
        TEST_CHECK_SLEN(fr_size_to_str(test_out(buff), (size_t)1000 * 1000 * 1000), 3);
        TEST_CHECK_STRCMP(buff, "1GB");