1717#include < sstream>
1818#include < memory>
1919#include < set>
20+ #include < limits>
2021
21- #if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
22+ #if defined(_MSC_VER)
23+ #if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above
24+ #define snprintf sprintf_s
25+ #elif _MSC_VER >= 1900 // VC++ 14.0 and above
26+ #define snprintf std::snprintf
27+ #else
2228#define snprintf _snprintf
2329#endif
30+ #elif defined(__ANDROID__)
31+ #define snprintf snprintf
32+ #elif __cplusplus >= 201103L
33+ #define snprintf std::snprintf
34+ #endif
2435
2536#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
2637// Disable warning about strdup being deprecated.
@@ -795,15 +806,7 @@ std::string Reader::getLocationLineAndColumn(Location location) const {
795806 int line, column;
796807 getLocationLineAndColumn (location, line, column);
797808 char buffer[18 + 16 + 16 + 1 ];
798- #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
799- #if defined(WINCE)
800- _snprintf (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
801- #else
802- sprintf_s (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
803- #endif
804- #else
805809 snprintf (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
806- #endif
807810 return buffer;
808811}
809812
@@ -894,6 +897,7 @@ class OurFeatures {
894897 bool allowSingleQuotes_;
895898 bool failIfExtra_;
896899 bool rejectDupKeys_;
900+ bool allowSpecialFloats_;
897901 int stackLimit_;
898902}; // OurFeatures
899903
@@ -905,6 +909,7 @@ OurFeatures::OurFeatures()
905909 , allowDroppedNullPlaceholders_(false ), allowNumericKeys_(false )
906910 , allowSingleQuotes_(false )
907911 , failIfExtra_(false )
912+ , allowSpecialFloats_(false )
908913{
909914}
910915
@@ -950,6 +955,9 @@ class OurReader {
950955 tokenTrue,
951956 tokenFalse,
952957 tokenNull,
958+ tokenNaN,
959+ tokenPosInf,
960+ tokenNegInf,
953961 tokenArraySeparator,
954962 tokenMemberSeparator,
955963 tokenComment,
@@ -980,7 +988,7 @@ class OurReader {
980988 bool readCppStyleComment ();
981989 bool readString ();
982990 bool readStringSingleQuote ();
983- void readNumber ();
991+ bool readNumber (bool checkInf );
984992 bool readValue ();
985993 bool readObject (Token& token);
986994 bool readArray (Token& token);
@@ -1134,6 +1142,30 @@ bool OurReader::readValue() {
11341142 currentValue ().setOffsetLimit (token.end_ - begin_);
11351143 }
11361144 break ;
1145+ case tokenNaN:
1146+ {
1147+ Value v (std::numeric_limits<double >::quiet_NaN ());
1148+ currentValue ().swapPayload (v);
1149+ currentValue ().setOffsetStart (token.start_ - begin_);
1150+ currentValue ().setOffsetLimit (token.end_ - begin_);
1151+ }
1152+ break ;
1153+ case tokenPosInf:
1154+ {
1155+ Value v (std::numeric_limits<double >::infinity ());
1156+ currentValue ().swapPayload (v);
1157+ currentValue ().setOffsetStart (token.start_ - begin_);
1158+ currentValue ().setOffsetLimit (token.end_ - begin_);
1159+ }
1160+ break ;
1161+ case tokenNegInf:
1162+ {
1163+ Value v (-std::numeric_limits<double >::infinity ());
1164+ currentValue ().swapPayload (v);
1165+ currentValue ().setOffsetStart (token.start_ - begin_);
1166+ currentValue ().setOffsetLimit (token.end_ - begin_);
1167+ }
1168+ break ;
11371169 case tokenArraySeparator:
11381170 case tokenObjectEnd:
11391171 case tokenArrayEnd:
@@ -1214,9 +1246,16 @@ bool OurReader::readToken(Token& token) {
12141246 case ' 7' :
12151247 case ' 8' :
12161248 case ' 9' :
1217- case ' -' :
12181249 token.type_ = tokenNumber;
1219- readNumber ();
1250+ readNumber (false );
1251+ break ;
1252+ case ' -' :
1253+ if (readNumber (true )) {
1254+ token.type_ = tokenNumber;
1255+ } else {
1256+ token.type_ = tokenNegInf;
1257+ ok = features_.allowSpecialFloats_ && match (" nfinity" , 7 );
1258+ }
12201259 break ;
12211260 case ' t' :
12221261 token.type_ = tokenTrue;
@@ -1230,6 +1269,22 @@ bool OurReader::readToken(Token& token) {
12301269 token.type_ = tokenNull;
12311270 ok = match (" ull" , 3 );
12321271 break ;
1272+ case ' N' :
1273+ if (features_.allowSpecialFloats_ ) {
1274+ token.type_ = tokenNaN;
1275+ ok = match (" aN" , 2 );
1276+ } else {
1277+ ok = false ;
1278+ }
1279+ break ;
1280+ case ' I' :
1281+ if (features_.allowSpecialFloats_ ) {
1282+ token.type_ = tokenPosInf;
1283+ ok = match (" nfinity" , 7 );
1284+ } else {
1285+ ok = false ;
1286+ }
1287+ break ;
12331288 case ' ,' :
12341289 token.type_ = tokenArraySeparator;
12351290 break ;
@@ -1330,8 +1385,12 @@ bool OurReader::readCppStyleComment() {
13301385 return true ;
13311386}
13321387
1333- void OurReader::readNumber () {
1388+ bool OurReader::readNumber (bool checkInf ) {
13341389 const char *p = current_;
1390+ if (checkInf && p != end_ && *p == ' I' ) {
1391+ current_ = ++p;
1392+ return false ;
1393+ }
13351394 char c = ' 0' ; // stopgap for already consumed character
13361395 // integral part
13371396 while (c >= ' 0' && c <= ' 9' )
@@ -1350,6 +1409,7 @@ void OurReader::readNumber() {
13501409 while (c >= ' 0' && c <= ' 9' )
13511410 c = (current_ = p) < end_ ? *p++ : 0 ;
13521411 }
1412+ return true ;
13531413}
13541414bool OurReader::readString () {
13551415 Char c = 0 ;
@@ -1758,15 +1818,7 @@ std::string OurReader::getLocationLineAndColumn(Location location) const {
17581818 int line, column;
17591819 getLocationLineAndColumn (location, line, column);
17601820 char buffer[18 + 16 + 16 + 1 ];
1761- #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
1762- #if defined(WINCE)
1763- _snprintf (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
1764- #else
1765- sprintf_s (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
1766- #endif
1767- #else
17681821 snprintf (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
1769- #endif
17701822 return buffer;
17711823}
17721824
@@ -1880,6 +1932,7 @@ CharReader* CharReaderBuilder::newCharReader() const
18801932 features.stackLimit_ = settings_[" stackLimit" ].asInt ();
18811933 features.failIfExtra_ = settings_[" failIfExtra" ].asBool ();
18821934 features.rejectDupKeys_ = settings_[" rejectDupKeys" ].asBool ();
1935+ features.allowSpecialFloats_ = settings_[" allowSpecialFloats" ].asBool ();
18831936 return new OurCharReader (collectComments, features);
18841937}
18851938static void getValidReaderKeys (std::set<std::string>* valid_keys)
@@ -1894,6 +1947,7 @@ static void getValidReaderKeys(std::set<std::string>* valid_keys)
18941947 valid_keys->insert (" stackLimit" );
18951948 valid_keys->insert (" failIfExtra" );
18961949 valid_keys->insert (" rejectDupKeys" );
1950+ valid_keys->insert (" allowSpecialFloats" );
18971951}
18981952bool CharReaderBuilder::validate (Json::Value* invalid) const
18991953{
@@ -1927,6 +1981,7 @@ void CharReaderBuilder::strictMode(Json::Value* settings)
19271981 (*settings)[" allowSingleQuotes" ] = false ;
19281982 (*settings)[" failIfExtra" ] = true ;
19291983 (*settings)[" rejectDupKeys" ] = true ;
1984+ (*settings)[" allowSpecialFloats" ] = false ;
19301985// ! [CharReaderBuilderStrictMode]
19311986}
19321987// static
@@ -1942,6 +1997,7 @@ void CharReaderBuilder::setDefaults(Json::Value* settings)
19421997 (*settings)[" stackLimit" ] = 1000 ;
19431998 (*settings)[" failIfExtra" ] = false ;
19441999 (*settings)[" rejectDupKeys" ] = false ;
2000+ (*settings)[" allowSpecialFloats" ] = false ;
19452001// ! [CharReaderBuilderDefaults]
19462002}
19472003
0 commit comments