diff --git a/CHANGES.md b/CHANGES.md index 87ab15d50e..cf28c0831c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -29,6 +29,7 @@ ## Bug fixes * Runtime: fix parsing of unsigned integers (0u2147483648) (#1633, #1666) * Runtime: fix incorrect pos_in after unmarshalling +* Runtime: make float_of_string stricter (#1609) * Toplevel: fix missing primitives with separate compilation * Compiler: fix link of packed modules with separate compilation * Compiler: Fixed the static evaluation of some equalities (#1659) diff --git a/compiler/tests-jsoo/test_floats.ml b/compiler/tests-jsoo/test_floats.ml index b67e1fe224..3e19c7d8c9 100644 --- a/compiler/tests-jsoo/test_floats.ml +++ b/compiler/tests-jsoo/test_floats.ml @@ -177,10 +177,38 @@ let%expect_test "log2" = p 1024.0; [%expect {| 10.000000 |}] +let print' f = try print (f ()) with e -> print_endline (Printexc.to_string e) + let%expect_test "of_string" = let x = "0x1.1" in - print (float_of_string x); + print' (fun () -> float_of_string x); [%expect {| 1.062500 |}]; let x = "0x1.1p-1" in - print (float_of_string x); - [%expect {| 0.531250 |}] + print' (fun () -> float_of_string x); + [%expect {| 0.531250 |}]; + let x = " 0x1.1" in + print' (fun () -> float_of_string x); + [%expect {| 1.062500 |}]; + let x = " 0x1.1 " in + print' (fun () -> float_of_string x); + [%expect {| Failure("float_of_string") |}]; + let x = "0x1.1 p-1" in + print' (fun () -> float_of_string x); + [%expect {| Failure("float_of_string") |}] + +let%expect_test "of_string" = + let x = "3.14" in + print' (fun () -> float_of_string x); + [%expect {| 3.140000 |}]; + let x = " 3.14" in + print' (fun () -> float_of_string x); + [%expect {| 3.140000 |}]; + let x = "3. 14" in + print' (fun () -> float_of_string x); + [%expect {| Failure("float_of_string") |}]; + let x = "3.1 4" in + print' (fun () -> float_of_string x); + [%expect {| Failure("float_of_string") |}]; + let x = "3.14 " in + print' (fun () -> float_of_string x); + [%expect {| Failure("float_of_string") |}] diff --git a/runtime/ieee_754.js b/runtime/ieee_754.js index 30d839ab98..f2980625b6 100644 --- a/runtime/ieee_754.js +++ b/runtime/ieee_754.js @@ -562,14 +562,16 @@ function caml_format_float(fmt, x) { //Requires: caml_failwith, caml_jsbytes_of_string function caml_float_of_string(s) { var res; + var r_float = /^ *[-+]?(?:\d*\.?\d+|\d+\.?\d*)(?:[eE][-+]?\d+)?$/; s = caml_jsbytes_of_string(s); res = +s; //Fast path - if (s.length > 0 && !Number.isNaN(res)) return res; + if (!Number.isNaN(res) && r_float.test(s)) return res; s = s.replace(/_/g, ""); res = +s; - if (s.length > 0 && (!Number.isNaN(res) || /^[+-]?nan$/i.test(s))) return res; - var m = /^ *([+-]?)0x([0-9a-f]+)\.?([0-9a-f]*)(p([+-]?[0-9]+))?/i.exec(s); + if ((!Number.isNaN(res) && r_float.test(s)) || /^[+-]?nan$/i.test(s)) + return res; + var m = /^ *([+-]?)0x([0-9a-f]+)\.?([0-9a-f]*)(p([+-]?[0-9]+))?$/i.exec(s); // 1 2 3 5 if (m) { var m3 = m[3].replace(/0+$/, "");