diff options
-rw-r--r-- | Changes | 2 | ||||
-rw-r--r-- | byterun/ints.c | 23 | ||||
-rw-r--r-- | stdlib/scanf.ml | 3 |
3 files changed, 17 insertions, 11 deletions
@@ -45,6 +45,8 @@ Runtime system: (Peter Zotov, review by Jacques-Henri Jourdan) Standard library: +- PR#6316: Scanf.scanf failure on %u formats when reading big integers + (Xavier Leroy, BenoƮt Vaugon) - PR#6390, GPR#36: expose Sys.{int_size,max_wosize} for improved js_of_ocaml portability (Hugo Heuzard) * PR#6494: Add equal function in modules diff --git a/byterun/ints.c b/byterun/ints.c index ee1f05fa45..fa7aaa3271 100644 --- a/byterun/ints.c +++ b/byterun/ints.c @@ -23,6 +23,7 @@ static char * parse_sign_and_base(char * p, /*out*/ int * base, + /*out*/ int * signedness, /*out*/ int * sign) { *sign = 1; @@ -30,15 +31,17 @@ static char * parse_sign_and_base(char * p, *sign = -1; p++; } - *base = 10; + *base = 10; *signedness = 1; if (*p == '0') { switch (p[1]) { case 'x': case 'X': - *base = 16; p += 2; break; + *base = 16; *signedness = 0; p += 2; break; case 'o': case 'O': - *base = 8; p += 2; break; + *base = 8; *signedness = 0; p += 2; break; case 'b': case 'B': - *base = 2; p += 2; break; + *base = 2; *signedness = 0; p += 2; break; + case 'u': case 'U': + *signedness = 0; p += 2; break; } } return p; @@ -65,9 +68,9 @@ static intnat parse_intnat(value s, int nbits, const char *errmsg) { char * p; uintnat res, threshold; - int sign, base, d; + int sign, base, signedness, d; - p = parse_sign_and_base(String_val(s), &base, &sign); + p = parse_sign_and_base(String_val(s), &base, &signedness, &sign); threshold = ((uintnat) -1) / base; d = parse_digit(*p); if (d < 0 || d >= base) caml_failwith(errmsg); @@ -85,7 +88,7 @@ static intnat parse_intnat(value s, int nbits, const char *errmsg) if (p != String_val(s) + caml_string_length(s)){ caml_failwith(errmsg); } - if (base == 10) { + if (signedness) { /* Signed representation expected, allow -2^(nbits-1) to 2^(nbits-1) - 1 */ if (sign >= 0) { if (res >= (uintnat)1 << (nbits - 1)) caml_failwith(errmsg); @@ -530,9 +533,9 @@ CAMLprim value caml_int64_of_string(value s) { char * p; uint64_t res, threshold; - int sign, base, d; + int sign, base, signedness, d; - p = parse_sign_and_base(String_val(s), &base, &sign); + p = parse_sign_and_base(String_val(s), &base, &signedness, &sign); threshold = ((uint64_t) -1) / base; d = parse_digit(*p); if (d < 0 || d >= base) caml_failwith(INT64_ERRMSG); @@ -551,7 +554,7 @@ CAMLprim value caml_int64_of_string(value s) if (p != String_val(s) + caml_string_length(s)){ caml_failwith(INT64_ERRMSG); } - if (base == 10) { + if (signedness) { /* Signed representation expected, allow -2^63 to 2^63 - 1 only */ if (sign >= 0) { if (res >= (uint64_t)1 << 63) caml_failwith(INT64_ERRMSG); diff --git a/stdlib/scanf.ml b/stdlib/scanf.ml index 08fc9aba50..948808830c 100644 --- a/stdlib/scanf.ml +++ b/stdlib/scanf.ml @@ -500,7 +500,8 @@ let token_bool ib = let token_int_literal conv ib = let tok = match conv with - | 'd' | 'i' | 'u' -> Scanning.token ib + | 'd' | 'i' -> Scanning.token ib + | 'u' -> "0u" ^ Scanning.token ib | 'o' -> "0o" ^ Scanning.token ib | 'x' | 'X' -> "0x" ^ Scanning.token ib | 'b' -> "0b" ^ Scanning.token ib |