Skip to content

Commit 24b5e7a

Browse files
tyler92miloyip
authored andcommitted
Fix out of bounds read with kParseValidateEncodingFlag
1 parent b1c0c28 commit 24b5e7a

2 files changed

Lines changed: 20 additions & 2 deletions

File tree

include/rapidjson/encodings.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,10 @@ struct UTF8 {
177177

178178
template <typename InputStream, typename OutputStream>
179179
static bool Validate(InputStream& is, OutputStream& os) {
180-
#define RAPIDJSON_COPY() os.Put(c = is.Take())
180+
#define RAPIDJSON_COPY() if (c != '\0') os.Put(c = is.Take())
181181
#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
182182
#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
183-
Ch c;
183+
Ch c = static_cast<Ch>(-1);
184184
RAPIDJSON_COPY();
185185
if (!(c & 0x80))
186186
return true;

test/unittest/readertest.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,24 @@ TEST(Reader, ParseString_Error) {
987987
}
988988
}
989989

990+
// 3.6 Lonely start characters near the end of the input
991+
{
992+
char e[] = { '\"', 0, '\"', '\0' };
993+
for (unsigned c = 0xC0u; c <= 0xFFu; c++) {
994+
e[1] = static_cast<char>(c);
995+
unsigned streamPos;
996+
if (c <= 0xC1u)
997+
streamPos = 2; // 0xC0 - 0xC1
998+
else if (c <= 0xDFu)
999+
streamPos = 3; // 0xC2 - 0xDF
1000+
else if (c <= 0xF4u)
1001+
streamPos = 4; // 0xE0 - 0xF4
1002+
else
1003+
streamPos = 2; // 0xF5 - 0xFF
1004+
TEST_STRING_ERROR(kParseErrorStringInvalidEncoding, e, 1u, streamPos);
1005+
}
1006+
}
1007+
9901008
// 4 Overlong sequences
9911009

9921010
// 4.1 Examples of an overlong ASCII character

0 commit comments

Comments
 (0)