[skjson] NaN while parsing long decimals
When parsing numbers with long decimals, the fast-path decimal factor may collapse to zero. Catch this condition (and defer to the slow parse path). Bug: skia:8499 Change-Id: I4e364402aecdcca9558d027a55ff297170e2a195 Reviewed-on: https://skia-review.googlesource.com/c/181179 Reviewed-by: Kevin Lubick <kjlubick@google.com> Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
parent
275eaff3be
commit
5809a4e2c3
@ -740,13 +740,14 @@ private:
|
||||
f = f * 10.f + (*p++ - '0'); --exp;
|
||||
}
|
||||
|
||||
if (is_numeric(*p)) {
|
||||
SkASSERT(*p == '.' || *p == 'e' || *p == 'E');
|
||||
// We either have malformed input, or an (unsupported) exponent.
|
||||
const auto decimal_scale = pow10(exp);
|
||||
if (is_numeric(*p) || !decimal_scale) {
|
||||
SkASSERT((*p == '.' || *p == 'e' || *p == 'E') || !decimal_scale);
|
||||
// Malformed input, or an (unsupported) exponent, or a collapsed decimal factor.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
this->pushFloat(sign * f * pow10(exp));
|
||||
this->pushFloat(sign * f * decimal_scale);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
@ -414,3 +414,43 @@ DEF_TEST(JSON_DOM_build, reporter) {
|
||||
"]"
|
||||
"}");
|
||||
}
|
||||
|
||||
DEF_TEST(JSON_ParseNumber, reporter) {
|
||||
static constexpr struct {
|
||||
const char* string;
|
||||
SkScalar value,
|
||||
tolerance;
|
||||
} gTests[] = {
|
||||
{ "0", 0, 0 },
|
||||
{ "1", 1, 0 },
|
||||
|
||||
{ "00000000", 0, 0 },
|
||||
{ "00000001", 1, 0 },
|
||||
|
||||
{ "0.001", 0.001f, 0 },
|
||||
{ "1.001", 1.001f, 0 },
|
||||
|
||||
{ "0.000001" , 0.000001f, 0 },
|
||||
{ "1.000001" , 1.000001f, 0 },
|
||||
{ "1000.000001", 1000.000001f, 0 },
|
||||
|
||||
{ "0.0000000001" , 0.0000000001f, 0 },
|
||||
{ "1.0000000001" , 1.0000000001f, 0 },
|
||||
{ "1000.0000000001", 1000.0000000001f, 0 },
|
||||
|
||||
{ "20.001111814444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444473",
|
||||
20.001f, 0.001f },
|
||||
};
|
||||
|
||||
for (const auto& test : gTests) {
|
||||
const auto json = SkStringPrintf("{ \"key\": %s }", test.string);
|
||||
const DOM dom(json.c_str(), json.size());
|
||||
const ObjectValue* jroot = dom.root();
|
||||
|
||||
REPORTER_ASSERT(reporter, jroot);
|
||||
|
||||
const NumberValue* jnumber = (*jroot)["key"];
|
||||
REPORTER_ASSERT(reporter, jnumber);
|
||||
REPORTER_ASSERT(reporter, SkScalarNearlyEqual(**jnumber, test.value, test.tolerance));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user