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.
@@ -753,15 +764,7 @@ std::string Reader::getLocationLineAndColumn(Location location) const {
753764 int line, column;
754765 getLocationLineAndColumn (location, line, column);
755766 char buffer[18 + 16 + 16 + 1 ];
756- #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
757- #if defined(WINCE)
758- _snprintf (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
759- #else
760- sprintf_s (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
761- #endif
762- #else
763767 snprintf (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
764- #endif
765768 return buffer;
766769}
767770
@@ -801,6 +804,7 @@ class OurFeatures {
801804 bool allowSingleQuotes_;
802805 bool failIfExtra_;
803806 bool rejectDupKeys_;
807+ bool allowSpecialFloats_;
804808 int stackLimit_;
805809}; // OurFeatures
806810
@@ -812,6 +816,7 @@ OurFeatures::OurFeatures()
812816 , allowDroppedNullPlaceholders_(false ), allowNumericKeys_(false )
813817 , allowSingleQuotes_(false )
814818 , failIfExtra_(false )
819+ , allowSpecialFloats_(false )
815820{
816821}
817822
@@ -853,6 +858,9 @@ class OurReader {
853858 tokenTrue,
854859 tokenFalse,
855860 tokenNull,
861+ tokenNaN,
862+ tokenPosInf,
863+ tokenNegInf,
856864 tokenArraySeparator,
857865 tokenMemberSeparator,
858866 tokenComment,
@@ -883,7 +891,7 @@ class OurReader {
883891 bool readCppStyleComment ();
884892 bool readString ();
885893 bool readStringSingleQuote ();
886- void readNumber ();
894+ bool readNumber (bool checkInf );
887895 bool readValue ();
888896 bool readObject (Token& token);
889897 bool readArray (Token& token);
@@ -1029,6 +1037,24 @@ bool OurReader::readValue() {
10291037 currentValue ().swapPayload (v);
10301038 }
10311039 break ;
1040+ case tokenNaN:
1041+ {
1042+ Value v (std::numeric_limits<double >::quiet_NaN ());
1043+ currentValue ().swapPayload (v);
1044+ }
1045+ break ;
1046+ case tokenPosInf:
1047+ {
1048+ Value v (std::numeric_limits<double >::infinity ());
1049+ currentValue ().swapPayload (v);
1050+ }
1051+ break ;
1052+ case tokenNegInf:
1053+ {
1054+ Value v (-std::numeric_limits<double >::infinity ());
1055+ currentValue ().swapPayload (v);
1056+ }
1057+ break ;
10321058 case tokenArraySeparator:
10331059 case tokenObjectEnd:
10341060 case tokenArrayEnd:
@@ -1105,9 +1131,16 @@ bool OurReader::readToken(Token& token) {
11051131 case ' 7' :
11061132 case ' 8' :
11071133 case ' 9' :
1108- case ' -' :
11091134 token.type_ = tokenNumber;
1110- readNumber ();
1135+ readNumber (false );
1136+ break ;
1137+ case ' -' :
1138+ if (readNumber (true )) {
1139+ token.type_ = tokenNumber;
1140+ } else {
1141+ token.type_ = tokenNegInf;
1142+ ok = features_.allowSpecialFloats_ && match (" nfinity" , 7 );
1143+ }
11111144 break ;
11121145 case ' t' :
11131146 token.type_ = tokenTrue;
@@ -1121,6 +1154,22 @@ bool OurReader::readToken(Token& token) {
11211154 token.type_ = tokenNull;
11221155 ok = match (" ull" , 3 );
11231156 break ;
1157+ case ' N' :
1158+ if (features_.allowSpecialFloats_ ) {
1159+ token.type_ = tokenNaN;
1160+ ok = match (" aN" , 2 );
1161+ } else {
1162+ ok = false ;
1163+ }
1164+ break ;
1165+ case ' I' :
1166+ if (features_.allowSpecialFloats_ ) {
1167+ token.type_ = tokenPosInf;
1168+ ok = match (" nfinity" , 7 );
1169+ } else {
1170+ ok = false ;
1171+ }
1172+ break ;
11241173 case ' ,' :
11251174 token.type_ = tokenArraySeparator;
11261175 break ;
@@ -1221,8 +1270,12 @@ bool OurReader::readCppStyleComment() {
12211270 return true ;
12221271}
12231272
1224- void OurReader::readNumber () {
1273+ bool OurReader::readNumber (bool checkInf ) {
12251274 const char *p = current_;
1275+ if (checkInf && p != end_ && *p == ' I' ) {
1276+ current_ = ++p;
1277+ return false ;
1278+ }
12261279 char c = ' 0' ; // stopgap for already consumed character
12271280 // integral part
12281281 while (c >= ' 0' && c <= ' 9' )
@@ -1241,6 +1294,7 @@ void OurReader::readNumber() {
12411294 while (c >= ' 0' && c <= ' 9' )
12421295 c = (current_ = p) < end_ ? *p++ : 0 ;
12431296 }
1297+ return true ;
12441298}
12451299bool OurReader::readString () {
12461300 Char c = 0 ;
@@ -1641,15 +1695,7 @@ std::string OurReader::getLocationLineAndColumn(Location location) const {
16411695 int line, column;
16421696 getLocationLineAndColumn (location, line, column);
16431697 char buffer[18 + 16 + 16 + 1 ];
1644- #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
1645- #if defined(WINCE)
1646- _snprintf (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
1647- #else
1648- sprintf_s (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
1649- #endif
1650- #else
16511698 snprintf (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
1652- #endif
16531699 return buffer;
16541700}
16551701
@@ -1709,6 +1755,7 @@ CharReader* CharReaderBuilder::newCharReader() const
17091755 features.stackLimit_ = settings_[" stackLimit" ].asInt ();
17101756 features.failIfExtra_ = settings_[" failIfExtra" ].asBool ();
17111757 features.rejectDupKeys_ = settings_[" rejectDupKeys" ].asBool ();
1758+ features.allowSpecialFloats_ = settings_[" allowSpecialFloats" ].asBool ();
17121759 return new OurCharReader (collectComments, features);
17131760}
17141761static void getValidReaderKeys (std::set<std::string>* valid_keys)
@@ -1723,6 +1770,7 @@ static void getValidReaderKeys(std::set<std::string>* valid_keys)
17231770 valid_keys->insert (" stackLimit" );
17241771 valid_keys->insert (" failIfExtra" );
17251772 valid_keys->insert (" rejectDupKeys" );
1773+ valid_keys->insert (" allowSpecialFloats" );
17261774}
17271775bool CharReaderBuilder::validate (Json::Value* invalid) const
17281776{
@@ -1756,6 +1804,7 @@ void CharReaderBuilder::strictMode(Json::Value* settings)
17561804 (*settings)[" allowSingleQuotes" ] = false ;
17571805 (*settings)[" failIfExtra" ] = true ;
17581806 (*settings)[" rejectDupKeys" ] = true ;
1807+ (*settings)[" allowSpecialFloats" ] = false ;
17591808// ! [CharReaderBuilderStrictMode]
17601809}
17611810// static
@@ -1771,6 +1820,7 @@ void CharReaderBuilder::setDefaults(Json::Value* settings)
17711820 (*settings)[" stackLimit" ] = 1000 ;
17721821 (*settings)[" failIfExtra" ] = false ;
17731822 (*settings)[" rejectDupKeys" ] = false ;
1823+ (*settings)[" allowSpecialFloats" ] = false ;
17741824// ! [CharReaderBuilderDefaults]
17751825}
17761826
0 commit comments