mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Allowed non-quoted key to contain underscores (fixes #665)
This commit is contained in:
		| @@ -5,6 +5,7 @@ HEAD | ||||
| ---- | ||||
|  | ||||
| * Fixed `JsonVariant::operator|(int)` that returned the default value if the variant contained a double (issue #675) | ||||
| * Allowed non-quoted key to contain underscores (issue #665) | ||||
|  | ||||
| v5.13.0 | ||||
| ------- | ||||
|   | ||||
| @@ -50,13 +50,13 @@ class JsonParser { | ||||
|   inline bool parseObjectTo(JsonVariant *destination); | ||||
|   inline bool parseStringTo(JsonVariant *destination); | ||||
|  | ||||
|   static inline bool isInRange(char c, char min, char max) { | ||||
|   static inline bool isBetween(char c, char min, char max) { | ||||
|     return min <= c && c <= max; | ||||
|   } | ||||
|  | ||||
|   static inline bool isLetterOrNumber(char c) { | ||||
|     return isInRange(c, '0', '9') || isInRange(c, 'a', 'z') || | ||||
|            isInRange(c, 'A', 'Z') || c == '+' || c == '-' || c == '.'; | ||||
|   static inline bool canBeInNonQuotedString(char c) { | ||||
|     return isBetween(c, '0', '9') || isBetween(c, '_', 'z') || | ||||
|            isBetween(c, 'A', 'Z') || c == '+' || c == '-' || c == '.'; | ||||
|   } | ||||
|  | ||||
|   static inline bool isQuote(char c) { | ||||
| @@ -99,5 +99,5 @@ inline typename JsonParserBuilder<TJsonBuffer, TString>::TParser makeParser( | ||||
|   return JsonParserBuilder<TJsonBuffer, TString>::makeParser(buffer, json, | ||||
|                                                              nestingLimit); | ||||
| } | ||||
| } | ||||
| } | ||||
| }  // namespace Internals | ||||
| }  // namespace ArduinoJson | ||||
|   | ||||
| @@ -167,7 +167,7 @@ ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseString() { | ||||
|     } | ||||
|   } else {  // no quotes | ||||
|     for (;;) { | ||||
|       if (!isLetterOrNumber(c)) break; | ||||
|       if (!canBeInNonQuotedString(c)) break; | ||||
|       _reader.move(); | ||||
|       str.append(c); | ||||
|       c = _reader.current(); | ||||
|   | ||||
| @@ -8,82 +8,92 @@ | ||||
| TEST_CASE("JsonBuffer::parseObject()") { | ||||
|   DynamicJsonBuffer jb; | ||||
|  | ||||
|   SECTION("EmptyObject") { | ||||
|   SECTION("An empty object") { | ||||
|     JsonObject& obj = jb.parseObject("{}"); | ||||
|     REQUIRE(obj.success()); | ||||
|     REQUIRE(obj.size() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("MissingOpeningBrace") { | ||||
|     JsonObject& obj = jb.parseObject("}"); | ||||
|     REQUIRE_FALSE(obj.success()); | ||||
|   } | ||||
|  | ||||
|   SECTION("MissingClosingBrace") { | ||||
|     JsonObject& obj = jb.parseObject("{"); | ||||
|     REQUIRE_FALSE(obj.success()); | ||||
|   } | ||||
|  | ||||
|   SECTION("MissingColonAndValue") { | ||||
|     JsonObject& obj = jb.parseObject("{\"key\"}"); | ||||
|     REQUIRE_FALSE(obj.success()); | ||||
|   } | ||||
|  | ||||
|   SECTION("MissingQuotesAndColonAndValue") { | ||||
|     JsonObject& obj = jb.parseObject("{key}"); | ||||
|     REQUIRE_FALSE(obj.success()); | ||||
|   } | ||||
|  | ||||
|   SECTION("OneString") { | ||||
|   SECTION("Quotes") { | ||||
|     SECTION("Double quotes") { | ||||
|       JsonObject& obj = jb.parseObject("{\"key\":\"value\"}"); | ||||
|       REQUIRE(obj.success()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
|  | ||||
|   SECTION("OneStringSingleQuotes") { | ||||
|     SECTION("Single quotes") { | ||||
|       JsonObject& obj = jb.parseObject("{'key':'value'}"); | ||||
|       REQUIRE(obj.success()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
|  | ||||
|   SECTION("OneStringNoQuotes") { | ||||
|     SECTION("No quotes") { | ||||
|       JsonObject& obj = jb.parseObject("{key:value}"); | ||||
|       REQUIRE(obj.success()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
|  | ||||
|   SECTION("OneStringSpaceBeforeKey") { | ||||
|     SECTION("No quotes, allow underscore in key") { | ||||
|       JsonObject& obj = jb.parseObject("{_k_e_y_:42}"); | ||||
|       REQUIRE(obj.success()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["_k_e_y_"] == 42); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Spaces") { | ||||
|     SECTION("Before the key") { | ||||
|       JsonObject& obj = jb.parseObject("{ \"key\":\"value\"}"); | ||||
|       REQUIRE(obj.success()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
|  | ||||
|   SECTION("OneStringSpaceAfterKey") { | ||||
|     SECTION("After the key") { | ||||
|       JsonObject& obj = jb.parseObject("{\"key\" :\"value\"}"); | ||||
|       REQUIRE(obj.success()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
|  | ||||
|   SECTION("OneStringSpaceBeforeValue") { | ||||
|     SECTION("Before the value") { | ||||
|       JsonObject& obj = jb.parseObject("{\"key\": \"value\"}"); | ||||
|       REQUIRE(obj.success()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
|  | ||||
|   SECTION("OneStringSpaceAfterValue") { | ||||
|     SECTION("After the value") { | ||||
|       JsonObject& obj = jb.parseObject("{\"key\":\"value\" }"); | ||||
|       REQUIRE(obj.success()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
|  | ||||
|   SECTION("TwoStrings") { | ||||
|     SECTION("Before the colon") { | ||||
|       JsonObject& obj = | ||||
|           jb.parseObject("{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); | ||||
|       REQUIRE(obj.success()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"] == "value1"); | ||||
|       REQUIRE(obj["key2"] == "value2"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After the colon") { | ||||
|       JsonObject& obj = | ||||
|           jb.parseObject("{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); | ||||
|       REQUIRE(obj.success()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"] == "value1"); | ||||
|       REQUIRE(obj["key2"] == "value2"); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Values types") { | ||||
|     SECTION("String") { | ||||
|       JsonObject& obj = | ||||
|           jb.parseObject("{\"key1\":\"value1\",\"key2\":\"value2\"}"); | ||||
|       REQUIRE(obj.success()); | ||||
| @@ -92,31 +102,7 @@ TEST_CASE("JsonBuffer::parseObject()") { | ||||
|       REQUIRE(obj["key2"] == "value2"); | ||||
|     } | ||||
|  | ||||
|   SECTION("TwoStringsSpaceBeforeComma") { | ||||
|     JsonObject& obj = | ||||
|         jb.parseObject("{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); | ||||
|     REQUIRE(obj.success()); | ||||
|     REQUIRE(obj.size() == 2); | ||||
|     REQUIRE(obj["key1"] == "value1"); | ||||
|     REQUIRE(obj["key2"] == "value2"); | ||||
|   } | ||||
|  | ||||
|   SECTION("TwoStringsSpaceAfterComma") { | ||||
|     JsonObject& obj = | ||||
|         jb.parseObject("{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); | ||||
|     REQUIRE(obj.success()); | ||||
|     REQUIRE(obj.size() == 2); | ||||
|     REQUIRE(obj["key1"] == "value1"); | ||||
|     REQUIRE(obj["key2"] == "value2"); | ||||
|   } | ||||
|  | ||||
|   SECTION("EndingWithAComma") { | ||||
|     JsonObject& obj = jb.parseObject("{\"key1\":\"value1\",}"); | ||||
|     REQUIRE_FALSE(obj.success()); | ||||
|     REQUIRE(obj.size() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("TwoIntergers") { | ||||
|     SECTION("Integer") { | ||||
|       JsonObject& obj = jb.parseObject("{\"key1\":42,\"key2\":-42}"); | ||||
|       REQUIRE(obj.success()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
| @@ -124,7 +110,7 @@ TEST_CASE("JsonBuffer::parseObject()") { | ||||
|       REQUIRE(obj["key2"] == -42); | ||||
|     } | ||||
|  | ||||
|   SECTION("TwoDoubles") { | ||||
|     SECTION("Double") { | ||||
|       JsonObject& obj = jb.parseObject("{\"key1\":12.345,\"key2\":-7E89}"); | ||||
|       REQUIRE(obj.success()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
| @@ -132,7 +118,7 @@ TEST_CASE("JsonBuffer::parseObject()") { | ||||
|       REQUIRE(obj["key2"] == -7E89); | ||||
|     } | ||||
|  | ||||
|   SECTION("TwoBooleans") { | ||||
|     SECTION("Booleans") { | ||||
|       JsonObject& obj = jb.parseObject("{\"key1\":true,\"key2\":false}"); | ||||
|       REQUIRE(obj.success()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
| @@ -140,16 +126,45 @@ TEST_CASE("JsonBuffer::parseObject()") { | ||||
|       REQUIRE(obj["key2"] == false); | ||||
|     } | ||||
|  | ||||
|   SECTION("TwoNulls") { | ||||
|     SECTION("Null") { | ||||
|       JsonObject& obj = jb.parseObject("{\"key1\":null,\"key2\":null}"); | ||||
|       REQUIRE(obj.success()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"].as<char*>() == 0); | ||||
|       REQUIRE(obj["key2"].as<char*>() == 0); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("NullForKey") { | ||||
|   SECTION("Misc") { | ||||
|     SECTION("The opening brace is missing") { | ||||
|       JsonObject& obj = jb.parseObject("}"); | ||||
|       REQUIRE_FALSE(obj.success()); | ||||
|     } | ||||
|  | ||||
|     SECTION("The closing brace is missing") { | ||||
|       JsonObject& obj = jb.parseObject("{"); | ||||
|       REQUIRE_FALSE(obj.success()); | ||||
|     } | ||||
|  | ||||
|     SECTION("A quoted key without value") { | ||||
|       JsonObject& obj = jb.parseObject("{\"key\"}"); | ||||
|       REQUIRE_FALSE(obj.success()); | ||||
|     } | ||||
|  | ||||
|     SECTION("A non-quoted key without value") { | ||||
|       JsonObject& obj = jb.parseObject("{key}"); | ||||
|       REQUIRE_FALSE(obj.success()); | ||||
|     } | ||||
|  | ||||
|     SECTION("A dangling comma") { | ||||
|       JsonObject& obj = jb.parseObject("{\"key1\":\"value1\",}"); | ||||
|       REQUIRE_FALSE(obj.success()); | ||||
|       REQUIRE(obj.size() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("null as a key") { | ||||
|       JsonObject& obj = jb.parseObject("null:\"value\"}"); | ||||
|       REQUIRE_FALSE(obj.success()); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user