diff options
author | Vladimir Glavnyy <31897320+vglavnyy@users.noreply.github.com> | 2020-12-08 02:12:58 +0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-07 11:12:58 -0800 |
commit | 8d9eae9ac95c06ca1ae0139a8d80522163a17ae5 (patch) | |
tree | 850b481c2e7a48b44f6e13b125a3e7f8f7d383ed | |
parent | 2046bffa40400904c926c2a5bedab67a8d6b7e08 (diff) | |
download | flatbuffers-8d9eae9ac95c06ca1ae0139a8d80522163a17ae5.tar.gz flatbuffers-8d9eae9ac95c06ca1ae0139a8d80522163a17ae5.tar.bz2 flatbuffers-8d9eae9ac95c06ca1ae0139a8d80522163a17ae5.zip |
[idl_parser] Unify parsing of NaN values read from .fbs and .json files (#6296)
This commit unifies parsing of NaN values read
from .fbs and .json files by converting them to unsigned NaN.
-rw-r--r-- | include/flatbuffers/base.h | 7 | ||||
-rw-r--r-- | include/flatbuffers/stl_emulation.h | 6 | ||||
-rw-r--r-- | src/idl_parser.cpp | 18 | ||||
-rw-r--r-- | tests/fuzzer/CMakeLists.txt | 22 | ||||
-rw-r--r-- | tests/fuzzer/flatbuffers_scalar_fuzzer.cc | 4 | ||||
-rw-r--r-- | tests/fuzzer/scalar_debug.cpp | 2 | ||||
-rw-r--r-- | tests/fuzzer/scalar_json.dict | 4 |
7 files changed, 55 insertions, 8 deletions
diff --git a/include/flatbuffers/base.h b/include/flatbuffers/base.h index 95b788e0..92db55b7 100644 --- a/include/flatbuffers/base.h +++ b/include/flatbuffers/base.h @@ -197,12 +197,17 @@ namespace flatbuffers { #if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \ (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) || \ defined(__clang__) - #define FLATBUFFERS_DEFAULT_DECLARATION #define FLATBUFFERS_DELETE_FUNC(func) func = delete; #else #define FLATBUFFERS_DELETE_FUNC(func) private: func; #endif +#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \ + (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \ + defined(__clang__) + #define FLATBUFFERS_DEFAULT_DECLARATION +#endif + // Check if we can use template aliases // Not possible if Microsoft Compiler before 2012 // Possible is the language feature __cpp_alias_templates is defined well diff --git a/include/flatbuffers/stl_emulation.h b/include/flatbuffers/stl_emulation.h index 66bd620d..70e5dc94 100644 --- a/include/flatbuffers/stl_emulation.h +++ b/include/flatbuffers/stl_emulation.h @@ -164,6 +164,8 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) { using conditional = std::conditional<B, T, F>; template<class T, T v> using integral_constant = std::integral_constant<T, v>; + template <bool B> + using bool_constant = integral_constant<bool, B>; #else // Map C++ TR1 templates defined by stlport. template <typename T> using is_scalar = std::tr1::is_scalar<T>; @@ -187,6 +189,8 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) { using conditional = std::tr1::conditional<B, T, F>; template<class T, T v> using integral_constant = std::tr1::integral_constant<T, v>; + template <bool B> + using bool_constant = integral_constant<bool, B>; #endif // !FLATBUFFERS_CPP98_STL #else // MSVC 2010 doesn't support C++11 aliases. @@ -201,6 +205,8 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) { struct conditional : public std::conditional<B, T, F> {}; template<class T, T v> struct integral_constant : public std::integral_constant<T, v> {}; + template <bool B> + struct bool_constant : public integral_constant<bool, B> {}; #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) #ifndef FLATBUFFERS_CPP98_STL diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index 6d916e5d..bb23dc11 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -172,8 +172,21 @@ template<typename T> std::string TypeToIntervalString() { // atot: template version of atoi/atof: convert a string to an instance of T. template<typename T> -inline CheckedError atot(const char *s, Parser &parser, T *val) { - auto done = StringToNumber(s, val); +bool atot_scalar(const char *s, T *val, bool_constant<false>) { + return StringToNumber(s, val); +} + +template<typename T> +bool atot_scalar(const char *s, T *val, bool_constant<true>) { + // Normalize NaN parsed from fbs or json to unsigned NaN. + if (false == StringToNumber(s, val)) return false; + *val = (*val != *val) ? std::fabs(*val) : *val; + return true; +} + +template<typename T> +CheckedError atot(const char *s, Parser &parser, T *val) { + auto done = atot_scalar(s, val, bool_constant<is_floating_point<T>::value>()); if (done) return NoError(); if (0 == *val) return parser.Error("invalid number: \"" + std::string(s) + "\""); @@ -1806,7 +1819,6 @@ CheckedError Parser::ParseSingleValue(const std::string *name, Value &e, match = true; } // Parse a float/integer number from the string. - if (!match) check_now = true; // Re-pack if parsed from string literal. // A "scalar-in-string" value needs extra checks. if (!match && is_tok_string && IsScalar(in_type)) { // Strip trailing whitespaces from attribute_. diff --git a/tests/fuzzer/CMakeLists.txt b/tests/fuzzer/CMakeLists.txt index 5deba0fd..717bc943 100644 --- a/tests/fuzzer/CMakeLists.txt +++ b/tests/fuzzer/CMakeLists.txt @@ -139,6 +139,23 @@ target_link_libraries(monster_fuzzer PRIVATE flatbuffers_fuzzed) # Build debugger for weird cases found with fuzzer. if(BUILD_DEBUGGER) add_library(flatbuffers_nonfuzz STATIC ${FlatBuffers_Library_SRCS}) + target_compile_options( + flatbuffers_nonfuzz + PUBLIC + $<$<BOOL:${USE_ASAN}>: + -fsanitize=undefined,address + > + -fno-limit-debug-info + ) + + target_link_libraries( + flatbuffers_nonfuzz + PUBLIC + $<$<BOOL:${USE_ASAN}>: + -fsanitize=undefined,address + > + ) + target_compile_definitions( flatbuffers_nonfuzz PUBLIC @@ -147,6 +164,9 @@ if(BUILD_DEBUGGER) PRIVATE FLATBUFFERS_MAX_PARSING_DEPTH=${FLATBUFFERS_MAX_PARSING_DEPTH} ) - add_executable(scalar_debug flatbuffers_scalar_fuzzer.cc scalar_debug.cpp) + add_executable(scalar_debug + flatbuffers_scalar_fuzzer.cc + scalar_debug.cpp + ) target_link_libraries(scalar_debug PRIVATE flatbuffers_nonfuzz) endif(BUILD_DEBUGGER) diff --git a/tests/fuzzer/flatbuffers_scalar_fuzzer.cc b/tests/fuzzer/flatbuffers_scalar_fuzzer.cc index 3c711fcb..16728d29 100644 --- a/tests/fuzzer/flatbuffers_scalar_fuzzer.cc +++ b/tests/fuzzer/flatbuffers_scalar_fuzzer.cc @@ -288,7 +288,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { } // Parse original input as-is. - auto orig_scalar = "{ \"Y\" : " + input + " }"; + auto orig_scalar = "{\"Y\" : " + input + "}"; std::string orig_back; auto orig_done = Parse(parser, orig_scalar, &orig_back); @@ -326,7 +326,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { // Test quoted version of the string if (!qouted_input.empty()) { - auto fix_scalar = "{ \"Y\" : " + qouted_input + " }"; + auto fix_scalar = "{\"Y\" : " + qouted_input + "}"; std::string fix_back; auto fix_done = Parse(parser, fix_scalar, &fix_back); diff --git a/tests/fuzzer/scalar_debug.cpp b/tests/fuzzer/scalar_debug.cpp index 9ce9e5e1..d0c9b407 100644 --- a/tests/fuzzer/scalar_debug.cpp +++ b/tests/fuzzer/scalar_debug.cpp @@ -23,6 +23,6 @@ int main(int argc, char *argv[]) { auto rc = LLVMFuzzerTestOneInput( reinterpret_cast<const uint8_t *>(crash_file_data.data()), crash_file_data.size()); - std::cout << "LLVMFuzzerTestOneInput finished with code " << rc; + std::cout << "LLVMFuzzerTestOneInput finished with code " << rc << "\n\n"; return rc; } diff --git a/tests/fuzzer/scalar_json.dict b/tests/fuzzer/scalar_json.dict index 60689ddf..7558dc3e 100644 --- a/tests/fuzzer/scalar_json.dict +++ b/tests/fuzzer/scalar_json.dict @@ -17,7 +17,11 @@ "e" "f" "nan" +"-nan" +"+nan" "inf" +"+inf" "-inf" "infinity" +"+infinity" "-infinity" |