Procházet zdrojové kódy

Check structure depth when parsing JSON

Tatsuhiro Tsujikawa před 13 roky
rodič
revize
cd67e27ca4
3 změnil soubory, kde provedl 23 přidání a 7 odebrání
  1. 17 5
      src/JsonParser.cc
  2. 3 2
      src/JsonParser.h
  3. 3 0
      test/ValueBaseJsonParserTest.cc

+ 17 - 5
src/JsonParser.cc

@@ -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)
 {
-  stateStack_.push(state);
+  if(stateStack_.size() >= 50) {
+    return ERR_STRUCTURE_TOO_DEEP;
+  } else {
+    stateStack_.push(state);
+    return 0;
+  }
 }
 
 int JsonParser::stateTop() const

+ 3 - 2
src/JsonParser.h

@@ -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);

+ 3 - 0
test/ValueBaseJsonParserTest.cc

@@ -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