From b8aaccee8248059b2af032cca0eb1d2ddbdb6cdc Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Wed, 15 Dec 2021 10:41:29 -0800 Subject: [PATCH] Disable parsing of nested_flatbuffers as bytes by default Parsing as bytes produces buffers that are unsafe to access unless passed thru a verifier, whereas users could reasonably assume that any JSON parsed without errors is safe to access. Users that still have legacy JSON files with such bytes in it will get a helpful error point them to the option to turn on to have it work again. --- docs/source/Compiler.md | 4 ++++ include/flatbuffers/idl.h | 2 ++ src/flatc.cpp | 5 +++++ src/idl_parser.cpp | 7 ++++++- 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/source/Compiler.md b/docs/source/Compiler.md index 386ee07ee..242506a5b 100644 --- a/docs/source/Compiler.md +++ b/docs/source/Compiler.md @@ -220,5 +220,9 @@ Additional options: - `--cs-global-alias` : Prepend `global::` to all user generated csharp classes and structs. +- `--json-nested-bytes` : Allow a nested_flatbuffer field to be parsed as a + vector of bytes in JSON, which is unsafe unless checked by a verifier + afterwards. + NOTE: short-form options for generators are deprecated, use the long form whenever possible. diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 208ac52c9..a67d713f8 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -595,6 +595,7 @@ struct IDLOptions { bool cs_global_alias; bool json_nested_flatbuffers; bool json_nested_flexbuffers; + bool json_nested_legacy_flatbuffers; // Possible options for the more general generator below. enum Language { @@ -684,6 +685,7 @@ struct IDLOptions { cs_global_alias(false), json_nested_flatbuffers(true), json_nested_flexbuffers(true), + json_nested_legacy_flatbuffers(false), mini_reflect(IDLOptions::kNone), require_explicit_ids(false), lang_to_generate(0), diff --git a/src/flatc.cpp b/src/flatc.cpp index 2398b3876..cee5f144f 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -205,6 +205,9 @@ const static FlatCOption options[] = { { "", "cs-gen-json-serializer", "", "Allows (de)serialization of JSON text in the Object API. (requires " "--gen-object-api)." }, + { "", "json-nested-bytes", "", + "Allow a nested_flatbuffer field to be parsed as a vector of bytes" + "in JSON, which is unsafe unless checked by a verifier afterwards." }, }; static void AppendTextWrappedString(std::stringstream &ss, std::string &text, @@ -503,6 +506,8 @@ int FlatCompiler::Compile(int argc, const char **argv) { opts.cpp_static_reflection = true; } else if (arg == "--cs-global-alias") { opts.cs_global_alias = true; + } else if (arg == "--json-nested-bytes") { + opts.json_nested_legacy_flatbuffers = true; } else { for (size_t i = 0; i < params_.num_generators; ++i) { if (arg == "--" + params_.generators[i].option.long_opt || diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index 9684fbfde..a4a40fd60 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -1671,7 +1671,12 @@ CheckedError Parser::ParseNestedFlatbuffer(Value &val, FieldDef *field, size_t fieldn, const StructDef *parent_struct_def) { if (token_ == '[') { // backwards compat for 'legacy' ubyte buffers - ECHECK(ParseAnyValue(val, field, fieldn, parent_struct_def, 0)); + if (opts.json_nested_legacy_flatbuffers) { + ECHECK(ParseAnyValue(val, field, fieldn, parent_struct_def, 0)); + } else { + return Error("cannot parse nested_flatbuffer as bytes unless" + " --json-nested-bytes is set"); + } } else { auto cursor_at_value_begin = cursor_; ECHECK(SkipAnyJsonValue());