diff options
-rw-r--r-- | src/integer.h | 42 | ||||
-rw-r--r-- | tests/core/integer.c | 253 | ||||
-rw-r--r-- | tests/core/strtol.c | 2 |
3 files changed, 292 insertions, 5 deletions
diff --git a/src/integer.h b/src/integer.h index 724e076a0..a3a0f53ee 100644 --- a/src/integer.h +++ b/src/integer.h @@ -166,15 +166,47 @@ GIT_INLINE(bool) git__add_int64_overflow(int64_t *out, int64_t one, int64_t two) #if !defined(git__multiply_int64_overflow) GIT_INLINE(bool) git__multiply_int64_overflow(int64_t *out, int64_t one, int64_t two) { - if ((one == -1 && two == INT64_MIN) || - (two == -1 && one == INT64_MIN)) - return true; + /* + * Detects whether `INT64_MAX < (one * two) || INT64_MIN > (one * two)`, + * without incurring in undefined behavior. That is done by performing the + * comparison with a division instead of a multiplication, which translates + * to `INT64_MAX / one < two || INT64_MIN / one > two`. Some caveats: + * + * - The comparison sign is inverted when both sides of the inequality are + * multiplied/divided by a negative number, so if `one < 0` the comparison + * needs to be flipped. + * - `INT64_MAX / -1` itself overflows (or traps), so that case should be + * avoided. + * - Since the overflow flag is defined as the discrepance between the result + * of performing the multiplication in a signed integer at twice the width + * of the operands, and the truncated+sign-extended version of that same + * result, there are four cases where the result is the opposite of what + * would be expected: + * * `INT64_MIN * -1` / `-1 * INT64_MIN` + * * `INT64_MIN * 1 / `1 * INT64_MIN` + */ if (one && two) { - if (one > 0 == two > 0) { + if (one > 0 && two > 0) { if (INT64_MAX / one < two) return true; + } else if (one < 0 && two < 0) { + if ((one == -1 && two == INT64_MIN) || + (two == -1 && one == INT64_MIN)) { + *out = INT64_MIN; + return false; + } + if (INT64_MAX / one > two) + return true; + } else if (one > 0 && two < 0) { + if ((one == 1 && two == INT64_MIN) || + (INT64_MIN / one > two)) + return true; + } else if (one == -1) { + if (INT64_MIN / two > one) + return true; } else { - if (INT64_MIN / one < two) + if ((one == INT64_MIN && two == 1) || + (INT64_MIN / one < two)) return true; } } diff --git a/tests/core/integer.c b/tests/core/integer.c new file mode 100644 index 000000000..bd19651af --- /dev/null +++ b/tests/core/integer.c @@ -0,0 +1,253 @@ +#include "clar_libgit2.h" + +void test_core_integer__multiply_int64_no_overflow(void) +{ +#if !defined(git__multiply_int64_overflow) + int64_t result = 0; + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x1ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x1ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x2ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x2ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x7ffffffffffffffll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x7ffffffffffffffll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x800000000000000ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x800000000000000ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x7fffffffffffffffll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x7fffffffffffffffll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x8000000000000000ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x1ll)); + cl_assert_equal_i(result, 0x1ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x1ll)); + cl_assert_equal_i(result, -0x1ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x2ll)); + cl_assert_equal_i(result, 0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x2ll)); + cl_assert_equal_i(result, -0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x7ffffffffffffffll)); + cl_assert_equal_i(result, 0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x7ffffffffffffffll)); + cl_assert_equal_i(result, -0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x800000000000000ll)); + cl_assert_equal_i(result, 0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x800000000000000ll)); + cl_assert_equal_i(result, -0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x7fffffffffffffffll)); + cl_assert_equal_i(result, 0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x7fffffffffffffffll)); + cl_assert_equal_i(result, -0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x1ll)); + cl_assert_equal_i(result, -0x1ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x1ll)); + cl_assert_equal_i(result, 0x1ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x2ll)); + cl_assert_equal_i(result, -0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x2ll)); + cl_assert_equal_i(result, 0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x7ffffffffffffffll)); + cl_assert_equal_i(result, -0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x7ffffffffffffffll)); + cl_assert_equal_i(result, 0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x800000000000000ll)); + cl_assert_equal_i(result, -0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x800000000000000ll)); + cl_assert_equal_i(result, 0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x7fffffffffffffffll)); + cl_assert_equal_i(result, -0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x7fffffffffffffffll)); + cl_assert_equal_i(result, 0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x1ll)); + cl_assert_equal_i(result, 0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x1ll)); + cl_assert_equal_i(result, -0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x2ll)); + cl_assert_equal_i(result, 0x4ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x2ll)); + cl_assert_equal_i(result, -0x4ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x7ffffffffffffffll)); + cl_assert_equal_i(result, 0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x7ffffffffffffffll)); + cl_assert_equal_i(result, -0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x800000000000000ll)); + cl_assert_equal_i(result, 0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x800000000000000ll)); + cl_assert_equal_i(result, -0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x1ll)); + cl_assert_equal_i(result, -0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x1ll)); + cl_assert_equal_i(result, 0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x2ll)); + cl_assert_equal_i(result, -0x4ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x2ll)); + cl_assert_equal_i(result, 0x4ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x7ffffffffffffffll)); + cl_assert_equal_i(result, -0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x7ffffffffffffffll)); + cl_assert_equal_i(result, 0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x800000000000000ll)); + cl_assert_equal_i(result, -0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x800000000000000ll)); + cl_assert_equal_i(result, 0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x4000000000000000ll)); + cl_assert_equal_i(result, -0x8000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x1ll)); + cl_assert_equal_i(result, 0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x1ll)); + cl_assert_equal_i(result, -0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x2ll)); + cl_assert_equal_i(result, 0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x2ll)); + cl_assert_equal_i(result, -0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x1ll)); + cl_assert_equal_i(result, -0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x1ll)); + cl_assert_equal_i(result, 0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x2ll)); + cl_assert_equal_i(result, -0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x2ll)); + cl_assert_equal_i(result, 0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x1ll)); + cl_assert_equal_i(result, 0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x1ll)); + cl_assert_equal_i(result, -0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x2ll)); + cl_assert_equal_i(result, 0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x2ll)); + cl_assert_equal_i(result, -0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x1ll)); + cl_assert_equal_i(result, -0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x1ll)); + cl_assert_equal_i(result, 0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x2ll)); + cl_assert_equal_i(result, -0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x2ll)); + cl_assert_equal_i(result, 0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x1ll)); + cl_assert_equal_i(result, 0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x1ll)); + cl_assert_equal_i(result, -0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x4000000000000000ll, 0x2ll)); + cl_assert_equal_i(result, -0x8000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x1ll)); + cl_assert_equal_i(result, -0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x1ll)); + cl_assert_equal_i(result, 0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); +#endif +} + +void test_core_integer__multiply_int64_overflow(void) +{ +#if !defined(git__multiply_int64_overflow) + int64_t result = 0; + cl_assert(git__multiply_int64_overflow(&result, 0x2ll, 0x4000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x2ll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x2ll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x2ll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x2ll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x2ll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x2ll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x4000000000000000ll, 0x2ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x2ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x2ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x2ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x2ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x2ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x2ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x8000000000000000ll)); +#endif +} + +void test_core_integer__multiply_int64_edge_cases(void) +{ +#if !defined(git__multiply_int64_overflow) + int64_t result = 0; + cl_assert(!git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x1ll)); + cl_assert_equal_i(result, -0x8000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x8000000000000000ll)); + cl_assert_equal_i(result, -0x8000000000000000ll); + cl_assert(git__multiply_int64_overflow(&result, 0x1ll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x1ll)); +#endif +} diff --git a/tests/core/strtol.c b/tests/core/strtol.c index 25dbe467c..cac6ca56b 100644 --- a/tests/core/strtol.c +++ b/tests/core/strtol.c @@ -30,6 +30,7 @@ void test_core_strtol__int32(void) { assert_l32_parses("123", 123, 10); assert_l32_parses(" +123 ", 123, 10); + assert_l32_parses(" -123 ", -123, 10); assert_l32_parses(" +2147483647 ", 2147483647, 10); assert_l32_parses(" -2147483648 ", -2147483648LL, 10); assert_l32_parses("A", 10, 16); @@ -46,6 +47,7 @@ void test_core_strtol__int64(void) { assert_l64_parses("123", 123, 10); assert_l64_parses(" +123 ", 123, 10); + assert_l64_parses(" -123 ", -123, 10); assert_l64_parses(" +2147483647 ", 2147483647, 10); assert_l64_parses(" -2147483648 ", -2147483648LL, 10); assert_l64_parses(" 2147483657 ", 2147483657LL, 10); |