17
17
#include < sstream>
18
18
#include < memory>
19
19
#include < set>
20
+ #include < limits>
20
21
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
22
28
#define snprintf _snprintf
23
29
#endif
30
+ #elif defined(__ANDROID__)
31
+ #define snprintf snprintf
32
+ #elif __cplusplus >= 201103L
33
+ #define snprintf std::snprintf
34
+ #endif
24
35
25
36
#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
26
37
// Disable warning about strdup being deprecated.
@@ -753,15 +764,7 @@ std::string Reader::getLocationLineAndColumn(Location location) const {
753
764
int line, column;
754
765
getLocationLineAndColumn (location, line, column);
755
766
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
763
767
snprintf (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
764
- #endif
765
768
return buffer;
766
769
}
767
770
@@ -801,6 +804,7 @@ class OurFeatures {
801
804
bool allowSingleQuotes_;
802
805
bool failIfExtra_;
803
806
bool rejectDupKeys_;
807
+ bool allowSpecialFloats_;
804
808
int stackLimit_;
805
809
}; // OurFeatures
806
810
@@ -812,6 +816,7 @@ OurFeatures::OurFeatures()
812
816
, allowDroppedNullPlaceholders_(false ), allowNumericKeys_(false )
813
817
, allowSingleQuotes_(false )
814
818
, failIfExtra_(false )
819
+ , allowSpecialFloats_(false )
815
820
{
816
821
}
817
822
@@ -853,6 +858,9 @@ class OurReader {
853
858
tokenTrue,
854
859
tokenFalse,
855
860
tokenNull,
861
+ tokenNaN,
862
+ tokenPosInf,
863
+ tokenNegInf,
856
864
tokenArraySeparator,
857
865
tokenMemberSeparator,
858
866
tokenComment,
@@ -883,7 +891,7 @@ class OurReader {
883
891
bool readCppStyleComment ();
884
892
bool readString ();
885
893
bool readStringSingleQuote ();
886
- void readNumber ();
894
+ bool readNumber (bool checkInf );
887
895
bool readValue ();
888
896
bool readObject (Token& token);
889
897
bool readArray (Token& token);
@@ -1029,6 +1037,24 @@ bool OurReader::readValue() {
1029
1037
currentValue ().swapPayload (v);
1030
1038
}
1031
1039
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 ;
1032
1058
case tokenArraySeparator:
1033
1059
case tokenObjectEnd:
1034
1060
case tokenArrayEnd:
@@ -1105,9 +1131,16 @@ bool OurReader::readToken(Token& token) {
1105
1131
case ' 7' :
1106
1132
case ' 8' :
1107
1133
case ' 9' :
1108
- case ' -' :
1109
1134
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
+ }
1111
1144
break ;
1112
1145
case ' t' :
1113
1146
token.type_ = tokenTrue;
@@ -1121,6 +1154,22 @@ bool OurReader::readToken(Token& token) {
1121
1154
token.type_ = tokenNull;
1122
1155
ok = match (" ull" , 3 );
1123
1156
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 ;
1124
1173
case ' ,' :
1125
1174
token.type_ = tokenArraySeparator;
1126
1175
break ;
@@ -1221,8 +1270,12 @@ bool OurReader::readCppStyleComment() {
1221
1270
return true ;
1222
1271
}
1223
1272
1224
- void OurReader::readNumber () {
1273
+ bool OurReader::readNumber (bool checkInf ) {
1225
1274
const char *p = current_;
1275
+ if (checkInf && p != end_ && *p == ' I' ) {
1276
+ current_ = ++p;
1277
+ return false ;
1278
+ }
1226
1279
char c = ' 0' ; // stopgap for already consumed character
1227
1280
// integral part
1228
1281
while (c >= ' 0' && c <= ' 9' )
@@ -1241,6 +1294,7 @@ void OurReader::readNumber() {
1241
1294
while (c >= ' 0' && c <= ' 9' )
1242
1295
c = (current_ = p) < end_ ? *p++ : 0 ;
1243
1296
}
1297
+ return true ;
1244
1298
}
1245
1299
bool OurReader::readString () {
1246
1300
Char c = 0 ;
@@ -1641,15 +1695,7 @@ std::string OurReader::getLocationLineAndColumn(Location location) const {
1641
1695
int line, column;
1642
1696
getLocationLineAndColumn (location, line, column);
1643
1697
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
1651
1698
snprintf (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
1652
- #endif
1653
1699
return buffer;
1654
1700
}
1655
1701
@@ -1709,6 +1755,7 @@ CharReader* CharReaderBuilder::newCharReader() const
1709
1755
features.stackLimit_ = settings_[" stackLimit" ].asInt ();
1710
1756
features.failIfExtra_ = settings_[" failIfExtra" ].asBool ();
1711
1757
features.rejectDupKeys_ = settings_[" rejectDupKeys" ].asBool ();
1758
+ features.allowSpecialFloats_ = settings_[" allowSpecialFloats" ].asBool ();
1712
1759
return new OurCharReader (collectComments, features);
1713
1760
}
1714
1761
static void getValidReaderKeys (std::set<std::string>* valid_keys)
@@ -1723,6 +1770,7 @@ static void getValidReaderKeys(std::set<std::string>* valid_keys)
1723
1770
valid_keys->insert (" stackLimit" );
1724
1771
valid_keys->insert (" failIfExtra" );
1725
1772
valid_keys->insert (" rejectDupKeys" );
1773
+ valid_keys->insert (" allowSpecialFloats" );
1726
1774
}
1727
1775
bool CharReaderBuilder::validate (Json::Value* invalid) const
1728
1776
{
@@ -1756,6 +1804,7 @@ void CharReaderBuilder::strictMode(Json::Value* settings)
1756
1804
(*settings)[" allowSingleQuotes" ] = false ;
1757
1805
(*settings)[" failIfExtra" ] = true ;
1758
1806
(*settings)[" rejectDupKeys" ] = true ;
1807
+ (*settings)[" allowSpecialFloats" ] = false ;
1759
1808
// ! [CharReaderBuilderStrictMode]
1760
1809
}
1761
1810
// static
@@ -1771,6 +1820,7 @@ void CharReaderBuilder::setDefaults(Json::Value* settings)
1771
1820
(*settings)[" stackLimit" ] = 1000 ;
1772
1821
(*settings)[" failIfExtra" ] = false ;
1773
1822
(*settings)[" rejectDupKeys" ] = false ;
1823
+ (*settings)[" allowSpecialFloats" ] = false ;
1774
1824
// ! [CharReaderBuilderDefaults]
1775
1825
}
1776
1826
0 commit comments