mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-01 19:58:15 +00:00
[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.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,11 @@
|
||||
"e"
|
||||
"f"
|
||||
"nan"
|
||||
"-nan"
|
||||
"+nan"
|
||||
"inf"
|
||||
"+inf"
|
||||
"-inf"
|
||||
"infinity"
|
||||
"+infinity"
|
||||
"-infinity"
|
||||
|
||||
Reference in New Issue
Block a user