[svn] commit: r2114 - in /branches/trac172/src/lib/cc: data.cc data.h data_unittests.cc
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Jun 15 13:37:41 UTC 2010
Author: jelte
Date: Tue Jun 15 13:37:41 2010
New Revision: 2114
Log:
rename ParseError to JSONError
check for overflow when parsing numbers
Modified:
branches/trac172/src/lib/cc/data.cc
branches/trac172/src/lib/cc/data.h
branches/trac172/src/lib/cc/data_unittests.cc
Modified: branches/trac172/src/lib/cc/data.cc
==============================================================================
--- branches/trac172/src/lib/cc/data.cc (original)
+++ branches/trac172/src/lib/cc/data.cc Tue Jun 15 13:37:41 2010
@@ -26,6 +26,8 @@
#include <boost/algorithm/string.hpp> // for iequals
+#include <cmath>
+
using namespace std;
namespace {
@@ -201,14 +203,14 @@
namespace {
inline void
-throwParseError(const std::string& error, const std::string& file, int line = 0, int pos = 0)
+throwJSONError(const std::string& error, const std::string& file, int line = 0, int pos = 0)
{
if (line != 0 || pos != 0) {
std::stringstream ss;
ss << error << " in " + file + ":" << line << ":" << pos;
- throw ParseError(ss.str());
- } else {
- throw ParseError(error);
+ throw JSONError(ss.str());
+ } else {
+ throw JSONError(error);
}
}
}
@@ -321,17 +323,17 @@
--pos;
return;
} else {
- throwParseError(std::string("'") + c + "' read, one of \"" + chars + "\" expected", file, line, pos);
- }
- }
- throwParseError(std::string("EOF read, one of \"") + chars + "\" expected", file, line, pos);
+ throwJSONError(std::string("'") + c + "' read, one of \"" + chars + "\" expected", file, line, pos);
+ }
+ }
+ throwJSONError(std::string("EOF read, one of \"") + chars + "\" expected", file, line, pos);
}
// TODO: Should we check for all other official escapes here (and
// error on the rest)?
std::string
str_from_stringstream(std::istream &in, const std::string& file, const int line,
- int& pos) throw (ParseError)
+ int& pos) throw (JSONError)
{
char c = 0;
std::stringstream ss;
@@ -341,7 +343,7 @@
c = in.get();
++pos;
} else {
- throwParseError("String expected", file, line, pos);
+ throwJSONError("String expected", file, line, pos);
}
while (c != EOF && c != '"') {
ss << c;
@@ -375,7 +377,9 @@
return result;
}
-// TODO: range checks
+// Should we change from IntElement and DoubleElement to NumberElement
+// that can also hold an e value? (and have specific getters if the
+// value is larger than an int can handle)
ElementPtr
from_stringstream_number(std::istream &in, int &pos) {
int i, d_i;
@@ -384,43 +388,43 @@
in >> i;
pos += count_chars_i(i);
+ if (in.fail()) {
+ throw JSONError("Bad integer or overflow");
+ }
if (in.peek() == '.') {
is_double = true;
in.get();
pos++;
in >> d_i;
+ if (in.fail()) {
+ throw JSONError("Bad real or overflow");
+ }
d = i + (double)d_i / 10;
pos += count_chars_i(d_i);
}
if (in.peek() == 'e' || in.peek() == 'E') {
int e;
+ double p;
in.get();
pos++;
in >> e;
+ if (in.fail()) {
+ throw JSONError("Bad exponent or overflow");
+ }
pos += count_chars_i(e);
- if (e == 0) {
- d = 1;
- i = 1;
- } else if (e < 0) {
- if (!is_double) {
+ p = pow(10, e);
+ if (p == HUGE_VAL) {
+ throw JSONError("Bad exponent or overflow");
+ }
+ if (is_double) {
+ d = d * p;
+ } else {
+ if (p > 1.0) {
+ i = i * p;
+ } else {
+ // negative exponent, so type becomes a double
is_double = true;
- d = i;
- }
- while (e < 0) {
- d = d / 10;
- e++;
- }
- } else {
- if (is_double) {
- while (e > 0) {
- d = d * 10;
- e--;
- }
- } else {
- while (e > 0) {
- i = i * 10;
- e--;
- }
+ d = i * p;
}
}
}
@@ -442,7 +446,7 @@
} else if (boost::iequals(word, "False")) {
return Element::create(false);
} else {
- throwParseError(std::string("Bad boolean value: ") + word, file, line, pos);
+ throwJSONError(std::string("Bad boolean value: ") + word, file, line, pos);
// above is a throw shortcur, return empty is never reached
return ElementPtr();
}
@@ -456,7 +460,7 @@
if (boost::iequals(word, "null")) {
return Element::create();
} else {
- throwParseError(std::string("Bad null value: ") + word, file, line, pos);
+ throwJSONError(std::string("Bad null value: ") + word, file, line, pos);
return ElementPtr();
}
}
@@ -503,7 +507,7 @@
if (key.length() > 255) {
// Map tag has one-byte length field in wire format, so the
// length cannot exceed 255.
- throwParseError("Map tag is too long", file, line, pos);
+ throwJSONError("Map tag is too long", file, line, pos);
}
skip_to(in, file, line, pos, ":", " \t\n");
@@ -524,20 +528,20 @@
}
ElementPtr
-Element::fromJSON(std::istream& in) throw(ParseError) {
+Element::fromJSON(std::istream& in) throw(JSONError) {
int line = 1, pos = 1;
return fromJSON(in, "<istream>", line, pos);
}
ElementPtr
-Element::fromJSON(std::istream& in, const std::string& file_name) throw(ParseError)
+Element::fromJSON(std::istream& in, const std::string& file_name) throw(JSONError)
{
int line = 1, pos = 1;
return fromJSON(in, file_name, line, pos);
}
ElementPtr
-Element::fromJSON(std::istream &in, const std::string& file, int& line, int& pos) throw(ParseError)
+Element::fromJSON(std::istream &in, const std::string& file, int& line, int& pos) throw(JSONError)
{
char c = 0;
ElementPtr element;
@@ -590,14 +594,14 @@
case EOF:
break;
default:
- throwParseError(std::string("error: unexpected character ") + c, file, line, pos);
+ throwJSONError(std::string("error: unexpected character ") + c, file, line, pos);
break;
}
}
if (el_read) {
return element;
} else {
- throw ParseError("nothing read");
+ throw JSONError("nothing read");
}
}
Modified: branches/trac172/src/lib/cc/data.h
==============================================================================
--- branches/trac172/src/lib/cc/data.h (original)
+++ branches/trac172/src/lib/cc/data.h Tue Jun 15 13:37:41 2010
@@ -48,9 +48,9 @@
// i'd like to use Exception here but we need one that is derived from
// runtime_error (as this one is directly based on external data, and
// i want to add some values to any static data string that is provided)
-class ParseError : public std::runtime_error {
-public:
- ParseError(const std::string &err) : std::runtime_error(err) {};
+class JSONError : public std::runtime_error {
+public:
+ JSONError(const std::string &err) : std::runtime_error(err) {};
};
///
@@ -298,7 +298,7 @@
/// \brief These functions will parse the given string (JSON)
/// representation of a compound element. If there is a parse
- /// error, an exception of the type isc::data::ParseError is thrown.
+ /// error, an exception of the type isc::data::JSONError is thrown.
//@{
/// Creates an Element from the given JSON string
@@ -313,8 +313,8 @@
/// \param in The string to parse the element from
/// \return An ElementPtr that contains the element(s) specified
/// in the given input stream.
- static ElementPtr fromJSON(std::istream& in) throw(ParseError);
- static ElementPtr fromJSON(std::istream& in, const std::string& file_name) throw(ParseError);
+ static ElementPtr fromJSON(std::istream& in) throw(JSONError);
+ static ElementPtr fromJSON(std::istream& in, const std::string& file_name) throw(JSONError);
/// Creates an Element from the given input stream, where we keep
/// track of the location in the stream for error reporting.
@@ -327,7 +327,7 @@
/// \return An ElementPtr that contains the element(s) specified
/// in the given input stream.
// make this one private?
- static ElementPtr fromJSON(std::istream& in, const std::string& file, int& line, int &pos) throw(ParseError);
+ static ElementPtr fromJSON(std::istream& in, const std::string& file, int& line, int &pos) throw(JSONError);
//@}
/// \name Wire format factory functions
Modified: branches/trac172/src/lib/cc/data_unittests.cc
==============================================================================
--- branches/trac172/src/lib/cc/data_unittests.cc (original)
+++ branches/trac172/src/lib/cc/data_unittests.cc Tue Jun 15 13:37:41 2010
@@ -44,9 +44,10 @@
EXPECT_EQ(list_el.getType(), Element::list);
MapElement map_el = MapElement();
EXPECT_EQ(map_el.getType(), Element::map);
-}
-
-TEST(Element, from_and_to_str) {
+
+}
+
+TEST(Element, from_and_to_json) {
// this test checks whether the str() method returns the same
// string that was used for creation
ElementPtr el;
@@ -73,7 +74,7 @@
// some parse errors
try {
Element::fromJSON("{1}");
- } catch (isc::data::ParseError pe) {
+ } catch (isc::data::JSONError pe) {
std::string s = std::string(pe.what());
EXPECT_EQ(s, "String expected in <string>:1:3");
}
@@ -89,7 +90,7 @@
sv.push_back("");
BOOST_FOREACH(std::string s, sv) {
- EXPECT_THROW(el = Element::fromJSON(s), isc::data::ParseError);
+ EXPECT_THROW(el = Element::fromJSON(s), isc::data::JSONError);
}
// some json specific format tests, here the str() output is
@@ -102,6 +103,13 @@
EXPECT_EQ("100", Element::fromJSON("1.0e2")->str());
EXPECT_EQ("0.01", Element::fromJSON("1.0e-2")->str());
EXPECT_EQ("0.012", Element::fromJSON("1.2e-2")->str());
+
+ EXPECT_THROW(Element::fromJSON("12345678901234567890")->str(), JSONError);
+ EXPECT_THROW(Element::fromJSON("1.12345678901234567890")->str(), JSONError);
+ EXPECT_THROW(Element::fromJSON("1.1e12345678901234567890")->str(), JSONError);
+ EXPECT_THROW(Element::fromJSON("1e12345678901234567890")->str(), JSONError);
+ EXPECT_THROW(Element::fromJSON("1e50000")->str(), JSONError);
+
}
TEST(Element, create_and_value_throws) {
@@ -231,7 +239,7 @@
long_maptag.push_back('f');
EXPECT_THROW(Element::fromJSON("{ \"" + long_maptag +
"\": \"bar\"}"),
- ParseError);
+ JSONError);
EXPECT_THROW(el->set(long_maptag, Element::create("bar")), TypeError);
More information about the bind10-changes
mailing list