Permalink
Browse files

SERVER-2950 use strtod to parse real numbers from json strings

  • Loading branch information...
1 parent 0badca8 commit 19e4da397533e2b7bbd1c217d70a98a72093738f @astaple astaple committed Jun 7, 2011
Showing with 21 additions and 11 deletions.
  1. +8 −4 db/json.cpp
  2. +13 −7 dbtests/jsontests.cpp
View
12 db/json.cpp
@@ -258,8 +258,12 @@ namespace mongo {
struct numberValue {
numberValue( ObjectBuilder &_b ) : b( _b ) {}
- void operator() ( double d ) const {
- b.back()->append( b.fieldName(), d );
+ void operator() ( const char *start, const char *end ) const {
+ // We re-parse the numeric string here because spirit parsing of strings
+ // to doubles produces different results from strtod in some cases and
+ // we want to use strtod to ensure consistency with other string to
+ // double conversions in our code.
+ b.back()->append( b.fieldName(), strtod( start, 0 ) );
}
ObjectBuilder &b;
};
@@ -462,7 +466,7 @@ namespace mongo {
elements = list_p(value, ch_p(',')[arrayNext( self.b )]);
value =
str[ stringEnd( self.b ) ] |
- number |
+ number[ numberValue( self.b ) ] |
integer |
array[ arrayEnd( self.b ) ] |
lexeme_d[ str_p( "true" ) ][ trueValue( self.b ) ] |
@@ -510,7 +514,7 @@ namespace mongo {
// real_p accepts numbers with nonsignificant zero prefixes, which
// aren't allowed in JSON. Oh well.
- number = strict_real_p[ numberValue( self.b ) ];
+ number = strict_real_p;
static int_parser<long long, 10, 1, numeric_limits<long long>::digits10 + 1> long_long_p;
integer = long_long_p[ intValue(self.b) ];
View
20 dbtests/jsontests.cpp
@@ -499,16 +499,21 @@ namespace JsonTests {
}
};
- class FancyNumber {
- public:
- virtual ~FancyNumber() {}
- void run() {
- ASSERT_EQUALS( int( 1000000 * bson().firstElement().number() ),
- int( 1000000 * fromjson( json() ).firstElement().number() ) );
+ class RealNumber : public Base {
+ virtual BSONObj bson() const {
+ BSONObjBuilder b;
+ b.append( "a", strtod( "0.7", 0 ) );
+ return b.obj();
}
+ virtual string json() const {
+ return "{ \"a\" : 0.7 }";
+ }
+ };
+
+ class FancyNumber : public Base {
virtual BSONObj bson() const {
BSONObjBuilder b;
- b.append( "a", -4.4433e-2 );
+ b.append( "a", strtod( "-4.4433e-2", 0 ) );
return b.obj();
}
virtual string json() const {
@@ -1124,6 +1129,7 @@ namespace JsonTests {
add< FromJsonTests::ReservedFieldName >();
add< FromJsonTests::OkDollarFieldName >();
add< FromJsonTests::SingleNumber >();
+ add< FromJsonTests::RealNumber >();
add< FromJsonTests::FancyNumber >();
add< FromJsonTests::TwoElements >();
add< FromJsonTests::Subobject >();

0 comments on commit 19e4da3

Please sign in to comment.