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 ();
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:
@@ -1215,8 +1247,12 @@ bool OurReader::readToken(Token& token) {
12151247 case ' 8' :
12161248 case ' 9' :
12171249 case ' -' :
1218- token.type_ = tokenNumber;
1219- readNumber ();
1250+ if (readNumber ()) {
1251+ token.type_ = tokenNumber;
1252+ } else {
1253+ token.type_ = tokenNegInf;
1254+ ok = features_.allowSpecialFloats_ && match (" nfinity" , 7 );
1255+ }
12201256 break ;
12211257 case ' t' :
12221258 token.type_ = tokenTrue;
@@ -1230,6 +1266,22 @@ bool OurReader::readToken(Token& token) {
12301266 token.type_ = tokenNull;
12311267 ok = match (" ull" , 3 );
12321268 break ;
1269+ case ' N' :
1270+ if (features_.allowSpecialFloats_ ) {
1271+ token.type_ = tokenNaN;
1272+ ok = match (" aN" , 2 );
1273+ } else {
1274+ ok = false ;
1275+ }
1276+ break ;
1277+ case ' I' :
1278+ if (features_.allowSpecialFloats_ ) {
1279+ token.type_ = tokenPosInf;
1280+ ok = match (" nfinity" , 7 );
1281+ } else {
1282+ ok = false ;
1283+ }
1284+ break ;
12331285 case ' ,' :
12341286 token.type_ = tokenArraySeparator;
12351287 break ;
@@ -1330,8 +1382,12 @@ bool OurReader::readCppStyleComment() {
13301382 return true ;
13311383}
13321384
1333- void OurReader::readNumber () {
1385+ bool OurReader::readNumber () {
13341386 const char *p = current_;
1387+ if (p != end_ && *p == ' I' ) {
1388+ current_ = ++p;
1389+ return false ;
1390+ }
13351391 char c = ' 0' ; // stopgap for already consumed character
13361392 // integral part
13371393 while (c >= ' 0' && c <= ' 9' )
@@ -1350,6 +1406,7 @@ void OurReader::readNumber() {
13501406 while (c >= ' 0' && c <= ' 9' )
13511407 c = (current_ = p) < end_ ? *p++ : 0 ;
13521408 }
1409+ return true ;
13531410}
13541411bool OurReader::readString () {
13551412 Char c = 0 ;
@@ -1758,15 +1815,7 @@ std::string OurReader::getLocationLineAndColumn(Location location) const {
17581815 int line, column;
17591816 getLocationLineAndColumn (location, line, column);
17601817 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
17681818 snprintf (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
1769- #endif
17701819 return buffer;
17711820}
17721821
@@ -1880,6 +1929,7 @@ CharReader* CharReaderBuilder::newCharReader() const
18801929 features.stackLimit_ = settings_[" stackLimit" ].asInt ();
18811930 features.failIfExtra_ = settings_[" failIfExtra" ].asBool ();
18821931 features.rejectDupKeys_ = settings_[" rejectDupKeys" ].asBool ();
1932+ features.allowSpecialFloats_ = settings_[" allowSpecialFloats" ].asBool ();
18831933 return new OurCharReader (collectComments, features);
18841934}
18851935static void getValidReaderKeys (std::set<std::string>* valid_keys)
@@ -1894,6 +1944,7 @@ static void getValidReaderKeys(std::set<std::string>* valid_keys)
18941944 valid_keys->insert (" stackLimit" );
18951945 valid_keys->insert (" failIfExtra" );
18961946 valid_keys->insert (" rejectDupKeys" );
1947+ valid_keys->insert (" allowSpecialFloats" );
18971948}
18981949bool CharReaderBuilder::validate (Json::Value* invalid) const
18991950{
@@ -1927,6 +1978,7 @@ void CharReaderBuilder::strictMode(Json::Value* settings)
19271978 (*settings)[" allowSingleQuotes" ] = false ;
19281979 (*settings)[" failIfExtra" ] = true ;
19291980 (*settings)[" rejectDupKeys" ] = true ;
1981+ (*settings)[" allowSpecialFloats" ] = false ;
19301982// ! [CharReaderBuilderStrictMode]
19311983}
19321984// static
@@ -1942,6 +1994,7 @@ void CharReaderBuilder::setDefaults(Json::Value* settings)
19421994 (*settings)[" stackLimit" ] = 1000 ;
19431995 (*settings)[" failIfExtra" ] = false ;
19441996 (*settings)[" rejectDupKeys" ] = false ;
1997+ (*settings)[" allowSpecialFloats" ] = false ;
19451998// ! [CharReaderBuilderDefaults]
19461999}
19472000
0 commit comments