forked from bblanchon/ArduinoJson
Fix buffer overflow (pull request #81)
This commit is contained in:
committed by
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