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)) { } else if(isSpace(c)) {
break; break;
} else { } else {
pushState(currentState_); int rv = pushState(currentState_);
if(rv < 0) {
return rv;
}
currentState_ = JSON_VALUE; currentState_ = JSON_VALUE;
runBeginCallback(STRUCT_ARRAY_DATA_T); runBeginCallback(STRUCT_ARRAY_DATA_T);
} }
@ -208,11 +211,15 @@ ssize_t JsonParser::parseUpdate(const char* data, size_t size)
break; break;
case JSON_OBJECT_KEY: case JSON_OBJECT_KEY:
switch(c) { switch(c) {
case '"': case '"': {
pushState(currentState_); int rv = pushState(currentState_);
if(rv < 0) {
return rv;
}
currentState_ = JSON_STRING; currentState_ = JSON_STRING;
runBeginCallback(STRUCT_DICT_KEY_T); runBeginCallback(STRUCT_DICT_KEY_T);
break; break;
}
case '}': case '}':
onObjectEnd(); onObjectEnd();
break; 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); stateStack_.push(state);
return 0;
}
} }
int JsonParser::stateTop() const int JsonParser::stateTop() const

View File

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

View File

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