Skip to content

Commit 25313f1

Browse files
authored
Use StreamConstraintsException exception in canonicalizer (#948)
1 parent 7fe79e9 commit 25313f1

File tree

8 files changed

+107
-62
lines changed

8 files changed

+107
-62
lines changed

src/main/java/com/fasterxml/jackson/core/json/UTF8DataInputJsonParser.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import com.fasterxml.jackson.core.*;
77
import com.fasterxml.jackson.core.base.ParserBase;
8+
import com.fasterxml.jackson.core.exc.StreamConstraintsException;
89
import com.fasterxml.jackson.core.io.CharTypes;
910
import com.fasterxml.jackson.core.io.IOContext;
1011
import com.fasterxml.jackson.core.sym.ByteQuadsCanonicalizer;
@@ -38,8 +39,6 @@
3839
public class UTF8DataInputJsonParser
3940
extends ParserBase
4041
{
41-
final static byte BYTE_LF = (byte) '\n';
42-
4342
@SuppressWarnings("deprecation")
4443
private final static int FEAT_MASK_TRAILING_COMMA = Feature.ALLOW_TRAILING_COMMA.getMask();
4544
@SuppressWarnings("deprecation")
@@ -1768,7 +1767,8 @@ protected String _parseAposName() throws IOException
17681767
/**********************************************************
17691768
*/
17701769

1771-
private final String findName(int q1, int lastQuadBytes) throws JsonParseException
1770+
private final String findName(int q1, int lastQuadBytes)
1771+
throws JsonParseException, StreamConstraintsException
17721772
{
17731773
q1 = pad(q1, lastQuadBytes);
17741774
// Usually we'll find it from the canonical symbol table already
@@ -1781,7 +1781,8 @@ private final String findName(int q1, int lastQuadBytes) throws JsonParseExcepti
17811781
return addName(_quadBuffer, 1, lastQuadBytes);
17821782
}
17831783

1784-
private final String findName(int q1, int q2, int lastQuadBytes) throws JsonParseException
1784+
private final String findName(int q1, int q2, int lastQuadBytes)
1785+
throws JsonParseException, StreamConstraintsException
17851786
{
17861787
q2 = pad(q2, lastQuadBytes);
17871788
// Usually we'll find it from the canonical symbol table already
@@ -1795,7 +1796,8 @@ private final String findName(int q1, int q2, int lastQuadBytes) throws JsonPars
17951796
return addName(_quadBuffer, 2, lastQuadBytes);
17961797
}
17971798

1798-
private final String findName(int q1, int q2, int q3, int lastQuadBytes) throws JsonParseException
1799+
private final String findName(int q1, int q2, int q3, int lastQuadBytes)
1800+
throws JsonParseException, StreamConstraintsException
17991801
{
18001802
q3 = pad(q3, lastQuadBytes);
18011803
String name = _symbols.findName(q1, q2, q3);
@@ -1809,7 +1811,8 @@ private final String findName(int q1, int q2, int q3, int lastQuadBytes) throws
18091811
return addName(quads, 3, lastQuadBytes);
18101812
}
18111813

1812-
private final String findName(int[] quads, int qlen, int lastQuad, int lastQuadBytes) throws JsonParseException
1814+
private final String findName(int[] quads, int qlen, int lastQuad, int lastQuadBytes)
1815+
throws JsonParseException, StreamConstraintsException
18131816
{
18141817
if (qlen >= quads.length) {
18151818
_quadBuffer = quads = _growArrayBy(quads, quads.length);
@@ -1828,7 +1831,8 @@ private final String findName(int[] quads, int qlen, int lastQuad, int lastQuadB
18281831
* multi-byte chars (if any), and then construct Name instance
18291832
* and add it to the symbol table.
18301833
*/
1831-
private final String addName(int[] quads, int qlen, int lastQuadBytes) throws JsonParseException
1834+
private final String addName(int[] quads, int qlen, int lastQuadBytes)
1835+
throws JsonParseException, StreamConstraintsException
18321836
{
18331837
/* Ok: must decode UTF-8 chars. No other validation is
18341838
* needed, since unescaping has been done earlier as necessary

src/main/java/com/fasterxml/jackson/core/json/UTF8StreamJsonParser.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import com.fasterxml.jackson.core.*;
66
import com.fasterxml.jackson.core.base.ParserBase;
7+
import com.fasterxml.jackson.core.exc.StreamConstraintsException;
78
import com.fasterxml.jackson.core.io.CharTypes;
89
import com.fasterxml.jackson.core.io.IOContext;
910
import com.fasterxml.jackson.core.sym.ByteQuadsCanonicalizer;
@@ -2309,7 +2310,8 @@ protected String _parseAposName() throws IOException
23092310
/**********************************************************
23102311
*/
23112312

2312-
private final String findName(int q1, int lastQuadBytes) throws JsonParseException
2313+
private final String findName(int q1, int lastQuadBytes)
2314+
throws JsonParseException, StreamConstraintsException
23132315
{
23142316
q1 = _padLastQuad(q1, lastQuadBytes);
23152317
// Usually we'll find it from the canonical symbol table already
@@ -2322,7 +2324,8 @@ private final String findName(int q1, int lastQuadBytes) throws JsonParseExcepti
23222324
return addName(_quadBuffer, 1, lastQuadBytes);
23232325
}
23242326

2325-
private final String findName(int q1, int q2, int lastQuadBytes) throws JsonParseException
2327+
private final String findName(int q1, int q2, int lastQuadBytes)
2328+
throws JsonParseException, StreamConstraintsException
23262329
{
23272330
q2 = _padLastQuad(q2, lastQuadBytes);
23282331
// Usually we'll find it from the canonical symbol table already
@@ -2336,7 +2339,8 @@ private final String findName(int q1, int q2, int lastQuadBytes) throws JsonPars
23362339
return addName(_quadBuffer, 2, lastQuadBytes);
23372340
}
23382341

2339-
private final String findName(int q1, int q2, int q3, int lastQuadBytes) throws JsonParseException
2342+
private final String findName(int q1, int q2, int q3, int lastQuadBytes)
2343+
throws JsonParseException, StreamConstraintsException
23402344
{
23412345
q3 = _padLastQuad(q3, lastQuadBytes);
23422346
String name = _symbols.findName(q1, q2, q3);
@@ -2350,7 +2354,8 @@ private final String findName(int q1, int q2, int q3, int lastQuadBytes) throws
23502354
return addName(quads, 3, lastQuadBytes);
23512355
}
23522356

2353-
private final String findName(int[] quads, int qlen, int lastQuad, int lastQuadBytes) throws JsonParseException
2357+
private final String findName(int[] quads, int qlen, int lastQuad, int lastQuadBytes)
2358+
throws JsonParseException, StreamConstraintsException
23542359
{
23552360
if (qlen >= quads.length) {
23562361
_quadBuffer = quads = growArrayBy(quads, quads.length);
@@ -2368,7 +2373,8 @@ private final String findName(int[] quads, int qlen, int lastQuad, int lastQuadB
23682373
* multi-byte chars (if any), and then construct Name instance
23692374
* and add it to the symbol table.
23702375
*/
2371-
private final String addName(int[] quads, int qlen, int lastQuadBytes) throws JsonParseException
2376+
private final String addName(int[] quads, int qlen, int lastQuadBytes)
2377+
throws JsonParseException, StreamConstraintsException
23722378
{
23732379
/* Ok: must decode UTF-8 chars. No other validation is
23742380
* needed, since unescaping has been done earlier as necessary

src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingJsonParserBase.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import com.fasterxml.jackson.core.*;
66
import com.fasterxml.jackson.core.base.ParserBase;
7+
import com.fasterxml.jackson.core.exc.StreamConstraintsException;
78
import com.fasterxml.jackson.core.io.IOContext;
89
import com.fasterxml.jackson.core.json.JsonReadContext;
910
import com.fasterxml.jackson.core.sym.ByteQuadsCanonicalizer;
@@ -639,7 +640,8 @@ protected final JsonToken _closeObjectScope() throws IOException
639640
/**********************************************************
640641
*/
641642

642-
protected final String _findName(int q1, int lastQuadBytes) throws JsonParseException
643+
protected final String _findName(int q1, int lastQuadBytes)
644+
throws JsonParseException, StreamConstraintsException
643645
{
644646
q1 = _padLastQuad(q1, lastQuadBytes);
645647
// Usually we'll find it from the canonical symbol table already
@@ -652,7 +654,8 @@ protected final String _findName(int q1, int lastQuadBytes) throws JsonParseExce
652654
return _addName(_quadBuffer, 1, lastQuadBytes);
653655
}
654656

655-
protected final String _findName(int q1, int q2, int lastQuadBytes) throws JsonParseException
657+
protected final String _findName(int q1, int q2, int lastQuadBytes)
658+
throws JsonParseException, StreamConstraintsException
656659
{
657660
q2 = _padLastQuad(q2, lastQuadBytes);
658661
// Usually we'll find it from the canonical symbol table already
@@ -666,7 +669,8 @@ protected final String _findName(int q1, int q2, int lastQuadBytes) throws JsonP
666669
return _addName(_quadBuffer, 2, lastQuadBytes);
667670
}
668671

669-
protected final String _findName(int q1, int q2, int q3, int lastQuadBytes) throws JsonParseException
672+
protected final String _findName(int q1, int q2, int q3, int lastQuadBytes)
673+
throws JsonParseException, StreamConstraintsException
670674
{
671675
q3 = _padLastQuad(q3, lastQuadBytes);
672676
String name = _symbols.findName(q1, q2, q3);
@@ -684,10 +688,11 @@ protected final String _findName(int q1, int q2, int q3, int lastQuadBytes) thro
684688
// table miss. It needs to demultiplex individual bytes, decode
685689
// multi-byte chars (if any), and then construct Name instance
686690
// and add it to the symbol table.
687-
protected final String _addName(int[] quads, int qlen, int lastQuadBytes) throws JsonParseException
691+
protected final String _addName(int[] quads, int qlen, int lastQuadBytes)
692+
throws JsonParseException, StreamConstraintsException
688693
{
689694
/* Ok: must decode UTF-8 chars. No other validation is
690-
* needed, since unescaping has been done earlier as necessary
695+
* needed, since unescaping has been done earlier, as necessary
691696
* (as well as error reporting for unescaped control chars)
692697
*/
693698
// 4 bytes per quad, except last one maybe less

src/main/java/com/fasterxml/jackson/core/sym/ByteQuadsCanonicalizer.java

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.concurrent.atomic.AtomicReference;
55

66
import com.fasterxml.jackson.core.JsonFactory;
7+
import com.fasterxml.jackson.core.exc.StreamConstraintsException;
78
import com.fasterxml.jackson.core.util.InternCache;
89

910
/**
@@ -863,7 +864,13 @@ private boolean _verifyLongName2(int[] q, int qlen, int spillOffset)
863864
/**********************************************************
864865
*/
865866

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 {
867874
_verifySharing();
868875
if (_intern) {
869876
name = InternCache.instance.intern(name);
@@ -876,7 +883,14 @@ public String addName(String name, int q1) {
876883
return name;
877884
}
878885

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 {
880894
_verifySharing();
881895
if (_intern) {
882896
name = InternCache.instance.intern(name);
@@ -896,7 +910,15 @@ public String addName(String name, int q1, int q2) {
896910
return name;
897911
}
898912

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 {
900922
_verifySharing();
901923
if (_intern) {
902924
name = InternCache.instance.intern(name);
@@ -911,7 +933,14 @@ public String addName(String name, int q1, int q2, int q3) {
911933
return name;
912934
}
913935

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
915944
{
916945
_verifySharing();
917946
if (_intern) {
@@ -921,7 +950,7 @@ public String addName(String name, int[] q, int qlen)
921950

922951
switch (qlen) {
923952
case 1:
924-
{
953+
{
925954
offset = _findOffsetForAdd(calcHash(q[0]));
926955
_hashArea[offset] = q[0];
927956
_hashArea[offset+3] = 1;
@@ -961,16 +990,16 @@ public String addName(String name, int[] q, int qlen)
961990
return name;
962991
}
963992

964-
private void _verifySharing()
993+
private void _verifySharing() throws StreamConstraintsException
965994
{
966995
if (_hashShared) {
967996
// 12-Mar-2021, tatu: prevent modifying of "placeholder" and
968997
// parent tables
969998
if (_parent == null) {
970999
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");
9721001
}
973-
throw new IllegalStateException("Cannot add names to Placeholder symbol table");
1002+
throw new StreamConstraintsException("Cannot add names to Placeholder symbol table");
9741003
}
9751004

9761005
_hashArea = Arrays.copyOf(_hashArea, _hashArea.length);
@@ -982,7 +1011,7 @@ private void _verifySharing()
9821011
/**
9831012
* Method called to find the location within hash table to add a new symbol in.
9841013
*/
985-
private int _findOffsetForAdd(int hash)
1014+
private int _findOffsetForAdd(int hash) throws StreamConstraintsException
9861015
{
9871016
// first, check the primary: if slot found, no need for resize
9881017
int offset = _calcOffset(hash);
@@ -1037,7 +1066,7 @@ private int _findOffsetForAdd(int hash)
10371066
}
10381067

10391068
// @since 2.10
1040-
private int _resizeAndFindOffsetForAdd(int hash)
1069+
private int _resizeAndFindOffsetForAdd(int hash) throws StreamConstraintsException
10411070
{
10421071
// First things first: we need to resize+rehash (or, if too big, nuke contents)
10431072
rehash();
@@ -1165,10 +1194,16 @@ public int calcHash(int q1, int q2, int q3)
11651194
return hash;
11661195
}
11671196

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+
*/
11681203
public int calcHash(int[] q, int qlen)
11691204
{
11701205
if (qlen < 4) {
1171-
throw new IllegalArgumentException();
1206+
throw new IllegalArgumentException("qlen is too short, needs to be at least 4");
11721207
}
11731208
/* And then change handling again for "multi-quad" case; mostly
11741209
* to make calculation of collisions less fun. For example,
@@ -1202,7 +1237,7 @@ public int calcHash(int[] q, int qlen)
12021237
/**********************************************************
12031238
*/
12041239

1205-
private void rehash()
1240+
private void rehash() throws StreamConstraintsException
12061241
{
12071242
// Note: since we'll make copies, no need to unshare, can just mark as such:
12081243
_hashShared = false;
@@ -1279,7 +1314,7 @@ private void rehash()
12791314
// Sanity checks: since corruption difficult to detect, assert explicitly
12801315
// with production code
12811316
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);
12831318
}
12841319
}
12851320

@@ -1315,13 +1350,13 @@ private final int _spilloverStart() {
13151350
return (offset << 3) - offset;
13161351
}
13171352

1318-
protected void _reportTooManyCollisions()
1353+
protected void _reportTooManyCollisions() throws StreamConstraintsException
13191354
{
13201355
// First: do not fuzz about small symbol tables; may get balanced by doubling up
13211356
if (_hashSize <= 1024) { // would have spill-over area of 128 entries
13221357
return;
13231358
}
1324-
throw new IllegalStateException("Spill-over slots in symbol table with "+_count
1359+
throw new StreamConstraintsException("Spill-over slots in symbol table with "+_count
13251360
+" entries, hash area of "+_hashSize+" slots is now full (all "
13261361
+(_hashSize >> 3)+" slots -- suspect a DoS attack based on hash collisions."
13271362
+" You can disable the check via `JsonFactory.Feature.FAIL_ON_SYMBOL_HASH_OVERFLOW`");

0 commit comments

Comments
 (0)