From da5b058decd93c8a067068018ec8c242ab16b39d Mon Sep 17 00:00:00 2001 From: Szilagyi Adam Date: Fri, 24 Jul 2020 15:55:12 +0200 Subject: [PATCH] Fix argument boundary check order during number format conversion (#4031) Also added some tests related to the issues caused by the wrong order JerryScript-DCO-1.0-Signed-off-by: Adam Szilagyi aszilagy@inf.u-szeged.hu --- .../ecma-builtin-number-prototype.c | 23 ++++++++++----- tests/jerry/number-prototype-to-precision.js | 28 +++++++++++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c index 1157b78a2..f44c0ea14 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c @@ -493,17 +493,12 @@ ecma_builtin_number_prototype_object_to_number_convert (ecma_number_t this_num, return to_integer; } - /* Argument boundary checks */ - if (mode != NUMBER_ROUTINE_TO_PRECISION + /* Argument boundary check for toFixed method */ + if (mode == NUMBER_ROUTINE_TO_FIXED && (arg_num <= -1 || arg_num >= 101)) { return ecma_raise_range_error (ECMA_ERR_MSG ("Fraction digits must be between 0 and 100.")); } - else if (mode == NUMBER_ROUTINE_TO_PRECISION - && (arg_num < 1 || arg_num > 100)) - { - return ecma_raise_range_error (ECMA_ERR_MSG ("Precision digits must be between 1 and 100.")); - } /* Handle NaN separately */ if (ecma_number_is_nan (this_num)) @@ -566,6 +561,20 @@ ecma_builtin_number_prototype_object_to_number_convert (ecma_number_t this_num, return ecma_make_string_value (ecma_stringbuilder_finalize (&builder)); } + /* Argument boundary check for toExponential and toPrecision methods */ + if (mode == NUMBER_ROUTINE_TO_EXPONENTIAL + && (arg_num <= -1 || arg_num >= 101)) + { + ecma_stringbuilder_destroy (&builder); + return ecma_raise_range_error (ECMA_ERR_MSG ("Fraction digits must be between 0 and 100.")); + } + else if (mode == NUMBER_ROUTINE_TO_PRECISION + && (arg_num < 1 || arg_num > 100)) + { + ecma_stringbuilder_destroy (&builder); + return ecma_raise_range_error (ECMA_ERR_MSG ("Precision digits must be between 1 and 100.")); + } + num_of_digits = ecma_number_to_decimal (this_num, digits, &exponent); /* Handle undefined argument */ diff --git a/tests/jerry/number-prototype-to-precision.js b/tests/jerry/number-prototype-to-precision.js index ba3bff868..037cca8da 100644 --- a/tests/jerry/number-prototype-to-precision.js +++ b/tests/jerry/number-prototype-to-precision.js @@ -59,3 +59,31 @@ try { } catch (e) { assert(e instanceof TypeError) } + + +assert((+Infinity).toPrecision(1000) === "Infinity"); +var n = new Number(+Infinity); +assert(n.toPrecision(1000) === "Infinity"); + +assert((-Infinity).toPrecision(1000) === "-Infinity"); +var n = new Number(-Infinity); +assert(n.toPrecision(1000) === "-Infinity"); + +assert(NaN.toPrecision(undefined) === "NaN"); + +var calls = 0; + +var p = { + valueOf: function() { + calls++; + return Infinity; + } +}; + +assert(NaN.toPrecision(p) === "NaN"); +assert(calls === 1); + +var n = new Number(NaN); +calls = 0; +assert(n.toPrecision(p) === "NaN"); +assert(calls === 1);