mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-02 04:04:19 +00:00
Fix recursion counter check. Add control to override depth of nested … (#4953)
* Fix recursion counter check. Add control to override depth of nested objects. * Change if-condition to `>=`
This commit is contained in:
committed by
Wouter van Oortmerssen
parent
c0698cc33f
commit
925c1d77fc
@@ -23,6 +23,12 @@ if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
|
||||
set(FLATBUFFERS_BUILD_TESTS OFF)
|
||||
endif()
|
||||
|
||||
if(DEFINED FLATBUFFERS_MAX_PARSING_DEPTH)
|
||||
# Override the default recursion depth limit.
|
||||
add_definitions(-DFLATBUFFERS_MAX_PARSING_DEPTH=${FLATBUFFERS_MAX_PARSING_DEPTH})
|
||||
message(STATUS "FLATBUFFERS_MAX_PARSING_DEPTH: ${FLATBUFFERS_MAX_PARSING_DEPTH}")
|
||||
endif()
|
||||
|
||||
set(FlatBuffers_Library_SRCS
|
||||
include/flatbuffers/code_generators.h
|
||||
include/flatbuffers/base.h
|
||||
|
||||
@@ -80,6 +80,14 @@ target_link_libraries(own_project_target PRIVATE flatbuffers)
|
||||
When build your project the `flatbuffers` library will be compiled and linked
|
||||
to a target as part of your project.
|
||||
|
||||
#### Override default depth limit of nested objects
|
||||
To override [the depth limit of recursion](@ref flatbuffers_guide_use_cpp),
|
||||
add this directive:
|
||||
```cmake
|
||||
set(FLATBUFFERS_MAX_PARSING_DEPTH 16)
|
||||
```
|
||||
to `CMakeLists.txt` file before `add_subdirectory(${FLATBUFFERS_SRC_DIR})` line.
|
||||
|
||||
#### For Google Play apps
|
||||
|
||||
For applications on Google Play that integrate this library, usage is tracked.
|
||||
|
||||
@@ -495,4 +495,13 @@ needed to use unions.
|
||||
|
||||
To use scalars, simply wrap them in a struct.
|
||||
|
||||
## Depth limit of nested objects and stack-overflow control
|
||||
The parser of Flatbuffers schema or json-files is kind of recursive parser.
|
||||
To avoid stack-overflow problem the parser has a built-in limiter of recursion depth.
|
||||
Number of nested declarations in a schema or number of nested json-objects is limited.
|
||||
By default, this depth limit set to `64`.
|
||||
It is possible to override this limit with `FLATBUFFERS_MAX_PARSING_DEPTH` definition.
|
||||
This definition can be helpful for testing purposes or embedded applications.
|
||||
For details see [build](@ref flatbuffers_guide_building) of CMake-based projects.
|
||||
|
||||
<br>
|
||||
|
||||
@@ -34,6 +34,12 @@
|
||||
// This file defines the data types representing a parsed IDL (Interface
|
||||
// Definition Language) / schema file.
|
||||
|
||||
// Limits maximum depth of nested objects.
|
||||
// Prevents stack overflow while parse flatbuffers or json.
|
||||
#if !defined(FLATBUFFERS_MAX_PARSING_DEPTH)
|
||||
# define FLATBUFFERS_MAX_PARSING_DEPTH 64
|
||||
#endif
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
// The order of these matters for Is*() functions below.
|
||||
@@ -745,10 +751,11 @@ class Parser : public ParserState {
|
||||
bool SupportsVectorOfUnions() const;
|
||||
Namespace *UniqueNamespace(Namespace *ns);
|
||||
|
||||
enum { kMaxParsingDepth = 64 };
|
||||
FLATBUFFERS_CHECKED_ERROR RecurseError();
|
||||
template<typename F> CheckedError Recurse(F f) {
|
||||
if (++recurse_protection_counter >= kMaxParsingDepth) return RecurseError();
|
||||
if (recurse_protection_counter >= (FLATBUFFERS_MAX_PARSING_DEPTH))
|
||||
return RecurseError();
|
||||
recurse_protection_counter++;
|
||||
auto ce = f();
|
||||
recurse_protection_counter--;
|
||||
return ce;
|
||||
|
||||
@@ -115,8 +115,8 @@ CheckedError Parser::Error(const std::string &msg) {
|
||||
inline CheckedError NoError() { return CheckedError(false); }
|
||||
|
||||
CheckedError Parser::RecurseError() {
|
||||
return Error("maximum parsing recursion of " + NumToString(kMaxParsingDepth) +
|
||||
" reached");
|
||||
return Error("maximum parsing recursion of " +
|
||||
NumToString(FLATBUFFERS_MAX_PARSING_DEPTH) + " reached");
|
||||
}
|
||||
|
||||
inline std::string OutOfRangeErrorMsg(int64_t val, const std::string &op,
|
||||
@@ -2254,7 +2254,10 @@ bool Parser::ParseFlexBuffer(const char *source, const char *source_filename,
|
||||
|
||||
bool Parser::Parse(const char *source, const char **include_paths,
|
||||
const char *source_filename) {
|
||||
return !ParseRoot(source, include_paths, source_filename).Check();
|
||||
FLATBUFFERS_ASSERT(0 == recurse_protection_counter);
|
||||
auto r = !ParseRoot(source, include_paths, source_filename).Check();
|
||||
FLATBUFFERS_ASSERT(0 == recurse_protection_counter);
|
||||
return r;
|
||||
}
|
||||
|
||||
CheckedError Parser::StartParseFile(const char *source,
|
||||
|
||||
Reference in New Issue
Block a user