@@ -875,6 +875,7 @@ class OurFeatures {
875
875
bool failIfExtra_;
876
876
bool rejectDupKeys_;
877
877
bool allowSpecialFloats_;
878
+ bool allowHexadecimal_;
878
879
bool skipBom_;
879
880
size_t stackLimit_;
880
881
}; // OurFeatures
@@ -914,6 +915,7 @@ class OurReader {
914
915
tokenArrayEnd,
915
916
tokenString,
916
917
tokenNumber,
918
+ tokenHexadecimal,
917
919
tokenTrue,
918
920
tokenFalse,
919
921
tokenNull,
@@ -952,11 +954,14 @@ class OurReader {
952
954
bool readString ();
953
955
bool readStringSingleQuote ();
954
956
bool readNumber (bool checkInf);
957
+ bool readHexadecimal ();
955
958
bool readValue ();
956
959
bool readObject (Token& token);
957
960
bool readArray (Token& token);
958
961
bool decodeNumber (Token& token);
959
962
bool decodeNumber (Token& token, Value& decoded);
963
+ bool decodeHexadecimal (Token& token);
964
+ bool decodeHexadecimal (Token& token, Value& decoded);
960
965
bool decodeString (Token& token);
961
966
bool decodeString (Token& token, String& decoded);
962
967
bool decodeDouble (Token& token);
@@ -1191,6 +1196,12 @@ bool OurReader::readToken(Token& token) {
1191
1196
ok = readComment ();
1192
1197
break ;
1193
1198
case ' 0' :
1199
+ if (match (" x" , 1 )) {
1200
+ token.type_ = tokenHexadecimal;
1201
+ ok = features_.allowHexadecimal_ ;
1202
+ readHexadecimal ();
1203
+ break ;
1204
+ }
1194
1205
case ' 1' :
1195
1206
case ' 2' :
1196
1207
case ' 3' :
@@ -1419,6 +1430,18 @@ bool OurReader::readNumber(bool checkInf) {
1419
1430
}
1420
1431
return true ;
1421
1432
}
1433
+
1434
+ bool OurReader::readHexadecimal (void ) {
1435
+ Location p = current_;
1436
+ char c = ' 0' ; // stopgap for already consumed character
1437
+ // integral part
1438
+ while ((c >= ' 0' && c <= ' 9' )
1439
+ || (c >= ' a' && c <= ' f' )
1440
+ || (c >= ' A' && c <= ' F' ))
1441
+ c = (current_ = p) < end_ ? *p++ : ' \0 ' ;
1442
+ return true ;
1443
+ }
1444
+
1422
1445
bool OurReader::readString () {
1423
1446
Char c = 0 ;
1424
1447
while (current_ != end_) {
@@ -1639,6 +1662,44 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) {
1639
1662
return true ;
1640
1663
}
1641
1664
1665
+ bool OurReader::decodeHexadecimal (Token& token) {
1666
+ Value decoded;
1667
+ if (!decodeHexadecimal (token, decoded))
1668
+ return false ;
1669
+ currentValue ().swapPayload (decoded);
1670
+ currentValue ().setOffsetStart (token.start_ - begin_);
1671
+ currentValue ().setOffsetLimit (token.end_ - begin_);
1672
+ return true ;
1673
+ }
1674
+
1675
+ bool OurReader::decodeHexadecimal (Token& token, Value& decoded) {
1676
+ Json::LargestUInt value = 0 ;
1677
+ constexpr Json::LargestUInt top =
1678
+ Json::LargestUInt (0xF ) << (sizeof (top) * 8 ) - 4 ;
1679
+
1680
+ Location current = token.start_ ;
1681
+ while (current < token.end_ ) {
1682
+ Char c = *current++;
1683
+ static_assert (' A' < ' a' );
1684
+ static_assert (' 0' < ' A' );
1685
+ if (c == ' x' )
1686
+ continue ;
1687
+ else if (c >= ' a' )
1688
+ c -= ' a' - 10 ;
1689
+ else if (c >= ' A' )
1690
+ c -= ' A' - 10 ;
1691
+ else if (c >= ' 0' )
1692
+ c -= ' 0' ;
1693
+ else return addError (
1694
+ " Contains non-hexadecimal digits." , token, current);
1695
+ if (value & top) return addError (
1696
+ " Number is too large for unsigned integer." , token, current);
1697
+ value = value << 4 | static_cast <Value::UInt>(c);
1698
+ }
1699
+ decoded = value;
1700
+ return true ;
1701
+ }
1702
+
1642
1703
bool OurReader::decodeDouble (Token& token) {
1643
1704
Value decoded;
1644
1705
if (!decodeDouble (token, decoded))
@@ -1908,6 +1969,7 @@ CharReader* CharReaderBuilder::newCharReader() const {
1908
1969
features.failIfExtra_ = settings_[" failIfExtra" ].asBool ();
1909
1970
features.rejectDupKeys_ = settings_[" rejectDupKeys" ].asBool ();
1910
1971
features.allowSpecialFloats_ = settings_[" allowSpecialFloats" ].asBool ();
1972
+ features.allowHexadecimal_ = settings_[" allowHexacecimal" ].asBool ();
1911
1973
features.skipBom_ = settings_[" skipBom" ].asBool ();
1912
1974
return new OurCharReader (collectComments, features);
1913
1975
}
@@ -1925,6 +1987,7 @@ bool CharReaderBuilder::validate(Json::Value* invalid) const {
1925
1987
" failIfExtra" ,
1926
1988
" rejectDupKeys" ,
1927
1989
" allowSpecialFloats" ,
1990
+ " allowHexacecimal" ,
1928
1991
" skipBom" ,
1929
1992
};
1930
1993
for (auto si = settings_.begin (); si != settings_.end (); ++si) {
0 commit comments