summaryrefslogtreecommitdiffstats
path: root/byterun/ints.c
diff options
context:
space:
mode:
Diffstat (limited to 'byterun/ints.c')
-rw-r--r--byterun/ints.c17
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);
}