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
|
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
|
v4.4
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@ -58,46 +58,44 @@ static char unescapeChar(char c) {
|
|||||||
static inline bool isQuote(char c) { return c == '\"' || c == '\''; }
|
static inline bool isQuote(char c) { return c == '\"' || c == '\''; }
|
||||||
|
|
||||||
char *QuotedString::extractFrom(char *input, char **endPtr) {
|
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 *startPtr = input + 1; // skip the quote
|
||||||
char *readPtr = startPtr;
|
char *readPtr = startPtr;
|
||||||
char *writePtr = startPtr;
|
char *writePtr = startPtr;
|
||||||
char c;
|
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 (;;) {
|
for (;;) {
|
||||||
c = *readPtr++;
|
c = *readPtr++;
|
||||||
|
|
||||||
if (c == '\0') {
|
if (c == '\0') goto ERROR_CLOSING_QUOTE_MISSING;
|
||||||
// premature ending
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == stopChar) {
|
if (c == stopChar) goto SUCCESS;
|
||||||
// closing quote
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
// replace char
|
// replace char
|
||||||
c = unescapeChar(*readPtr++);
|
c = unescapeChar(*readPtr++);
|
||||||
|
if (c == '\0') goto ERROR_ESCAPE_SEQUENCE_INTERRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
*writePtr++ = c;
|
*writePtr++ = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SUCCESS:
|
||||||
// end the string here
|
// end the string here
|
||||||
*writePtr = '\0';
|
*writePtr = '\0';
|
||||||
|
|
||||||
// update end ptr
|
// update end ptr
|
||||||
*endPtr = readPtr;
|
*endPtr = readPtr;
|
||||||
|
|
||||||
|
// return pointer to unquoted string
|
||||||
return startPtr;
|
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);
|
_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 resultMustBe(const char *expected) { EXPECT_STREQ(expected, _result); }
|
||||||
|
|
||||||
void trailingMustBe(const char *expected) {
|
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\"");
|
whenInputIs("\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"");
|
||||||
resultMustBe("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