[idl_parser] Add kTokenNumericConstant token (#6432)

* [idl_parser] Add kTokenNumericConstant token

This commit adds the new token for correct parsing of signed numeric constants.
Before this expressions `-nan` or `-inf` were treated as kTokenStringConstant.
This was ambiguous if a real string field parsed.
For example, `{ "text_field" : -name }` was accepted by the parser as valid JSON object.

Related oss-fuzz issue: 6200301176619008

* Add additional positive tests fo 'inf' and 'nan' as identifiers

* Rebase to HEAD

* Move processing of signed constants to ParseSingleValue method.

* Add missed `--cpp-static-reflection` (#6324) to pass CI

* Remove `flatbuffers.pc` from repository to unblock CI (#6455).

Probably the generated flatbuffers.pc should not be a part of repo.

* Fix FieldIdentifierTest()
This commit is contained in:
Vladimir Glavnyy
2021-03-12 02:12:06 +07:00
committed by GitHub
parent e9b4ae69dc
commit 0e453ac352
2 changed files with 83 additions and 38 deletions

View File

@@ -1694,6 +1694,9 @@ void ErrorTest() {
TestError("table X { y: [int] = [1]; }", "Expected `]`");
TestError("table X { y: [int] = [; }", "Expected `]`");
TestError("table X { y: [int] = \"\"; }", "type mismatch");
// An identifier can't start from sign (+|-)
TestError("table X { -Y: int; } root_type Y: {Y:1.0}", "identifier");
TestError("table X { +Y: int; } root_type Y: {Y:1.0}", "identifier");
}
template<typename T>
@@ -2028,6 +2031,8 @@ void ValidFloatTest() {
TEST_EQ(std::isnan(TestValue<double>("{ y:nan }", "double")), true);
TEST_EQ(std::isnan(TestValue<float>("{ y:nan }", "float")), true);
TEST_EQ(std::isnan(TestValue<float>("{ y:\"nan\" }", "float")), true);
TEST_EQ(std::isnan(TestValue<float>("{ y:\"+nan\" }", "float")), true);
TEST_EQ(std::isnan(TestValue<float>("{ y:\"-nan\" }", "float")), true);
TEST_EQ(std::isnan(TestValue<float>("{ y:+nan }", "float")), true);
TEST_EQ(std::isnan(TestValue<float>("{ y:-nan }", "float")), true);
TEST_EQ(std::isnan(TestValue<float>(nullptr, "float=nan")), true);
@@ -2035,6 +2040,8 @@ void ValidFloatTest() {
// check inf
TEST_EQ(TestValue<float>("{ y:inf }", "float"), infinity_f);
TEST_EQ(TestValue<float>("{ y:\"inf\" }", "float"), infinity_f);
TEST_EQ(TestValue<float>("{ y:\"-inf\" }", "float"), -infinity_f);
TEST_EQ(TestValue<float>("{ y:\"+inf\" }", "float"), infinity_f);
TEST_EQ(TestValue<float>("{ y:+inf }", "float"), infinity_f);
TEST_EQ(TestValue<float>("{ y:-inf }", "float"), -infinity_f);
TEST_EQ(TestValue<float>(nullptr, "float=inf"), infinity_f);
@@ -3777,6 +3784,34 @@ void FieldIdentifierTest() {
// Positive tests for unions
TEST_EQ(true, Parser().Parse("union X{} table T{ u: X (id:1); }"));
TEST_EQ(true, Parser().Parse("union X{} table T{ u: X; }"));
// Test using 'inf' and 'nan' words both as identifiers and as default values.
TEST_EQ(true, Parser().Parse("table T{ nan: string; }"));
TEST_EQ(true, Parser().Parse("table T{ inf: string; }"));
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
TEST_EQ(true, Parser().Parse("table T{ inf: float = inf; }"));
TEST_EQ(true, Parser().Parse("table T{ nan: float = inf; }"));
#endif
}
void ParseIncorrectMonsterJsonTest() {
std::string schemafile;
TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.bfbs").c_str(),
true, &schemafile),
true);
flatbuffers::Parser parser;
flatbuffers::Verifier verifier(
reinterpret_cast<const uint8_t *>(schemafile.c_str()), schemafile.size());
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
TEST_EQ(parser.Deserialize((const uint8_t *)schemafile.c_str(),
schemafile.size()),
true);
TEST_EQ(parser.ParseJson("{name:\"monster\"}"), true);
TEST_EQ(parser.ParseJson(""), false);
TEST_EQ(parser.ParseJson("{name: 1}"), false);
TEST_EQ(parser.ParseJson("{name:+1}"), false);
TEST_EQ(parser.ParseJson("{name:-1}"), false);
TEST_EQ(parser.ParseJson("{name:-f}"), false);
TEST_EQ(parser.ParseJson("{name:+f}"), false);
}
int FlatBufferTests() {
@@ -3873,6 +3908,7 @@ int FlatBufferTests() {
FixedLengthArrayConstructorTest();
FieldIdentifierTest();
StringVectorDefaultsTest();
ParseIncorrectMonsterJsonTest();
return 0;
}