Fix a typo in ScopeGuard.h
[folly.git] / folly / json.cpp
index 9d2a53656fb8dbc5aad8f1dada924273dc082b42..f4607efd88754069754c25589886c94a8f4061bb 100644 (file)
@@ -379,7 +379,18 @@ struct Input {
     return opts_;
   }
 
-private:
+  void incrementRecursionLevel() {
+    if (currentRecursionLevel_ > opts_.recursion_limit) {
+      error("recursion limit exceeded");
+    }
+    currentRecursionLevel_++;
+  }
+
+  void decrementRecursionLevel() {
+    currentRecursionLevel_--;
+  }
+
+ private:
   void storeCurrent() {
     current_ = range_.empty() ? EOF : range_.front();
   }
@@ -389,6 +400,21 @@ private:
   json::serialization_opts const& opts_;
   unsigned lineNum_;
   int current_;
+  unsigned int currentRecursionLevel_{0};
+};
+
+class RecursionGuard {
+ public:
+  explicit RecursionGuard(Input& in) : in_(in) {
+    in_.incrementRecursionLevel();
+  }
+
+  ~RecursionGuard() {
+    in_.decrementRecursionLevel();
+  }
+
+ private:
+  Input& in_;
 };
 
 dynamic parseValue(Input& in);
@@ -486,9 +512,9 @@ dynamic parseNumber(Input& in) {
   auto const wasE = *in == 'e' || *in == 'E';
 
   constexpr const char* maxInt = "9223372036854775807";
-  constexpr const char* minInt = "9223372036854775808";
+  constexpr const char* minInt = "-9223372036854775808";
   constexpr auto maxIntLen = constexpr_strlen(maxInt);
-
+  constexpr auto minIntLen = constexpr_strlen(minInt);
 
   if (*in != '.' && !wasE && in.getOpts().parse_numbers_as_strings) {
     return integral;
@@ -496,8 +522,8 @@ dynamic parseNumber(Input& in) {
 
   if (*in != '.' && !wasE) {
     if (LIKELY(!in.getOpts().double_fallback || integral.size() < maxIntLen) ||
-         (integral.size() == maxIntLen &&
-           (integral <= maxInt || (integral == minInt && negative)))) {
+        (!negative && integral.size() == maxIntLen && integral <= maxInt) ||
+        (negative && integral.size() == minIntLen && integral <= minInt)) {
       auto val = to<int64_t>(integral);
       in.skipWhitespace();
       return val;
@@ -627,6 +653,8 @@ std::string parseString(Input& in) {
 }
 
 dynamic parseValue(Input& in) {
+  RecursionGuard guard(in);
+
   in.skipWhitespace();
   return *in == '[' ? parseArray(in) :
          *in == '{' ? parseObject(in) :