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 ();
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:
@@ -1215,8 +1247,12 @@ bool OurReader::readToken(Token& token) {
1215
1247
case ' 8' :
1216
1248
case ' 9' :
1217
1249
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
+ }
1220
1256
break ;
1221
1257
case ' t' :
1222
1258
token.type_ = tokenTrue;
@@ -1230,6 +1266,22 @@ bool OurReader::readToken(Token& token) {
1230
1266
token.type_ = tokenNull;
1231
1267
ok = match (" ull" , 3 );
1232
1268
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 ;
1233
1285
case ' ,' :
1234
1286
token.type_ = tokenArraySeparator;
1235
1287
break ;
@@ -1330,8 +1382,12 @@ bool OurReader::readCppStyleComment() {
1330
1382
return true ;
1331
1383
}
1332
1384
1333
- void OurReader::readNumber () {
1385
+ bool OurReader::readNumber () {
1334
1386
const char *p = current_;
1387
+ if (p != end_ && *p == ' I' ) {
1388
+ current_ = ++p;
1389
+ return false ;
1390
+ }
1335
1391
char c = ' 0' ; // stopgap for already consumed character
1336
1392
// integral part
1337
1393
while (c >= ' 0' && c <= ' 9' )
@@ -1350,6 +1406,7 @@ void OurReader::readNumber() {
1350
1406
while (c >= ' 0' && c <= ' 9' )
1351
1407
c = (current_ = p) < end_ ? *p++ : 0 ;
1352
1408
}
1409
+ return true ;
1353
1410
}
1354
1411
bool OurReader::readString () {
1355
1412
Char c = 0 ;
@@ -1758,15 +1815,7 @@ std::string OurReader::getLocationLineAndColumn(Location location) const {
1758
1815
int line, column;
1759
1816
getLocationLineAndColumn (location, line, column);
1760
1817
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
1818
snprintf (buffer, sizeof (buffer), " Line %d, Column %d" , line, column);
1769
- #endif
1770
1819
return buffer;
1771
1820
}
1772
1821
@@ -1880,6 +1929,7 @@ CharReader* CharReaderBuilder::newCharReader() const
1880
1929
features.stackLimit_ = settings_[" stackLimit" ].asInt ();
1881
1930
features.failIfExtra_ = settings_[" failIfExtra" ].asBool ();
1882
1931
features.rejectDupKeys_ = settings_[" rejectDupKeys" ].asBool ();
1932
+ features.allowSpecialFloats_ = settings_[" allowSpecialFloats" ].asBool ();
1883
1933
return new OurCharReader (collectComments, features);
1884
1934
}
1885
1935
static void getValidReaderKeys (std::set<std::string>* valid_keys)
@@ -1894,6 +1944,7 @@ static void getValidReaderKeys(std::set<std::string>* valid_keys)
1894
1944
valid_keys->insert (" stackLimit" );
1895
1945
valid_keys->insert (" failIfExtra" );
1896
1946
valid_keys->insert (" rejectDupKeys" );
1947
+ valid_keys->insert (" allowSpecialFloats" );
1897
1948
}
1898
1949
bool CharReaderBuilder::validate (Json::Value* invalid) const
1899
1950
{
@@ -1927,6 +1978,7 @@ void CharReaderBuilder::strictMode(Json::Value* settings)
1927
1978
(*settings)[" allowSingleQuotes" ] = false ;
1928
1979
(*settings)[" failIfExtra" ] = true ;
1929
1980
(*settings)[" rejectDupKeys" ] = true ;
1981
+ (*settings)[" allowSpecialFloats" ] = false ;
1930
1982
// ! [CharReaderBuilderStrictMode]
1931
1983
}
1932
1984
// static
@@ -1942,6 +1994,7 @@ void CharReaderBuilder::setDefaults(Json::Value* settings)
1942
1994
(*settings)[" stackLimit" ] = 1000 ;
1943
1995
(*settings)[" failIfExtra" ] = false ;
1944
1996
(*settings)[" rejectDupKeys" ] = false ;
1997
+ (*settings)[" allowSpecialFloats" ] = false ;
1945
1998
// ! [CharReaderBuilderDefaults]
1946
1999
}
1947
2000
0 commit comments