mirror of
https://github.com/google/flatbuffers.git
synced 2026-07-02 13:08:17 +00:00
[flexbuffers, json] Parse nan and inf (#6512)
This commit is contained in:
@@ -956,6 +956,8 @@ class Parser : public ParserState {
|
|||||||
FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent();
|
FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type *type);
|
FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type *type);
|
||||||
FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue();
|
FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue();
|
||||||
|
FLATBUFFERS_CHECKED_ERROR ParseFlexBufferNumericConstant(
|
||||||
|
flexbuffers::Builder *builder);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder);
|
FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder);
|
||||||
FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
|
FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
|
||||||
const char *source_filename);
|
const char *source_filename);
|
||||||
|
|||||||
@@ -3009,6 +3009,15 @@ CheckedError Parser::SkipAnyJsonValue() {
|
|||||||
return NoError();
|
return NoError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckedError Parser::ParseFlexBufferNumericConstant(
|
||||||
|
flexbuffers::Builder *builder) {
|
||||||
|
double d;
|
||||||
|
if (!StringToNumber(attribute_.c_str(), &d))
|
||||||
|
return Error("unexpected floating-point constant: " + attribute_);
|
||||||
|
builder->Double(d);
|
||||||
|
return NoError();
|
||||||
|
}
|
||||||
|
|
||||||
CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) {
|
CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) {
|
||||||
ParseDepthGuard depth_guard(this);
|
ParseDepthGuard depth_guard(this);
|
||||||
ECHECK(depth_guard.Check());
|
ECHECK(depth_guard.Check());
|
||||||
@@ -3056,6 +3065,18 @@ CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) {
|
|||||||
EXPECT(kTokenFloatConstant);
|
EXPECT(kTokenFloatConstant);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case '-':
|
||||||
|
case '+': {
|
||||||
|
// `[-+]?(nan|inf|infinity)`, see ParseSingleValue().
|
||||||
|
const auto sign = static_cast<char>(token_);
|
||||||
|
NEXT();
|
||||||
|
if (token_ != kTokenIdentifier)
|
||||||
|
return Error("floating-point constant expected");
|
||||||
|
attribute_.insert(0, 1, sign);
|
||||||
|
ECHECK(ParseFlexBufferNumericConstant(builder));
|
||||||
|
NEXT();
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
if (IsIdent("true")) {
|
if (IsIdent("true")) {
|
||||||
builder->Bool(true);
|
builder->Bool(true);
|
||||||
@@ -3066,6 +3087,9 @@ CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) {
|
|||||||
} else if (IsIdent("null")) {
|
} else if (IsIdent("null")) {
|
||||||
builder->Null();
|
builder->Null();
|
||||||
NEXT();
|
NEXT();
|
||||||
|
} else if (IsIdent("inf") || IsIdent("infinity") || IsIdent("nan")) {
|
||||||
|
ECHECK(ParseFlexBufferNumericConstant(builder));
|
||||||
|
NEXT();
|
||||||
} else
|
} else
|
||||||
return TokenError();
|
return TokenError();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3020,6 +3020,31 @@ void FlexBuffersTest() {
|
|||||||
TEST_EQ(slb.GetSize(), 664);
|
TEST_EQ(slb.GetSize(), 664);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FlexBuffersFloatingPointTest() {
|
||||||
|
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
|
||||||
|
flexbuffers::Builder slb(512,
|
||||||
|
flexbuffers::BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
|
||||||
|
// Parse floating-point values from JSON:
|
||||||
|
flatbuffers::Parser parser;
|
||||||
|
slb.Clear();
|
||||||
|
auto jsontest =
|
||||||
|
"{ a: [1.0, nan, inf, infinity, -inf, +inf, -infinity, 8.0] }";
|
||||||
|
TEST_EQ(parser.ParseFlexBuffer(jsontest, nullptr, &slb), true);
|
||||||
|
auto jroot = flexbuffers::GetRoot(slb.GetBuffer());
|
||||||
|
auto jmap = jroot.AsMap();
|
||||||
|
auto jvec = jmap["a"].AsVector();
|
||||||
|
TEST_EQ(8, jvec.size());
|
||||||
|
TEST_EQ(1.0, jvec[0].AsDouble());
|
||||||
|
TEST_ASSERT(is_quiet_nan(jvec[1].AsDouble()));
|
||||||
|
TEST_EQ(infinity_d, jvec[2].AsDouble());
|
||||||
|
TEST_EQ(infinity_d, jvec[3].AsDouble());
|
||||||
|
TEST_EQ(-infinity_d, jvec[4].AsDouble());
|
||||||
|
TEST_EQ(+infinity_d, jvec[5].AsDouble());
|
||||||
|
TEST_EQ(-infinity_d, jvec[6].AsDouble());
|
||||||
|
TEST_EQ(8.0, jvec[7].AsDouble());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void FlexBuffersDeprecatedTest() {
|
void FlexBuffersDeprecatedTest() {
|
||||||
// FlexBuffers as originally designed had a flaw involving the
|
// FlexBuffers as originally designed had a flaw involving the
|
||||||
// FBT_VECTOR_STRING datatype, and this test documents/tests the fix for it.
|
// FBT_VECTOR_STRING datatype, and this test documents/tests the fix for it.
|
||||||
@@ -3909,6 +3934,7 @@ int FlatBufferTests() {
|
|||||||
FieldIdentifierTest();
|
FieldIdentifierTest();
|
||||||
StringVectorDefaultsTest();
|
StringVectorDefaultsTest();
|
||||||
ParseIncorrectMonsterJsonTest();
|
ParseIncorrectMonsterJsonTest();
|
||||||
|
FlexBuffersFloatingPointTest();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user