Check structure depth when parsing JSON

pull/25/merge
Tatsuhiro Tsujikawa 2012-07-11 23:20:20 +09:00
parent 57b46d5123
commit cd67e27ca4
3 changed files with 23 additions and 7 deletions

View File

@ -117,7 +117,10 @@ ssize_t JsonParser::parseUpdate(const char* data, size_t size)
} else if(isSpace(c)) {
break;
} else {
pushState(currentState_);
int rv = pushState(currentState_);
if(rv < 0) {
return rv;
}
currentState_ = JSON_VALUE;
runBeginCallback(STRUCT_ARRAY_DATA_T);
}
@ -208,11 +211,15 @@ ssize_t JsonParser::parseUpdate(const char* data, size_t size)
break;
case JSON_OBJECT_KEY:
switch(c) {
case '"':
pushState(currentState_);
case '"': {
int rv = pushState(currentState_);
if(rv < 0) {
return rv;
}
currentState_ = JSON_STRING;
runBeginCallback(STRUCT_DICT_KEY_T);
break;
}
case '}':
onObjectEnd();
break;
@ -584,9 +591,14 @@ void JsonParser::onValueEnd()
}
}
void JsonParser::pushState(int state)
int JsonParser::pushState(int state)
{
if(stateStack_.size() >= 50) {
return ERR_STRUCTURE_TOO_DEEP;
} else {
stateStack_.push(state);
return 0;
}
}
int JsonParser::stateTop() const

View File

@ -55,7 +55,8 @@ enum JsonError {
ERR_NUMBER_OUT_OF_RANGE = -7,
ERR_UNEXPECTED_CHAR_BEFORE_ARRAY_SEP = -8,
ERR_UNEXPECTED_LITERAL = -9,
ERR_PREMATURE_DATA = -10
ERR_PREMATURE_DATA = -10,
ERR_STRUCTURE_TOO_DEEP = -11
};
class JsonParser {
@ -76,7 +77,7 @@ public:
// reuse.
void reset();
private:
void pushState(int state);
int pushState(int state);
int stateTop() const;
int popState();
void runBeginCallback(int elementType);

View File

@ -288,6 +288,9 @@ void ValueBaseJsonParserTest::testParseUpdate_error()
checkDecodeError("[1.1e]");
// bool
checkDecodeError("[t");
// too deep structure
checkDecodeError(std::string(51, '[')+std::string(51,']'));
checkDecodeError(std::string(50, '[')+"{\"foo\":100}"+std::string(50,']'));
}
} // namespace aria2