mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Added DeserializationError::EmptyInput
This commit is contained in:
		| @@ -6,6 +6,7 @@ HEAD | |||||||
|  |  | ||||||
| * Added a build failure when nullptr is defined as a macro (issue #1355) | * Added a build failure when nullptr is defined as a macro (issue #1355) | ||||||
| * Added `JsonDocument::overflowed()` which tells if the memory pool was too small (issue #1358) | * Added `JsonDocument::overflowed()` which tells if the memory pool was too small (issue #1358) | ||||||
|  | * Added `DeserializationError::EmptyInput` which tells if the input was empty | ||||||
| * Fixed `JsonVariant::set((char*)0)` which returned false instead of true (issue #1368) | * Fixed `JsonVariant::set((char*)0)` which returned false instead of true (issue #1368) | ||||||
|  |  | ||||||
| v6.16.1 (2020-08-04) | v6.16.1 (2020-08-04) | ||||||
|   | |||||||
| @@ -30,20 +30,22 @@ void testBoolification(DeserializationError error, bool expected) { | |||||||
| TEST_CASE("DeserializationError") { | TEST_CASE("DeserializationError") { | ||||||
|   SECTION("c_str()") { |   SECTION("c_str()") { | ||||||
|     TEST_STRINGIFICATION(Ok); |     TEST_STRINGIFICATION(Ok); | ||||||
|     TEST_STRINGIFICATION(TooDeep); |     TEST_STRINGIFICATION(EmptyInput); | ||||||
|     TEST_STRINGIFICATION(NoMemory); |  | ||||||
|     TEST_STRINGIFICATION(InvalidInput); |  | ||||||
|     TEST_STRINGIFICATION(IncompleteInput); |     TEST_STRINGIFICATION(IncompleteInput); | ||||||
|  |     TEST_STRINGIFICATION(InvalidInput); | ||||||
|  |     TEST_STRINGIFICATION(NoMemory); | ||||||
|     TEST_STRINGIFICATION(NotSupported); |     TEST_STRINGIFICATION(NotSupported); | ||||||
|  |     TEST_STRINGIFICATION(TooDeep); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("as boolean") { |   SECTION("as boolean") { | ||||||
|     TEST_BOOLIFICATION(Ok, false); |     TEST_BOOLIFICATION(Ok, false); | ||||||
|     TEST_BOOLIFICATION(TooDeep, true); |     TEST_BOOLIFICATION(EmptyInput, true); | ||||||
|     TEST_BOOLIFICATION(NoMemory, true); |  | ||||||
|     TEST_BOOLIFICATION(InvalidInput, true); |  | ||||||
|     TEST_BOOLIFICATION(IncompleteInput, true); |     TEST_BOOLIFICATION(IncompleteInput, true); | ||||||
|  |     TEST_BOOLIFICATION(InvalidInput, true); | ||||||
|  |     TEST_BOOLIFICATION(NoMemory, true); | ||||||
|     TEST_BOOLIFICATION(NotSupported, true); |     TEST_BOOLIFICATION(NotSupported, true); | ||||||
|  |     TEST_BOOLIFICATION(TooDeep, true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("ostream DeserializationError") { |   SECTION("ostream DeserializationError") { | ||||||
| @@ -58,13 +60,6 @@ TEST_CASE("DeserializationError") { | |||||||
|     REQUIRE(s.str() == "InvalidInput"); |     REQUIRE(s.str() == "InvalidInput"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("out of range") { |  | ||||||
|     int code = 666; |  | ||||||
|     DeserializationError err( |  | ||||||
|         *reinterpret_cast<DeserializationError::Code*>(&code)); |  | ||||||
|     REQUIRE(err.c_str() == std::string("???")); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   SECTION("switch") { |   SECTION("switch") { | ||||||
|     DeserializationError err = DeserializationError::InvalidInput; |     DeserializationError err = DeserializationError::InvalidInput; | ||||||
|     switch (err.code()) { |     switch (err.code()) { | ||||||
|   | |||||||
| @@ -27,7 +27,13 @@ TEST_CASE("deserializeJson(DynamicJsonDocument&)") { | |||||||
|     SECTION("Empty input") { |     SECTION("Empty input") { | ||||||
|       DeserializationError err = deserializeJson(doc, ""); |       DeserializationError err = deserializeJson(doc, ""); | ||||||
|  |  | ||||||
|       REQUIRE(err == DeserializationError::IncompleteInput); |       REQUIRE(err == DeserializationError::EmptyInput); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     SECTION("Only spaces") { | ||||||
|  |       DeserializationError err = deserializeJson(doc, "  \t\n\r"); | ||||||
|  |  | ||||||
|  |       REQUIRE(err == DeserializationError::EmptyInput); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SECTION("issue #628") { |     SECTION("issue #628") { | ||||||
|   | |||||||
| @@ -373,16 +373,22 @@ TEST_CASE("Comments in objects") { | |||||||
| TEST_CASE("Comments alone") { | TEST_CASE("Comments alone") { | ||||||
|   DynamicJsonDocument doc(2048); |   DynamicJsonDocument doc(2048); | ||||||
|  |  | ||||||
|   SECTION("Just a trailing comment") { |   SECTION("Just a trailing comment with no line break") { | ||||||
|     DeserializationError err = deserializeJson(doc, "// comment"); |     DeserializationError err = deserializeJson(doc, "// comment"); | ||||||
|  |  | ||||||
|     REQUIRE(err == DeserializationError::IncompleteInput); |     REQUIRE(err == DeserializationError::IncompleteInput); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   SECTION("Just a trailing comment with no a break") { | ||||||
|  |     DeserializationError err = deserializeJson(doc, "// comment\n"); | ||||||
|  |  | ||||||
|  |     REQUIRE(err == DeserializationError::EmptyInput); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   SECTION("Just a block comment") { |   SECTION("Just a block comment") { | ||||||
|     DeserializationError err = deserializeJson(doc, "/*comment*/"); |     DeserializationError err = deserializeJson(doc, "/*comment*/"); | ||||||
|  |  | ||||||
|     REQUIRE(err == DeserializationError::IncompleteInput); |     REQUIRE(err == DeserializationError::EmptyInput); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("Just a slash") { |   SECTION("Just a slash") { | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ add_executable(MsgPackDeserializerTests | |||||||
| 	doubleToFloat.cpp | 	doubleToFloat.cpp | ||||||
| 	incompleteInput.cpp | 	incompleteInput.cpp | ||||||
| 	input_types.cpp | 	input_types.cpp | ||||||
|  | 	misc.cpp | ||||||
| 	nestingLimit.cpp | 	nestingLimit.cpp | ||||||
| 	notSupported.cpp | 	notSupported.cpp | ||||||
| ) | ) | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								extras/tests/MsgPackDeserializer/misc.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								extras/tests/MsgPackDeserializer/misc.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2020 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #include <ArduinoJson.h> | ||||||
|  | #include <catch.hpp> | ||||||
|  |  | ||||||
|  | TEST_CASE("deserializeMsgPack() returns EmptyInput") { | ||||||
|  |   StaticJsonDocument<100> doc; | ||||||
|  |  | ||||||
|  |   SECTION("from sized buffer") { | ||||||
|  |     DeserializationError err = deserializeMsgPack(doc, "", 0); | ||||||
|  |  | ||||||
|  |     REQUIRE(err == DeserializationError::EmptyInput); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("from stream") { | ||||||
|  |     std::istringstream input(""); | ||||||
|  |  | ||||||
|  |     DeserializationError err = deserializeMsgPack(doc, input); | ||||||
|  |  | ||||||
|  |     REQUIRE(err == DeserializationError::EmptyInput); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -20,6 +20,7 @@ class DeserializationError { | |||||||
|  public: |  public: | ||||||
|   enum Code { |   enum Code { | ||||||
|     Ok, |     Ok, | ||||||
|  |     EmptyInput, | ||||||
|     IncompleteInput, |     IncompleteInput, | ||||||
|     InvalidInput, |     InvalidInput, | ||||||
|     NoMemory, |     NoMemory, | ||||||
| @@ -77,22 +78,12 @@ class DeserializationError { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   const char* c_str() const { |   const char* c_str() const { | ||||||
|     switch (_code) { |     static const char* messages[] = { | ||||||
|       case Ok: |         "Ok",       "EmptyInput",   "IncompleteInput", "InvalidInput", | ||||||
|         return "Ok"; |         "NoMemory", "NotSupported", "TooDeep"}; | ||||||
|       case TooDeep: |     ARDUINOJSON_ASSERT(static_cast<size_t>(_code) < | ||||||
|         return "TooDeep"; |                        sizeof(messages) / sizeof(messages[0])); | ||||||
|       case NoMemory: |     return messages[_code]; | ||||||
|         return "NoMemory"; |  | ||||||
|       case InvalidInput: |  | ||||||
|         return "InvalidInput"; |  | ||||||
|       case IncompleteInput: |  | ||||||
|         return "IncompleteInput"; |  | ||||||
|       case NotSupported: |  | ||||||
|         return "NotSupported"; |  | ||||||
|       default: |  | ||||||
|         return "???"; |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ class JsonDeserializer { | |||||||
|   JsonDeserializer(MemoryPool &pool, TReader reader, |   JsonDeserializer(MemoryPool &pool, TReader reader, | ||||||
|                    TStringStorage stringStorage) |                    TStringStorage stringStorage) | ||||||
|       : _stringStorage(stringStorage), |       : _stringStorage(stringStorage), | ||||||
|  |         _foundSomething(false), | ||||||
|         _latch(reader), |         _latch(reader), | ||||||
|         _pool(&pool), |         _pool(&pool), | ||||||
|         _error(DeserializationError::Ok) {} |         _error(DeserializationError::Ok) {} | ||||||
| @@ -34,7 +35,7 @@ class JsonDeserializer { | |||||||
|  |  | ||||||
|     if (!_error && _latch.last() != 0 && !variant.isEnclosed()) { |     if (!_error && _latch.last() != 0 && !variant.isEnclosed()) { | ||||||
|       // We don't detect trailing characters earlier, so we need to check now |       // We don't detect trailing characters earlier, so we need to check now | ||||||
|       _error = DeserializationError::InvalidInput; |       return DeserializationError::InvalidInput; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return _error; |     return _error; | ||||||
| @@ -559,7 +560,8 @@ class JsonDeserializer { | |||||||
|       switch (current()) { |       switch (current()) { | ||||||
|         // end of string |         // end of string | ||||||
|         case '\0': |         case '\0': | ||||||
|           _error = DeserializationError::IncompleteInput; |           _error = _foundSomething ? DeserializationError::IncompleteInput | ||||||
|  |                                    : DeserializationError::EmptyInput; | ||||||
|           return false; |           return false; | ||||||
|  |  | ||||||
|         // spaces |         // spaces | ||||||
| @@ -619,12 +621,14 @@ class JsonDeserializer { | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|         default: |         default: | ||||||
|  |           _foundSomething = true; | ||||||
|           return true; |           return true; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   TStringStorage _stringStorage; |   TStringStorage _stringStorage; | ||||||
|  |   bool _foundSomething; | ||||||
|   Latch<TReader> _latch; |   Latch<TReader> _latch; | ||||||
|   MemoryPool *_pool; |   MemoryPool *_pool; | ||||||
|   char _buffer[64];  // using a member instead of a local variable because it |   char _buffer[64];  // using a member instead of a local variable because it | ||||||
|   | |||||||
| @@ -21,22 +21,23 @@ class MsgPackDeserializer { | |||||||
|       : _pool(&pool), |       : _pool(&pool), | ||||||
|         _reader(reader), |         _reader(reader), | ||||||
|         _stringStorage(stringStorage), |         _stringStorage(stringStorage), | ||||||
|         _error(DeserializationError::Ok) {} |         _error(DeserializationError::Ok), | ||||||
|  |         _foundSomething(false) {} | ||||||
|  |  | ||||||
|   // TODO: add support for filter |   // TODO: add support for filter | ||||||
|   DeserializationError parse(VariantData &variant, AllowAllFilter, |   DeserializationError parse(VariantData &variant, AllowAllFilter, | ||||||
|                              NestingLimit nestingLimit) { |                              NestingLimit nestingLimit) { | ||||||
|     parseVariant(variant, nestingLimit); |     parseVariant(variant, nestingLimit); | ||||||
|     return _error; |     return _foundSomething ? _error : DeserializationError::EmptyInput; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   bool parseVariant(VariantData &variant, NestingLimit nestingLimit) { |   bool parseVariant(VariantData &variant, NestingLimit nestingLimit) { | ||||||
|     uint8_t code; |     uint8_t code; | ||||||
|     if (!readByte(code)) { |     if (!readByte(code)) | ||||||
|       _error = DeserializationError::IncompleteInput; |  | ||||||
|       return false; |       return false; | ||||||
|     } |  | ||||||
|  |     _foundSomething = true; | ||||||
|  |  | ||||||
|     if ((code & 0x80) == 0) { |     if ((code & 0x80) == 0) { | ||||||
|       variant.setUnsignedInteger(code); |       variant.setUnsignedInteger(code); | ||||||
| @@ -345,6 +346,7 @@ class MsgPackDeserializer { | |||||||
|   TReader _reader; |   TReader _reader; | ||||||
|   TStringStorage _stringStorage; |   TStringStorage _stringStorage; | ||||||
|   DeserializationError _error; |   DeserializationError _error; | ||||||
|  |   bool _foundSomething; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| template <typename TInput> | template <typename TInput> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user