On Thu, Jun 01, 2023 at 05:02:50PM -0500, Eric Blake wrote: > We have quite a few undertested and underdocumented integer parsing > corner cases. To ensure that any changes we make in the code are > intentional rather than accidental semantic changes, it is time to add > more unit tests of existing behavior. > > static void test_qemu_strtol_overflow(void) > { > - const char *str = "99999999999999999999999999999999999999999999"; > + const char *str; > + const char *endptr; > + long res; > + int err; > + > + /* 1 more than LONG_MAX */ > + str = LONG_MAX == INT_MAX ? "2147483648" : "9223372036854775808"; > + endptr = "somewhere"; > + res = 999; > + err = qemu_strtol(str, &endptr, 0, &res); > + g_assert_cmpint(err, ==, -ERANGE); > + g_assert_cmpint(res, ==, LONG_MAX); > + g_assert_true(endptr == str + strlen(str)); > + > + if (LONG_MAX == INT_MAX) { > + str = "0xffffffff00000001"; /* ULLONG_MAX - UINT_MAX + 1 (not 1) */ > + endptr = "somewhere"; > + res = 999; > + err = qemu_strtol(str, &endptr, 0, &res); > + g_assert_cmpint(err, ==, -ERANGE); > + g_assert_cmpint(res, ==, LONG_MIN); > + g_assert_true(endptr == str + strlen(str)); > + }
Copy-paste failure, but only visible on platforms like mingw where long is 32-bits; I had copied this... > > static void test_qemu_strtol_underflow(void) > { > - const char *str = "-99999999999999999999999999999999999999999999"; > - char f = 'X'; > - const char *endptr = &f; > - long res = 999; > + const char *str; > + const char *endptr; > + long res; > int err; > > + /* 1 less than LONG_MIN */ > + str = LONG_MIN == INT_MIN ? "-2147483649" : "-9223372036854775809"; > + endptr = "somewhere"; > + res = 999; > err = qemu_strtol(str, &endptr, 0, &res); > + g_assert_cmpint(err, ==, -ERANGE); > + g_assert_cmpint(res, ==, LONG_MIN); > + g_assert_true(endptr == str + strlen(str)); > > + if (LONG_MAX == INT_MAX) { > + str = "-18446744073709551615"; /* -UINT64_MAX (not 1) */ > + endptr = "somewhere"; > + res = 999; > + err = qemu_strtol(str, &endptr, 0, &res); > + g_assert_cmpint(err, ==, -ERANGE); > + g_assert_cmpint(res, ==, LONG_MIN); > + g_assert_true(endptr == str + strlen(str)); > + } ...from here, but failed to s/MIN/MAX/ when dealing with the changed sign. Yay for CI catching it. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org