Remove disallowed &* of FwdIterator
[folly.git] / folly / json.cpp
index 3b954ef41e27df84a912d9c88a02236b92ef9a71..3141d1b2006bce870858a5723468707fbf8008e9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2013 Facebook, Inc.
+ * Copyright 2014 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -126,6 +126,11 @@ struct Printer {
   void operator()(dynamic const& v) const {
     switch (v.type()) {
     case dynamic::DOUBLE:
+      if (!opts_.allow_nan_inf &&
+          (std::isnan(v.asDouble()) || std::isinf(v.asDouble()))) {
+        throw std::runtime_error("folly::toJson: JSON object value was a "
+          "NaN or INF");
+      }
       toAppend(v.asDouble(), &out_);
       break;
     case dynamic::INT64: {
@@ -308,6 +313,15 @@ struct Input {
     return skipWhile([] (char c) { return c >= '0' && c <= '9'; });
   }
 
+  StringPiece skipMinusAndDigits() {
+    bool firstChar = true;
+    return skipWhile([&firstChar] (char c) {
+        bool result = (c >= '0' && c <= '9') || (firstChar && c == '-');
+        firstChar = false;
+        return result;
+      });
+  }
+
   void skipWhitespace() {
     // Spaces other than ' ' characters are less common but should be
     // checked.  This configuration where we loop on the ' '
@@ -469,22 +483,19 @@ dynamic parseArray(Input& in) {
 dynamic parseNumber(Input& in) {
   bool const negative = (*in == '-');
   if (negative) {
-    ++in;
-    if (in.consume("Infinity")) {
+    if (in.consume("-Infinity")) {
       return -std::numeric_limits<double>::infinity();
     }
   }
 
-  auto integral = in.skipDigits();
-  if (integral.empty()) {
+  auto integral = in.skipMinusAndDigits();
+  if (negative && integral.size() < 2) {
     in.error("expected digits after `-'");
   }
+
   auto const wasE = *in == 'e' || *in == 'E';
   if (*in != '.' && !wasE) {
     auto val = to<int64_t>(integral);
-    if (negative) {
-      val = -val;
-    }
     in.skipWhitespace();
     return val;
   }
@@ -501,9 +512,6 @@ dynamic parseNumber(Input& in) {
   auto fullNum = makeRange(integral.begin(), end);
 
   auto val = to<double>(fullNum);
-  if (negative) {
-    val *= -1;
-  }
   return val;
 }
 
@@ -748,6 +756,7 @@ fbstring toPrettyJson(dynamic const& dyn) {
 void dynamic::print_as_pseudo_json(std::ostream& out) const {
   json::serialization_opts opts;
   opts.allow_non_string_keys = true;
+  opts.allow_nan_inf = true;
   out << json::serialize(*this, opts);
 }