4
4
import java .util .concurrent .atomic .AtomicReference ;
5
5
6
6
import com .fasterxml .jackson .core .JsonFactory ;
7
+ import com .fasterxml .jackson .core .exc .StreamConstraintsException ;
7
8
import com .fasterxml .jackson .core .util .InternCache ;
8
9
9
10
/**
@@ -863,7 +864,13 @@ private boolean _verifyLongName2(int[] q, int qlen, int spillOffset)
863
864
/**********************************************************
864
865
*/
865
866
866
- public String addName (String name , int q1 ) {
867
+ /**
868
+ * @param name
869
+ * @param q1
870
+ * @return name (possibly interned)
871
+ * @throws StreamConstraintsException if the constraint exceptions
872
+ */
873
+ public String addName (String name , int q1 ) throws StreamConstraintsException {
867
874
_verifySharing ();
868
875
if (_intern ) {
869
876
name = InternCache .instance .intern (name );
@@ -876,7 +883,14 @@ public String addName(String name, int q1) {
876
883
return name ;
877
884
}
878
885
879
- public String addName (String name , int q1 , int q2 ) {
886
+ /**
887
+ * @param name
888
+ * @param q1
889
+ * @param q2
890
+ * @return name (possibly interned)
891
+ * @throws StreamConstraintsException if the constraint exceptions
892
+ */
893
+ public String addName (String name , int q1 , int q2 ) throws StreamConstraintsException {
880
894
_verifySharing ();
881
895
if (_intern ) {
882
896
name = InternCache .instance .intern (name );
@@ -896,7 +910,15 @@ public String addName(String name, int q1, int q2) {
896
910
return name ;
897
911
}
898
912
899
- public String addName (String name , int q1 , int q2 , int q3 ) {
913
+ /**
914
+ * @param name
915
+ * @param q1
916
+ * @param q2
917
+ * @param q3
918
+ * @return name (possibly interned)
919
+ * @throws StreamConstraintsException if the constraint exceptions
920
+ */
921
+ public String addName (String name , int q1 , int q2 , int q3 ) throws StreamConstraintsException {
900
922
_verifySharing ();
901
923
if (_intern ) {
902
924
name = InternCache .instance .intern (name );
@@ -911,7 +933,14 @@ public String addName(String name, int q1, int q2, int q3) {
911
933
return name ;
912
934
}
913
935
914
- public String addName (String name , int [] q , int qlen )
936
+ /**
937
+ * @param name
938
+ * @param q
939
+ * @param qlen
940
+ * @return name (possibly interned)
941
+ * @throws StreamConstraintsException if the constraint exceptions
942
+ */
943
+ public String addName (String name , int [] q , int qlen ) throws StreamConstraintsException
915
944
{
916
945
_verifySharing ();
917
946
if (_intern ) {
@@ -921,7 +950,7 @@ public String addName(String name, int[] q, int qlen)
921
950
922
951
switch (qlen ) {
923
952
case 1 :
924
- {
953
+ {
925
954
offset = _findOffsetForAdd (calcHash (q [0 ]));
926
955
_hashArea [offset ] = q [0 ];
927
956
_hashArea [offset +3 ] = 1 ;
@@ -961,16 +990,16 @@ public String addName(String name, int[] q, int qlen)
961
990
return name ;
962
991
}
963
992
964
- private void _verifySharing ()
993
+ private void _verifySharing () throws StreamConstraintsException
965
994
{
966
995
if (_hashShared ) {
967
996
// 12-Mar-2021, tatu: prevent modifying of "placeholder" and
968
997
// parent tables
969
998
if (_parent == null ) {
970
999
if (_count == 0 ) { // root
971
- throw new IllegalStateException ("Cannot add names to Root symbol table" );
1000
+ throw new StreamConstraintsException ("Cannot add names to Root symbol table" );
972
1001
}
973
- throw new IllegalStateException ("Cannot add names to Placeholder symbol table" );
1002
+ throw new StreamConstraintsException ("Cannot add names to Placeholder symbol table" );
974
1003
}
975
1004
976
1005
_hashArea = Arrays .copyOf (_hashArea , _hashArea .length );
@@ -982,7 +1011,7 @@ private void _verifySharing()
982
1011
/**
983
1012
* Method called to find the location within hash table to add a new symbol in.
984
1013
*/
985
- private int _findOffsetForAdd (int hash )
1014
+ private int _findOffsetForAdd (int hash ) throws StreamConstraintsException
986
1015
{
987
1016
// first, check the primary: if slot found, no need for resize
988
1017
int offset = _calcOffset (hash );
@@ -1037,7 +1066,7 @@ private int _findOffsetForAdd(int hash)
1037
1066
}
1038
1067
1039
1068
// @since 2.10
1040
- private int _resizeAndFindOffsetForAdd (int hash )
1069
+ private int _resizeAndFindOffsetForAdd (int hash ) throws StreamConstraintsException
1041
1070
{
1042
1071
// First things first: we need to resize+rehash (or, if too big, nuke contents)
1043
1072
rehash ();
@@ -1165,10 +1194,16 @@ public int calcHash(int q1, int q2, int q3)
1165
1194
return hash ;
1166
1195
}
1167
1196
1197
+ /**
1198
+ * @param q int array
1199
+ * @param qlen length
1200
+ * @return hash
1201
+ * @throws IllegalArgumentException if <code>qlen</code> is less than 4
1202
+ */
1168
1203
public int calcHash (int [] q , int qlen )
1169
1204
{
1170
1205
if (qlen < 4 ) {
1171
- throw new IllegalArgumentException ();
1206
+ throw new IllegalArgumentException ("qlen is too short, needs to be at least 4" );
1172
1207
}
1173
1208
/* And then change handling again for "multi-quad" case; mostly
1174
1209
* to make calculation of collisions less fun. For example,
@@ -1202,7 +1237,7 @@ public int calcHash(int[] q, int qlen)
1202
1237
/**********************************************************
1203
1238
*/
1204
1239
1205
- private void rehash ()
1240
+ private void rehash () throws StreamConstraintsException
1206
1241
{
1207
1242
// Note: since we'll make copies, no need to unshare, can just mark as such:
1208
1243
_hashShared = false ;
@@ -1279,7 +1314,7 @@ private void rehash()
1279
1314
// Sanity checks: since corruption difficult to detect, assert explicitly
1280
1315
// with production code
1281
1316
if (copyCount != oldCount ) {
1282
- throw new IllegalStateException ("Failed rehash(): old count=" +oldCount +", copyCount=" +copyCount );
1317
+ throw new StreamConstraintsException ("Failed rehash(): old count=" +oldCount +", copyCount=" +copyCount );
1283
1318
}
1284
1319
}
1285
1320
@@ -1315,13 +1350,13 @@ private final int _spilloverStart() {
1315
1350
return (offset << 3 ) - offset ;
1316
1351
}
1317
1352
1318
- protected void _reportTooManyCollisions ()
1353
+ protected void _reportTooManyCollisions () throws StreamConstraintsException
1319
1354
{
1320
1355
// First: do not fuzz about small symbol tables; may get balanced by doubling up
1321
1356
if (_hashSize <= 1024 ) { // would have spill-over area of 128 entries
1322
1357
return ;
1323
1358
}
1324
- throw new IllegalStateException ("Spill-over slots in symbol table with " +_count
1359
+ throw new StreamConstraintsException ("Spill-over slots in symbol table with " +_count
1325
1360
+" entries, hash area of " +_hashSize +" slots is now full (all "
1326
1361
+(_hashSize >> 3 )+" slots -- suspect a DoS attack based on hash collisions."
1327
1362
+" You can disable the check via `JsonFactory.Feature.FAIL_ON_SYMBOL_HASH_OVERFLOW`" );
0 commit comments