Squashed 'third_party/flatbuffers/' changes from d6a8dbd26..338393f85
338393f85 Documentation updates for Optional Scalars (#6014) (#6270)
c27bc2d76 [C++] Add ParseJson(), Parser(Parser&&), update fuzzers (#6284)
bc518a512 Fixed FlexBufferBuilder asserting on duplicate keys
100c59054 Added a few more paths for auto labeler (#6281)
e58c18244 Add --require-explicit-ids to require explicit ids (#6277)
69a8b2a57 idl_gen_json_schema.cpp: Changed generation of array element types (#6253)
25eba6f35 fix typo (#6280)
e1f0f75ba Updated Ms build Action to fix build issue (#6279)
faeb04fbe Add type annotation to unspecified array (#6264)
537212afe [Swift] Adds a format file and reformats the swift project (#6250)
6764f25d9 Adds a fix for enum generation (#6263)
Change-Id: I716bd4d2521fb0a673e50a699cef761e042052b2
git-subtree-dir: third_party/flatbuffers
git-subtree-split: 338393f854eb5ba24761a22cd9316ff5cee4eab0
diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp
index a87fbce..6d916e5 100644
--- a/src/idl_parser.cpp
+++ b/src/idl_parser.cpp
@@ -2379,11 +2379,18 @@
if ((*it)->attributes.Lookup("id")) num_id_fields++;
}
// If any fields have ids..
- if (num_id_fields) {
+ if (num_id_fields || opts.require_explicit_ids) {
// Then all fields must have them.
- if (num_id_fields != fields.size())
- return Error(
- "either all fields or no fields must have an 'id' attribute");
+ if (num_id_fields != fields.size()) {
+ if (opts.require_explicit_ids) {
+ return Error(
+ "all fields must have an 'id' attribute when "
+ "--require-explicit-ids is used");
+ } else {
+ return Error(
+ "either all fields or no fields must have an 'id' attribute");
+ }
+ }
// Simply sort by id, then the fields are the same as if no ids had
// been specified.
std::sort(fields.begin(), fields.end(), compareFieldDefs);
@@ -2850,6 +2857,8 @@
});
ECHECK(err);
builder->EndMap(start);
+ if (builder->HasDuplicateKeys())
+ return Error("FlexBuffers map has duplicate keys");
break;
}
case '[': {
@@ -2914,6 +2923,15 @@
return r;
}
+bool Parser::ParseJson(const char *json, const char *json_filename) {
+ FLATBUFFERS_ASSERT(0 == recurse_protection_counter);
+ builder_.Clear();
+ const auto done =
+ !StartParseFile(json, json_filename).Check() && !DoParseJson().Check();
+ FLATBUFFERS_ASSERT(0 == recurse_protection_counter);
+ return done;
+}
+
CheckedError Parser::StartParseFile(const char *source,
const char *source_filename) {
file_being_parsed_ = source_filename ? source_filename : "";
@@ -3094,25 +3112,7 @@
} else if (IsIdent("namespace")) {
ECHECK(ParseNamespace());
} else if (token_ == '{') {
- if (!root_struct_def_)
- return Error("no root type set to parse json with");
- if (builder_.GetSize()) {
- return Error("cannot have more than one json object in a file");
- }
- uoffset_t toff;
- ECHECK(ParseTable(*root_struct_def_, nullptr, &toff));
- if (opts.size_prefixed) {
- builder_.FinishSizePrefixed(
- Offset<Table>(toff),
- file_identifier_.length() ? file_identifier_.c_str() : nullptr);
- } else {
- builder_.Finish(Offset<Table>(toff), file_identifier_.length()
- ? file_identifier_.c_str()
- : nullptr);
- }
- // Check that JSON file doesn't contain more objects or IDL directives.
- // Comments after JSON are allowed.
- EXPECT(kTokenEof);
+ ECHECK(DoParseJson());
} else if (IsIdent("enum")) {
ECHECK(ParseEnum(false, nullptr));
} else if (IsIdent("union")) {
@@ -3163,6 +3163,34 @@
return NoError();
}
+CheckedError Parser::DoParseJson()
+{
+ if (token_ != '{') {
+ EXPECT('{');
+ } else {
+ if (!root_struct_def_)
+ return Error("no root type set to parse json with");
+ if (builder_.GetSize()) {
+ return Error("cannot have more than one json object in a file");
+ }
+ uoffset_t toff;
+ ECHECK(ParseTable(*root_struct_def_, nullptr, &toff));
+ if (opts.size_prefixed) {
+ builder_.FinishSizePrefixed(
+ Offset<Table>(toff),
+ file_identifier_.length() ? file_identifier_.c_str() : nullptr);
+ } else {
+ builder_.Finish(Offset<Table>(toff), file_identifier_.length()
+ ? file_identifier_.c_str()
+ : nullptr);
+ }
+ }
+ // Check that JSON file doesn't contain more objects or IDL directives.
+ // Comments after JSON are allowed.
+ EXPECT(kTokenEof);
+ return NoError();
+}
+
std::set<std::string> Parser::GetIncludedFilesRecursive(
const std::string &file_name) const {
std::set<std::string> included_files;