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.
@@ -795,15 +806,7 @@ std::string Reader::getLocationLineAndColumn(Location location) const {
795
806
int line, column;
796
807
getLocationLineAndColumn (location, line, column);
797
808
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
805
809
snprintf (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
806
- #endif
807
810
return buffer;
808
811
}
809
812
@@ -894,6 +897,7 @@ class OurFeatures {
894
897
bool allowSingleQuotes_;
895
898
bool failIfExtra_;
896
899
bool rejectDupKeys_;
900
+ bool allowSpecialFloats_;
897
901
int stackLimit_;
898
902
}; // OurFeatures
899
903
@@ -905,6 +909,7 @@ OurFeatures::OurFeatures()
905
909
, allowDroppedNullPlaceholders_(false ), allowNumericKeys_(false )
906
910
, allowSingleQuotes_(false )
907
911
, failIfExtra_(false )
912
+ , allowSpecialFloats_(false )
908
913
{
909
914
}
910
915
@@ -950,6 +955,9 @@ class OurReader {
950
955
tokenTrue,
951
956
tokenFalse,
952
957
tokenNull,
958
+ tokenNaN,
959
+ tokenPosInf,
960
+ tokenNegInf,
953
961
tokenArraySeparator,
954
962
tokenMemberSeparator,
955
963
tokenComment,
@@ -980,7 +988,7 @@ class OurReader {
980
988
bool readCppStyleComment ();
981
989
bool readString ();
982
990
bool readStringSingleQuote ();
983
- void readNumber ();
991
+ bool readNumber (bool checkInf );
984
992
bool readValue ();
985
993
bool readObject (Token& token);
986
994
bool readArray (Token& token);
@@ -1134,6 +1142,30 @@ bool OurReader::readValue() {
1134
1142
currentValue ().setOffsetLimit (token.end_ - begin_);
1135
1143
}
1136
1144
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 ;
1137
1169
case tokenArraySeparator:
1138
1170
case tokenObjectEnd:
1139
1171
case tokenArrayEnd:
@@ -1214,9 +1246,16 @@ bool OurReader::readToken(Token& token) {
1214
1246
case ' 7' :
1215
1247
case ' 8' :
1216
1248
case ' 9' :
1217
- case ' -' :
1218
1249
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
+ }
1220
1259
break ;
1221
1260
case ' t' :
1222
1261
token.type_ = tokenTrue;
@@ -1230,6 +1269,22 @@ bool OurReader::readToken(Token& token) {
1230
1269
token.type_ = tokenNull;
1231
1270
ok = match (" ull" , 3 );
1232
1271
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 ;
1233
1288
case ' ,' :
1234
1289
token.type_ = tokenArraySeparator;
1235
1290
break ;
@@ -1330,8 +1385,12 @@ bool OurReader::readCppStyleComment() {
1330
1385
return true ;
1331
1386
}
1332
1387
1333
- void OurReader::readNumber () {
1388
+ bool OurReader::readNumber (bool checkInf ) {
1334
1389
const char *p = current_;
1390
+ if (checkInf && p != end_ && *p == ' I' ) {
1391
+ current_ = ++p;
1392
+ return false ;
1393
+ }
1335
1394
char c = ' 0' ; // stopgap for already consumed character
1336
1395
// integral part
1337
1396
while (c >= ' 0' && c <= ' 9' )
@@ -1350,6 +1409,7 @@ void OurReader::readNumber() {
1350
1409
while (c >= ' 0' && c <= ' 9' )
1351
1410
c = (current_ = p) < end_ ? *p++ : 0 ;
1352
1411
}
1412
+ return true ;
1353
1413
}
1354
1414
bool OurReader::readString () {
1355
1415
Char c = 0 ;
@@ -1758,15 +1818,7 @@ std::string OurReader::getLocationLineAndColumn(Location location) const {
1758
1818
int line, column;
1759
1819
getLocationLineAndColumn (location, line, column);
1760
1820
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
1768
1821
snprintf (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
1769
- #endif
1770
1822
return buffer;
1771
1823
}
1772
1824
@@ -1880,6 +1932,7 @@ CharReader* CharReaderBuilder::newCharReader() const
1880
1932
features.stackLimit_ = settings_[" stackLimit" ].asInt ();
1881
1933
features.failIfExtra_ = settings_[" failIfExtra" ].asBool ();
1882
1934
features.rejectDupKeys_ = settings_[" rejectDupKeys" ].asBool ();
1935
+ features.allowSpecialFloats_ = settings_[" allowSpecialFloats" ].asBool ();
1883
1936
return new OurCharReader (collectComments, features);
1884
1937
}
1885
1938
static void getValidReaderKeys (std::set<std::string>* valid_keys)
@@ -1894,6 +1947,7 @@ static void getValidReaderKeys(std::set<std::string>* valid_keys)
1894
1947
valid_keys->insert (" stackLimit" );
1895
1948
valid_keys->insert (" failIfExtra" );
1896
1949
valid_keys->insert (" rejectDupKeys" );
1950
+ valid_keys->insert (" allowSpecialFloats" );
1897
1951
}
1898
1952
bool CharReaderBuilder::validate (Json::Value* invalid) const
1899
1953
{
@@ -1927,6 +1981,7 @@ void CharReaderBuilder::strictMode(Json::Value* settings)
1927
1981
(*settings)[" allowSingleQuotes" ] = false ;
1928
1982
(*settings)[" failIfExtra" ] = true ;
1929
1983
(*settings)[" rejectDupKeys" ] = true ;
1984
+ (*settings)[" allowSpecialFloats" ] = false ;
1930
1985
// ! [CharReaderBuilderStrictMode]
1931
1986
}
1932
1987
// static
@@ -1942,6 +1997,7 @@ void CharReaderBuilder::setDefaults(Json::Value* settings)
1942
1997
(*settings)[" stackLimit" ] = 1000 ;
1943
1998
(*settings)[" failIfExtra" ] = false ;
1944
1999
(*settings)[" rejectDupKeys" ] = false ;
2000
+ (*settings)[" allowSpecialFloats" ] = false ;
1945
2001
// ! [CharReaderBuilderDefaults]
1946
2002
}
1947
2003
0 commit comments