mirror of
https://github.com/Tencent/rapidjson.git
synced 2025-03-09 19:24:23 +01:00
Comments parsing fixes.
* Comments parsing function correctly handles EOF. * Since SkipWhitespaceAndComments can generate errors, its calls should be followed by RAPIDJSON_PARSE_ERROR_EARLY_RETURN macro. * Some tests to make the bug never appear again.
This commit is contained in:
parent
5ce78b135d
commit
f7960ac0e8
@ -400,6 +400,7 @@ public:
|
|||||||
ClearStackOnExit scope(*this);
|
ClearStackOnExit scope(*this);
|
||||||
|
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||||
|
|
||||||
if (is.Peek() == '\0') {
|
if (is.Peek() == '\0') {
|
||||||
RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());
|
RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());
|
||||||
@ -411,6 +412,7 @@ public:
|
|||||||
|
|
||||||
if (!(parseFlags & kParseStopWhenDoneFlag)) {
|
if (!(parseFlags & kParseStopWhenDoneFlag)) {
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||||
|
|
||||||
if (is.Peek() != '\0') {
|
if (is.Peek() != '\0') {
|
||||||
RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());
|
RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());
|
||||||
@ -473,10 +475,21 @@ private:
|
|||||||
|
|
||||||
if (is.Peek() == '*') {
|
if (is.Peek() == '*') {
|
||||||
is.Take();
|
is.Take();
|
||||||
while (is.Take() != '*' || is.Take() != '/') { }
|
while (true) {
|
||||||
|
if (is.Peek() == '\0')
|
||||||
|
RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
|
||||||
|
|
||||||
|
if (is.Take() == '*') {
|
||||||
|
if (is.Peek() == '\0')
|
||||||
|
RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
|
||||||
|
|
||||||
|
if (is.Take() == '/')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (is.Peek() == '/') {
|
} else if (is.Peek() == '/') {
|
||||||
is.Take();
|
is.Take();
|
||||||
while (is.Take() != '\n') { }
|
while (is.Peek() != '\0' && is.Take() != '\n') { }
|
||||||
} else {
|
} else {
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
|
RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
|
||||||
}
|
}
|
||||||
@ -496,6 +509,7 @@ private:
|
|||||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||||
|
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||||
|
|
||||||
if (is.Peek() == '}') {
|
if (is.Peek() == '}') {
|
||||||
is.Take();
|
is.Take();
|
||||||
@ -512,21 +526,27 @@ private:
|
|||||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||||
|
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||||
|
|
||||||
if (is.Take() != ':')
|
if (is.Take() != ':')
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
|
RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
|
||||||
|
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||||
|
|
||||||
ParseValue<parseFlags>(is, handler);
|
ParseValue<parseFlags>(is, handler);
|
||||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||||
|
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||||
|
|
||||||
++memberCount;
|
++memberCount;
|
||||||
|
|
||||||
switch (is.Take()) {
|
switch (is.Take()) {
|
||||||
case ',': SkipWhitespaceAndComments<parseFlags>(is); break;
|
case ',':
|
||||||
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||||
|
break;
|
||||||
case '}':
|
case '}':
|
||||||
if (!handler.EndObject(memberCount))
|
if (!handler.EndObject(memberCount))
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||||
@ -546,6 +566,7 @@ private:
|
|||||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||||
|
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||||
|
|
||||||
if (is.Peek() == ']') {
|
if (is.Peek() == ']') {
|
||||||
is.Take();
|
is.Take();
|
||||||
@ -560,9 +581,13 @@ private:
|
|||||||
|
|
||||||
++elementCount;
|
++elementCount;
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||||
|
|
||||||
switch (is.Take()) {
|
switch (is.Take()) {
|
||||||
case ',': SkipWhitespaceAndComments<parseFlags>(is); break;
|
case ',':
|
||||||
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||||
|
break;
|
||||||
case ']':
|
case ']':
|
||||||
if (!handler.EndArray(elementCount))
|
if (!handler.EndArray(elementCount))
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||||
@ -1429,6 +1454,7 @@ private:
|
|||||||
IterativeParsingState state = IterativeParsingStartState;
|
IterativeParsingState state = IterativeParsingStartState;
|
||||||
|
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||||
while (is.Peek() != '\0') {
|
while (is.Peek() != '\0') {
|
||||||
Token t = Tokenize(is.Peek());
|
Token t = Tokenize(is.Peek());
|
||||||
IterativeParsingState n = Predict(state, t);
|
IterativeParsingState n = Predict(state, t);
|
||||||
@ -1446,6 +1472,7 @@ private:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the end of file.
|
// Handle the end of file.
|
||||||
|
@ -1387,6 +1387,19 @@ TEST(Reader, ParseEmptyOnelineComment) {
|
|||||||
EXPECT_EQ(20u, h.step_);
|
EXPECT_EQ(20u, h.step_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Reader, ParseMultipleCommentsInARow) {
|
||||||
|
const char* json =
|
||||||
|
"{/* first comment *//* second */\n"
|
||||||
|
"/* third */ /*fourth*/// last one\n"
|
||||||
|
"\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
|
||||||
|
|
||||||
|
StringStream s(json);
|
||||||
|
ParseObjectHandler h;
|
||||||
|
Reader reader;
|
||||||
|
EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
|
||||||
|
EXPECT_EQ(20u, h.step_);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Reader, InlineCommentsAreDisabledByDefault) {
|
TEST(Reader, InlineCommentsAreDisabledByDefault) {
|
||||||
{
|
{
|
||||||
const char* json = "{/* Inline comment. */\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
|
const char* json = "{/* Inline comment. */\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
|
||||||
@ -1419,6 +1432,26 @@ TEST(Reader, OnelineCommentsAreDisabledByDefault) {
|
|||||||
EXPECT_FALSE(reader.Parse<kParseDefaultFlags>(s, h));
|
EXPECT_FALSE(reader.Parse<kParseDefaultFlags>(s, h));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Reader, EofAfterOneLineComment) {
|
||||||
|
const char* json = "{\"hello\" : \"world\" // EOF is here -->\0 \n}";
|
||||||
|
|
||||||
|
StringStream s(json);
|
||||||
|
ParseObjectHandler h;
|
||||||
|
Reader reader;
|
||||||
|
EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
|
||||||
|
EXPECT_EQ(kParseErrorObjectMissCommaOrCurlyBracket, reader.GetParseErrorCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Reader, IncompleteMultilineComment) {
|
||||||
|
const char* json = "{\"hello\" : \"world\" /* EOF is here -->\0 */}";
|
||||||
|
|
||||||
|
StringStream s(json);
|
||||||
|
ParseObjectHandler h;
|
||||||
|
Reader reader;
|
||||||
|
EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
|
||||||
|
EXPECT_EQ(kParseErrorUnspecificSyntaxError, reader.GetParseErrorCode());
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user