Commit 7bbda190 authored by Fredrik Söderquist's avatar Fredrik Söderquist Committed by Commit Bot

Change handling of negative exponents in GenericParseNumber

Rather than enforcing a limit on the smallest exponent, pass all
negative exponents straight to pow(...) and let it deal with it. Per
IEEE754 pow(10, -Inf) should yield 0, and the cast should round properly
for larger negative exponents (smaller than -37.)

Bug: 852785
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_slimming_paint_v2;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: Iccd80f7e80c8b87c49cd5eedf5e49ad1e9ccc8dc
Reviewed-on: https://chromium-review.googlesource.com/1102329
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567660}
parent 88d37d7e
......@@ -33,12 +33,6 @@ static inline bool IsValidRange(const FloatType x) {
return x >= -kMax && x <= kMax;
}
template <typename FloatType>
static inline bool IsValidExponent(const FloatType x) {
return x >= std::numeric_limits<FloatType>::min_exponent10 &&
x <= std::numeric_limits<FloatType>::max_exponent10;
}
// We use this generic parseNumber function to allow the Path parsing code to
// work at a higher precision internally, without any unnecessary runtime cost
// or code complexity.
......@@ -129,13 +123,19 @@ static bool GenericParseNumber(const CharType*& cursor,
exponent += *ptr - '0';
ptr++;
}
// TODO(fs): This is unnecessarily strict - the position of the decimal
// point is not taken into account when limiting |exponent|.
if (exponent_is_negative)
exponent = -exponent;
// Make sure exponent is valid.
if (!IsValidExponent(exponent))
// Fail if the exponent is greater than the largest positive power
// of ten (that would yield a representable float.)
if (exponent > std::numeric_limits<FloatType>::max_exponent10)
return false;
// If the exponent is smaller than smallest negative power of 10 (that
// would yield a representable float), then rely on the pow()+rounding to
// produce a reasonable result (likely zero.)
if (exponent)
number *= static_cast<FloatType>(pow(10.0, static_cast<int>(exponent)));
number *= static_cast<FloatType>(std::pow(10.0, exponent));
}
// Don't return Infinity() or NaN().
......
......@@ -138,6 +138,19 @@ TEST(SVGPathParserTest, Simple) {
MALFORMED("M1,1A2,3,4,0,0,5,6 7", "M 1 1 A 2 3 4 0 0 5 6");
VALID("M1,1A2,3,4,0,0,5,6 7,8,9,0,0,10,11",
"M 1 1 A 2 3 4 0 0 5 6 A 7 8 9 0 0 10 11");
// Scientific notation.
VALID("M1e2,10e1", "M 100 100");
VALID("M100e0,100", "M 100 100");
VALID("M1e+2,1000e-1", "M 100 100");
VALID("M1e2.5", "M 100 0.5");
VALID("M0.00000001e10 100", "M 100 100");
VALID("M1e-46,50 h1e38", "M 0 50 h 1.00000e+38");
VALID("M0,50 h1e-123456789123456789123", "M 0 50 h 0");
MALFORMED("M0,50 h1e39", "M 0 50");
MALFORMED("M0,50 h1e123456789123456789123", "M 0 50");
MALFORMED("M0,50 h1e-.5", "M 0 50");
MALFORMED("M0,50 h1e+.5", "M 0 50");
}
#undef MALFORMED
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment