/*
- * 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.
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: {
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 ' '
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;
}
auto fullNum = makeRange(integral.begin(), end);
auto val = to<double>(fullNum);
- if (negative) {
- val *= -1;
- }
return val;
}
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);
}