Kaynağa Gözat

Fixed reading "true" as a float (issue #516)

Benoit Blanchon 8 yıl önce
ebeveyn
işleme
bff77abe6a

+ 1 - 0
CHANGELOG.md

@@ -6,6 +6,7 @@ HEAD
 
 * Fixed IntelliSense errors in Visual Micro (issue #483)
 * Fixed compilation in IAR Embedded Workbench (issue #515)
+* Fixed reading "true" as a float (issue #516)
 * Added `ARDUINOJSON_DOUBLE_IS_64BITS`
 * Added `ARDUINOJSON_EMBEDDED_MODE`
 

+ 0 - 2
src/ArduinoJson/JsonVariantImpl.hpp

@@ -61,8 +61,6 @@ inline T JsonVariant::variantAsInteger() const {
       return T(~_content.asInteger + 1);
     case JSON_STRING:
     case JSON_UNPARSED:
-      if (!_content.asString) return 0;
-      if (!strcmp("true", _content.asString)) return 1;
       return Polyfills::parseInteger<T>(_content.asString);
     default:
       return T(_content.asFloat);

+ 2 - 1
src/ArduinoJson/Polyfills/parseFloat.hpp

@@ -20,7 +20,7 @@ inline T parseFloat(const char* s) {
   typedef typename traits::mantissa_type mantissa_t;
   typedef typename traits::exponent_type exponent_t;
 
-  if (!s) return 0;
+  if (!s) return 0;  // NULL
 
   bool negative_result = false;
   switch (*s) {
@@ -30,6 +30,7 @@ inline T parseFloat(const char* s) {
       s++;
   }
 
+  if (*s == 't') return 1;  // true
   if (*s == 'n' || *s == 'N') return traits::nan();
   if (*s == 'i' || *s == 'I')
     return negative_result ? -traits::inf() : traits::inf();

+ 3 - 1
src/ArduinoJson/Polyfills/parseInteger.hpp

@@ -16,7 +16,9 @@ namespace ArduinoJson {
 namespace Polyfills {
 template <typename T>
 T parseInteger(const char *s) {
-  if (!s) return 0;
+  if (!s) return 0;  // NULL
+
+  if (*s == 't') return 1;  // "true"
 
   T result = 0;
   bool negative_result = false;

+ 10 - 0
test/Polyfills/parseFloat.cpp

@@ -101,6 +101,11 @@ TEST_CASE("parseFloat<float>()") {
     checkInf<float>("+inf", false);
     checkInf<float>("-inf", true);
   }
+
+  SECTION("Boolean") {
+    check<float>("false", 0.0f);
+    check<float>("true", 1.0f);
+  }
 }
 
 TEST_CASE("parseFloat<double>()") {
@@ -167,4 +172,9 @@ TEST_CASE("parseFloat<double>()") {
     checkNaN<double>("NaN");
     checkNaN<double>("nan");
   }
+
+  SECTION("Boolean") {
+    check<double>("false", 0.0);
+    check<double>("true", 1.0);
+  }
 }

+ 10 - 4
test/Polyfills/parseInteger.cpp

@@ -23,11 +23,12 @@ TEST_CASE("parseInteger<int8_t>()") {
   check<int8_t>("127", 127);
   check<int8_t>("+127", 127);
   check<int8_t>("3.14", 3);
-  // check<int8_t>(" 42", 0);
   check<int8_t>("x42", 0);
   check<int8_t>("128", -128);
   check<int8_t>("-129", 127);
   check<int8_t>(NULL, 0);
+  check<int8_t>("true", 1);
+  check<int8_t>("false", 0);
 }
 
 TEST_CASE("parseInteger<int16_t>()") {
@@ -35,11 +36,12 @@ TEST_CASE("parseInteger<int16_t>()") {
   check<int16_t>("32767", 32767);
   check<int16_t>("+32767", 32767);
   check<int16_t>("3.14", 3);
-  // check<int16_t>(" 42", 0);
   check<int16_t>("x42", 0);
   check<int16_t>("-32769", 32767);
   check<int16_t>("32768", -32768);
   check<int16_t>(NULL, 0);
+  check<int16_t>("true", 1);
+  check<int16_t>("false", 0);
 }
 
 TEST_CASE("parseInteger<int32_t>()") {
@@ -47,10 +49,11 @@ TEST_CASE("parseInteger<int32_t>()") {
   check<int32_t>("2147483647", 2147483647);
   check<int32_t>("+2147483647", 2147483647);
   check<int32_t>("3.14", 3);
-  // check<int32_t>(" 42", 0);
   check<int32_t>("x42", 0);
   check<int32_t>("-2147483649", 2147483647);
   check<int32_t>("2147483648", (-2147483647 - 1));
+  check<int32_t>("true", 1);
+  check<int32_t>("false", 0);
 }
 
 TEST_CASE("parseInteger<uint8_t>()") {
@@ -58,10 +61,11 @@ TEST_CASE("parseInteger<uint8_t>()") {
   check<uint8_t>("255", 255);
   check<uint8_t>("+255", 255);
   check<uint8_t>("3.14", 3);
-  // check<uint8_t>(" 42", 0);
   check<uint8_t>("x42", 0);
   check<uint8_t>("-1", 255);
   check<uint8_t>("256", 0);
+  check<uint8_t>("true", 1);
+  check<uint8_t>("false", 0);
 }
 
 TEST_CASE("parseInteger<uint16_t>()") {
@@ -73,4 +77,6 @@ TEST_CASE("parseInteger<uint16_t>()") {
   check<uint16_t>("x42", 0);
   check<uint16_t>("-1", 65535);
   check<uint16_t>("65536", 0);
+  check<uint16_t>("true", 1);
+  check<uint16_t>("false", 0);
 }