mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Fix buffer overflow (pull request #81)
This commit is contained in:
		
				
					committed by
					
						 Benoit Blanchon
						Benoit Blanchon
					
				
			
			
				
	
			
			
			
						parent
						
							08d05df00e
						
					
				
				
					commit
					5e7b9ec688
				
			| @@ -1,6 +1,13 @@ | ||||
| Arduino JSON: change log | ||||
| ======================== | ||||
|  | ||||
| v4.5 | ||||
| ---- | ||||
|  | ||||
| * Fixed buffer overflow when input contains a backslash followed by a terminator (issue #81) | ||||
|  | ||||
| **Upgrading is recommended** since previous versions contain a potential security risk. | ||||
|  | ||||
| v4.4 | ||||
| ---- | ||||
|  | ||||
|   | ||||
| @@ -58,46 +58,44 @@ static char unescapeChar(char c) { | ||||
| static inline bool isQuote(char c) { return c == '\"' || c == '\''; } | ||||
|  | ||||
| char *QuotedString::extractFrom(char *input, char **endPtr) { | ||||
|   char firstChar = *input; | ||||
|  | ||||
|   if (!isQuote(firstChar)) { | ||||
|     // must start with a quote | ||||
|     return NULL; | ||||
|   } | ||||
|  | ||||
|   char stopChar = firstChar;  // closing quote is the same as opening quote | ||||
|  | ||||
|   char *startPtr = input + 1;  // skip the quote | ||||
|   char *readPtr = startPtr; | ||||
|   char *writePtr = startPtr; | ||||
|   char c; | ||||
|  | ||||
|   char firstChar = *input; | ||||
|   char stopChar = firstChar;  // closing quote is the same as opening quote | ||||
|  | ||||
|   if (!isQuote(firstChar)) goto ERROR_OPENING_QUOTE_MISSING; | ||||
|  | ||||
|   for (;;) { | ||||
|     c = *readPtr++; | ||||
|  | ||||
|     if (c == '\0') { | ||||
|       // premature ending | ||||
|       return NULL; | ||||
|     } | ||||
|     if (c == '\0') goto ERROR_CLOSING_QUOTE_MISSING; | ||||
|  | ||||
|     if (c == stopChar) { | ||||
|       // closing quote | ||||
|       break; | ||||
|     } | ||||
|     if (c == stopChar) goto SUCCESS; | ||||
|  | ||||
|     if (c == '\\') { | ||||
|       // replace char | ||||
|       c = unescapeChar(*readPtr++); | ||||
|       if (c == '\0') goto ERROR_ESCAPE_SEQUENCE_INTERRUPTED; | ||||
|     } | ||||
|  | ||||
|     *writePtr++ = c; | ||||
|   } | ||||
|  | ||||
| SUCCESS: | ||||
|   // end the string here | ||||
|   *writePtr = '\0'; | ||||
|  | ||||
|   // update end ptr | ||||
|   *endPtr = readPtr; | ||||
|  | ||||
|   // return pointer to unquoted string | ||||
|   return startPtr; | ||||
|  | ||||
| ERROR_OPENING_QUOTE_MISSING: | ||||
| ERROR_CLOSING_QUOTE_MISSING: | ||||
| ERROR_ESCAPE_SEQUENCE_INTERRUPTED: | ||||
|   return NULL; | ||||
| } | ||||
|   | ||||
| @@ -16,6 +16,11 @@ class QuotedString_ExtractFrom_Tests : public testing::Test { | ||||
|     _result = QuotedString::extractFrom(_jsonString, &_trailing); | ||||
|   } | ||||
|  | ||||
|   void whenInputIs(const char *json, size_t len) { | ||||
|     memcpy(_jsonString, json, len); | ||||
|     _result = QuotedString::extractFrom(_jsonString, &_trailing); | ||||
|   } | ||||
|  | ||||
|   void resultMustBe(const char *expected) { EXPECT_STREQ(expected, _result); } | ||||
|  | ||||
|   void trailingMustBe(const char *expected) { | ||||
| @@ -134,3 +139,8 @@ TEST_F(QuotedString_ExtractFrom_Tests, AllEscapedCharsTogether) { | ||||
|   whenInputIs("\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\""); | ||||
|   resultMustBe("1\"2\\3/4\b5\f6\n7\r8\t9"); | ||||
| } | ||||
|  | ||||
| TEST_F(QuotedString_ExtractFrom_Tests, UnterminatedEscapeSequence) { | ||||
|   whenInputIs("\"\\\0\"", 4); | ||||
|   resultMustBe(0); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user