From deb57b960be096100193377726f0de49917c8341 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Mon, 19 Sep 2016 10:08:14 +0200 Subject: [PATCH] Fixed parser that incorrectly rejected floats containing a `+` (issue #349) --- CHANGELOG.md | 1 + include/ArduinoJson/Internals/JsonParser.hpp | 2 +- include/ArduinoJson/JsonObject.ipp | 4 +- include/ArduinoJson/Print.hpp | 2 +- test/CMakeLists.txt | 8 +-- test/JsonParser_Variant_Tests.cpp | 57 +++++++++++--------- 6 files changed, 41 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c05e543..8ab7acd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ HEAD * Fixed `array[idx].as()` and `object[key].as()` * Fixed return value of `JsonObject::set()` (issue #350) * Fixed undefined behavior in `Prettyfier` and `Print` (issue #354) +* Fixed parser that incorrectly rejected floats containing a `+` (issue #349) v5.6.6 ------ diff --git a/include/ArduinoJson/Internals/JsonParser.hpp b/include/ArduinoJson/Internals/JsonParser.hpp index 88fe845e..bdbd12bd 100644 --- a/include/ArduinoJson/Internals/JsonParser.hpp +++ b/include/ArduinoJson/Internals/JsonParser.hpp @@ -50,7 +50,7 @@ class JsonParser { static inline bool isLetterOrNumber(char c) { return isInRange(c, '0', '9') || isInRange(c, 'a', 'z') || - isInRange(c, 'A', 'Z') || c == '-' || c == '.'; + isInRange(c, 'A', 'Z') || c == '+' || c == '-' || c == '.'; } static inline bool isQuote(char c) { diff --git a/include/ArduinoJson/JsonObject.ipp b/include/ArduinoJson/JsonObject.ipp index f04d53b5..4a86c061 100644 --- a/include/ArduinoJson/JsonObject.ipp +++ b/include/ArduinoJson/JsonObject.ipp @@ -17,14 +17,14 @@ template <> inline bool JsonObject::setNodeValue(node_type *node, String &value) { const char *dup = _buffer->strdup(value); node->content.value = dup; - return dup; + return dup != NULL; } template <> inline bool JsonObject::setNodeValue(node_type *node, const String &value) { const char *dup = _buffer->strdup(value); node->content.value = dup; - return dup; + return dup != NULL; } template <> diff --git a/include/ArduinoJson/Print.hpp b/include/ArduinoJson/Print.hpp index 367b3ae3..78243a5c 100644 --- a/include/ArduinoJson/Print.hpp +++ b/include/ArduinoJson/Print.hpp @@ -23,7 +23,7 @@ class Print { size_t print(const char* s) { size_t n = 0; while (*s) { - n += write(*s++); + n += write(static_cast(*s++)); } return n; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d64431d4..4af4f006 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -26,9 +26,6 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)") -Winit-self -Wmissing-include-dirs -Wparentheses - -Wno-sign-conversion - -Wno-unused - -Wno-variadic-macros -Wnon-virtual-dtor -Wold-style-cast -Woverloaded-virtual @@ -63,7 +60,10 @@ endif() if(MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) - add_compile_options(-W4) + add_compile_options( + /W4 # Set warning level + /WX # Treats all compiler warnings as errors. + ) endif() add_executable(ArduinoJsonTests ${TESTS_FILES}) diff --git a/test/JsonParser_Variant_Tests.cpp b/test/JsonParser_Variant_Tests.cpp index 567b4d94..382fc395 100644 --- a/test/JsonParser_Variant_Tests.cpp +++ b/test/JsonParser_Variant_Tests.cpp @@ -24,13 +24,29 @@ class JsonParser_Variant_Test : public testing::Test { EXPECT_STREQ(expected, _result.as()); } + void resultMustEqual(double expected) { + EXPECT_DOUBLE_EQ(expected, _result.as()); + } + template void resultTypeMustBe() { EXPECT_TRUE(_result.is()); } - void resultMustBeInvalid() { EXPECT_FALSE(_result.success()); } - void resultMustBeValid() { EXPECT_TRUE(_result.success()); } + void resultMustBeInvalid() { + EXPECT_FALSE(_result.success()); + } + void resultMustBeValid() { + EXPECT_TRUE(_result.success()); + } + + template + void verify(const char* input, T expected) { + whenInputIs(input); + resultMustBeValid(); + resultTypeMustBe(); + resultMustEqual(expected); + } private: DynamicJsonBuffer _jsonBuffer; @@ -51,38 +67,29 @@ TEST_F(JsonParser_Variant_Test, EmptyArray) { } TEST_F(JsonParser_Variant_Test, Integer) { - whenInputIs("42"); - resultMustBeValid(); - resultTypeMustBe(); - resultMustEqual(42); + verify("42", 42); + verify("-42", -42); } TEST_F(JsonParser_Variant_Test, Double) { - whenInputIs("3.14"); - resultMustBeValid(); - resultTypeMustBe(); - resultMustEqual(3.14); + verify("3.14", 3.14); + verify("3.14", 3.14); + verify("1E+10", 1E+10); + verify("-1E+10", -1E+10); + verify("1.234E+10", 1.234E+10); + verify("1.79769e+308", 1.79769e+308); + verify("-1.79769e+308", -1.79769e+308); + verify("1.7976931348623157e+308", 1.7976931348623157e+308); + verify("0.017976931348623157e+310", 0.017976931348623157e+310); } TEST_F(JsonParser_Variant_Test, String) { - whenInputIs("\"hello world\""); - resultMustBeValid(); - resultTypeMustBe(); - resultMustEqual("hello world"); + verify("\"hello world\"", "hello world"); } TEST_F(JsonParser_Variant_Test, True) { - whenInputIs("true"); - resultMustBeValid(); - resultTypeMustBe(); - resultMustEqual(true); -} - -TEST_F(JsonParser_Variant_Test, False) { - whenInputIs("false"); - resultMustBeValid(); - resultTypeMustBe(); - resultMustEqual(false); + verify("true", true); + verify("false", false); } TEST_F(JsonParser_Variant_Test, Invalid) {