Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions double-conversion/string-to-double.cc
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,17 @@ static bool IsHexFloatString(Iterator start,
}
if (!saw_digit) return false;
if (*current != 'p' && *current != 'P') return false;
if (Advance(&current, separator, 16, end)) return false;
// The separator is only allowed between significand digits, not in the
// exponent, so advance through the exponent with no separator.
const uc16 kNoSeparator = StringToDoubleConverter::kNoSeparator;
if (Advance(&current, kNoSeparator, 16, end)) return false;
if (*current == '+' || *current == '-') {
if (Advance(&current, separator, 16, end)) return false;
if (Advance(&current, kNoSeparator, 16, end)) return false;
}
if (!isDigit(*current, 10)) return false;
if (Advance(&current, separator, 16, end)) return true;
if (Advance(&current, kNoSeparator, 16, end)) return true;
while (isDigit(*current, 10)) {
if (Advance(&current, separator, 16, end)) return true;
if (Advance(&current, kNoSeparator, 16, end)) return true;
}
return allow_trailing_junk || !AdvanceToNonspace(&current, end);
}
Expand Down Expand Up @@ -400,15 +403,19 @@ static double RadixStringToIeee(Iterator* current,

if (parse_as_hex_float) {
DOUBLE_CONVERSION_ASSERT(**current == 'p' || **current == 'P');
Advance(current, separator, radix, end);
// The separator is only allowed between significand digits, not in the
// exponent, so advance through the exponent with no separator. This must
// match IsHexFloatString, which validated the string the same way.
const uc16 kNoSeparator = StringToDoubleConverter::kNoSeparator;
Advance(current, kNoSeparator, radix, end);
DOUBLE_CONVERSION_ASSERT(*current != end);
bool is_negative = false;
if (**current == '+') {
Advance(current, separator, radix, end);
Advance(current, kNoSeparator, radix, end);
DOUBLE_CONVERSION_ASSERT(*current != end);
} else if (**current == '-') {
is_negative = true;
Advance(current, separator, radix, end);
Advance(current, kNoSeparator, radix, end);
DOUBLE_CONVERSION_ASSERT(*current != end);
}
int written_exponent = 0;
Expand All @@ -418,7 +425,7 @@ static double RadixStringToIeee(Iterator* current,
if (abs(written_exponent) <= 100 * Double::kMaxExponent) {
written_exponent = 10 * written_exponent + **current - '0';
}
if (Advance(current, separator, radix, end)) break;
if (Advance(current, kNoSeparator, radix, end)) break;
}
if (is_negative) written_exponent = -written_exponent;
exponent += written_exponent;
Expand Down
31 changes: 31 additions & 0 deletions test/cctest/test-conversions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4091,6 +4091,37 @@ TEST(StringToDoubleSeparator) {
StrToD16("0x0@3.p0", flags, 0.0, &processed, &all_used,
char_separator, separator));
CHECK(all_used);

// The separator is only allowed between significand digits, not in the
// exponent. The decimal exponent already rejects it; the hex-float exponent
// must reject it too.
separator = '_';
flags = StringToDoubleConverter::ALLOW_HEX |
StringToDoubleConverter::ALLOW_HEX_FLOATS;

CHECK_EQ(144.0, // 0x12p3, separator between significand digits.
StrToD("0x1_2p3", flags, 0.0, &processed, &all_used, separator));
CHECK(all_used);

CHECK_EQ(1024.0, // 0x1p10, no separator in the exponent.
StrToD("0x1p10", flags, 0.0, &processed, &all_used, separator));
CHECK(all_used);

CHECK_EQ(Double::NaN(),
StrToD("0x1p1_0", flags, 0.0, &processed, &all_used, separator));
CHECK_EQ(0, processed);

CHECK_EQ(Double::NaN(),
StrToD("0x1.8p1_0", flags, 0.0, &processed, &all_used, separator));
CHECK_EQ(0, processed);

CHECK_EQ(Double::NaN(),
StrToD("0x1p_10", flags, 0.0, &processed, &all_used, separator));
CHECK_EQ(0, processed);

CHECK_EQ(Double::NaN(),
StrToD("0x1p10_", flags, 0.0, &processed, &all_used, separator));
CHECK_EQ(0, processed);
}

TEST(StringToDoubleSpecialValues) {
Expand Down
Loading