diff --git a/double-conversion/string-to-double.cc b/double-conversion/string-to-double.cc index 950b248..6a5aabf 100644 --- a/double-conversion/string-to-double.cc +++ b/double-conversion/string-to-double.cc @@ -233,7 +233,8 @@ template static bool IsHexFloatString(Iterator start, Iterator end, uc16 separator, - bool allow_trailing_junk) { + bool allow_trailing_junk, + bool allow_trailing_spaces) { DOUBLE_CONVERSION_ASSERT(start != end); Iterator current = start; @@ -264,7 +265,10 @@ static bool IsHexFloatString(Iterator start, while (isDigit(*current, 10)) { if (Advance(¤t, kNoSeparator, 16, end)) return true; } - return allow_trailing_junk || !AdvanceToNonspace(¤t, end); + // Trailing whitespace is junk unless ALLOW_TRAILING_SPACES is set, as it is + // for decimal numbers. + if (allow_trailing_junk) return true; + return allow_trailing_spaces && !AdvanceToNonspace(¤t, end); } @@ -279,12 +283,14 @@ static double RadixStringToIeee(Iterator* current, uc16 separator, bool parse_as_hex_float, bool allow_trailing_junk, + bool allow_trailing_spaces, double junk_string_value, bool read_as_double, bool* result_is_junk) { DOUBLE_CONVERSION_ASSERT(*current != end); DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float || - IsHexFloatString(*current, end, separator, allow_trailing_junk)); + IsHexFloatString(*current, end, separator, allow_trailing_junk, + allow_trailing_spaces)); const int kDoubleSize = Double::kSignificandSize; const int kSingleSize = Single::kSignificandSize; @@ -326,7 +332,10 @@ static double RadixStringToIeee(Iterator* current, } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) { break; } else { - if (allow_trailing_junk || !AdvanceToNonspace(current, end)) { + // Trailing whitespace is junk unless ALLOW_TRAILING_SPACES is set, as it + // is for decimal numbers. + if (allow_trailing_junk || + (allow_trailing_spaces && !AdvanceToNonspace(current, end))) { break; } else { return junk_string_value; @@ -370,10 +379,11 @@ static double RadixStringToIeee(Iterator* current, } } - if (!parse_as_hex_float && - !allow_trailing_junk && - AdvanceToNonspace(current, end)) { - return junk_string_value; + if (!parse_as_hex_float && !allow_trailing_junk) { + if (allow_trailing_spaces ? AdvanceToNonspace(current, end) + : *current != end) { + return junk_string_value; + } } int middle_value = (1 << (overflow_bits_count - 1)); @@ -562,7 +572,8 @@ double StringToDoubleConverter::StringToIeee( if (current == end) return junk_string_value_; // "0x" bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) && - IsHexFloatString(current, end, separator_, allow_trailing_junk); + IsHexFloatString(current, end, separator_, allow_trailing_junk, + allow_trailing_spaces); if (!parse_as_hex_float && !isDigit(*current, 16)) { return junk_string_value_; @@ -575,6 +586,7 @@ double StringToDoubleConverter::StringToIeee( separator_, parse_as_hex_float, allow_trailing_junk, + allow_trailing_spaces, junk_string_value_, read_as_double, &result_is_junk); @@ -748,6 +760,7 @@ double StringToDoubleConverter::StringToIeee( separator_, false, // Don't parse as hex_float. allow_trailing_junk, + allow_trailing_spaces, junk_string_value_, read_as_double, &result_is_junk); diff --git a/test/cctest/test-conversions.cc b/test/cctest/test-conversions.cc index a56268c..369b644 100644 --- a/test/cctest/test-conversions.cc +++ b/test/cctest/test-conversions.cc @@ -2742,6 +2742,21 @@ TEST(StringToDoubleHexString) { &processed, &all_used)); CHECK_EQ(0, processed); + // Trailing whitespace is junk without ALLOW_TRAILING_SPACES, as for + // decimal numbers. + CHECK_EQ(Double::NaN(), StrToD("0x12 ", flags, 0.0, + &processed, &all_used)); + CHECK_EQ(0, processed); + + CHECK_EQ(Double::NaN(), StrToD("0x12\t\n", flags, 0.0, + &processed, &all_used)); + CHECK_EQ(0, processed); + + // Same for a significand that overflows 53 bits. + CHECK_EQ(Double::NaN(), StrToD("0x10000000000000000 ", flags, 0.0, + &processed, &all_used)); + CHECK_EQ(0, processed); + CHECK_EQ(Double::NaN(), StrToD("+", flags, 0.0, &processed, &all_used)); CHECK_EQ(0, processed); @@ -3196,6 +3211,29 @@ TEST(StringToDoubleHexString) { CHECK_EQ(0.0, StrToD("0x1.p-10000000000000000", flags, 0.0, &processed, &all_used)); CHECK(all_used); + + // Trailing whitespace is junk without ALLOW_TRAILING_SPACES, as for + // decimal numbers. + CHECK_EQ(Double::NaN(), StrToD("0x3p0 ", flags, 0.0, + &processed, &all_used)); + CHECK_EQ(0, processed); + + CHECK_EQ(Double::NaN(), StrToD("0x3.p0 ", flags, 0.0, + &processed, &all_used)); + CHECK_EQ(0, processed); + + CHECK_EQ(Double::NaN(), StrToD("0x10000000000000001p0 ", flags, 0.0, + &processed, &all_used)); + CHECK_EQ(0, processed); + + flags = StringToDoubleConverter::ALLOW_HEX_FLOATS | + StringToDoubleConverter::ALLOW_TRAILING_SPACES; + + CHECK_EQ(3.0, StrToD("0x3p0 ", flags, 0.0, &processed, &all_used)); + CHECK(all_used); + + CHECK_EQ(3.0, StrToD("0x3.p0 ", flags, 0.0, &processed, &all_used)); + CHECK(all_used); }