diff options
Diffstat (limited to 'byterun/ints.c')
-rw-r--r-- | byterun/ints.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/byterun/ints.c b/byterun/ints.c index 5fc15c626..7b8a13675 100644 --- a/byterun/ints.c +++ b/byterun/ints.c @@ -83,9 +83,12 @@ static intnat parse_intnat(value s, int nbits) caml_failwith("int_of_string"); } if (base == 10) { - /* Signed representation expected, allow -2^(nbits-1) to 2^(nbits - 1) */ - if (res > (uintnat)1 << (nbits - 1)) - caml_failwith("int_of_string"); + /* Signed representation expected, allow -2^(nbits-1) to 2^(nbits-1) - 1 */ + if (sign >= 0) { + if (res >= (uintnat)1 << (nbits - 1)) caml_failwith("int_of_string"); + } else { + if (res > (uintnat)1 << (nbits - 1)) caml_failwith("int_of_string"); + } } else { /* Unsigned representation expected, allow 0 to 2^nbits - 1 and tolerate -(2^nbits - 1) to 0 */ @@ -540,7 +543,8 @@ CAMLprim value caml_int64_of_string(value s) { char * p; uint64 max_uint64 = I64_literal(0xFFFFFFFF, 0xFFFFFFFF); - uint64 max_int64 = I64_literal(0x80000000, 0x00000000); + uint64 max_int64_pos = I64_literal(0x7FFFFFFF, 0xFFFFFFFF); + uint64 max_int64_neg = I64_literal(0x80000000, 0x00000000); uint64 res, threshold; int sign, base, d; @@ -563,7 +567,10 @@ CAMLprim value caml_int64_of_string(value s) if (p != String_val(s) + caml_string_length(s)){ caml_failwith("int_of_string"); } - if (base == 10 && I64_ult(max_int64, res)) caml_failwith("int_of_string"); + if (base == 10) { + if (I64_ult((sign >= 0 ? max_int64_pos : max_int64_neg), res)) + caml_failwith("int_of_string"); + } if (sign < 0) res = I64_neg(res); return caml_copy_int64(res); } |