Skip to content

Commit ae170b2

Browse files
committed
Minor cleanup/unification post #386
1 parent cdd70bb commit ae170b2

File tree

13 files changed

+187
-135
lines changed

13 files changed

+187
-135
lines changed

avro/src/main/java/com/fasterxml/jackson/dataformat/avro/AvroGenerator.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,13 @@ private Feature(boolean defaultState) {
8888
/**********************************************************
8989
*/
9090

91-
final protected IOContext _ioContext;
91+
protected final IOContext _ioContext;
9292

93+
/**
94+
* @since 2.16
95+
*/
96+
protected final StreamWriteConstraints _streamWriteConstraints;
97+
9398
/**
9499
* Bit flag composed of bits that indicate which
95100
* {@link AvroGenerator.Feature}s
@@ -140,6 +145,7 @@ public AvroGenerator(IOContext ctxt, int jsonFeatures, int avroFeatures,
140145
{
141146
super(jsonFeatures, codec);
142147
_ioContext = ctxt;
148+
_streamWriteConstraints = ctxt.streamWriteConstraints();
143149
_formatFeatures = avroFeatures;
144150
_output = output;
145151
_avroContext = AvroWriteContext.nullContext();
@@ -159,7 +165,7 @@ public void setSchema(AvroSchema schema)
159165

160166
@Override
161167
public StreamWriteConstraints streamWriteConstraints() {
162-
return _ioContext.streamWriteConstraints();
168+
return _streamWriteConstraints;
163169
}
164170

165171
/*
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.fasterxml.jackson.dataformat.avro.dos;
2+
3+
import com.fasterxml.jackson.core.StreamReadConstraints;
4+
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
5+
import com.fasterxml.jackson.dataformat.avro.AvroFactory;
6+
import com.fasterxml.jackson.dataformat.avro.AvroMapper;
7+
import com.fasterxml.jackson.dataformat.avro.AvroSchema;
8+
import com.fasterxml.jackson.dataformat.avro.AvroTestBase;
9+
10+
/**
11+
* Simple unit tests to verify that we fail gracefully if you attempt to serialize
12+
* data that is cyclic (eg a list that contains itself).
13+
*/
14+
public class CyclicAvroDataSerTest extends AvroTestBase
15+
{
16+
17+
public static class Bean
18+
{
19+
Bean _next;
20+
final String _name;
21+
22+
public Bean(Bean next, String name) {
23+
_next = next;
24+
_name = name;
25+
}
26+
27+
public Bean getNext() { return _next; }
28+
public String getName() { return _name; }
29+
30+
public void assignNext(Bean n) { _next = n; }
31+
}
32+
33+
private final AvroMapper MAPPER = getMapper();
34+
35+
// Unlike default depth of 1000 for other formats, use lower (400) here
36+
// because we cannot actually generate 1000 levels due to Avro codec's
37+
// limitations
38+
private final AvroMapper MAPPER_400;
39+
{
40+
AvroFactory f = AvroFactory.builder()
41+
.streamReadConstraints(StreamReadConstraints.builder().maxNestingDepth(400).build())
42+
.build();
43+
MAPPER_400 = new AvroMapper(f);
44+
}
45+
46+
public void testDirectCyclic() throws Exception {
47+
Bean bean = new Bean(null, "123");
48+
bean.assignNext(bean);
49+
try {
50+
AvroSchema schema = MAPPER.schemaFor(Bean.class);
51+
MAPPER.writer(schema).writeValueAsBytes(bean);
52+
fail("expected InvalidDefinitionException");
53+
} catch (InvalidDefinitionException idex) {
54+
assertTrue("InvalidDefinitionException message is as expected?",
55+
idex.getMessage().startsWith("Direct self-reference leading to cycle"));
56+
}
57+
}
58+
59+
// With 2.16 also test looser loops, wrt new limits
60+
public void testLooserCyclic() throws Exception
61+
{
62+
Bean beanRoot = new Bean(null, "123");
63+
Bean bean2 = new Bean(beanRoot, "456");
64+
beanRoot.assignNext(bean2);
65+
66+
// 12-Jul-2023, tatu: Alas, won't work -- Avro serialization by-passes many
67+
// checks. Needs more work in future
68+
69+
if (false) {
70+
try {
71+
AvroSchema schema = MAPPER_400.schemaFor(Bean.class);
72+
MAPPER_400.writer(schema).writeValueAsBytes(beanRoot);
73+
fail("expected InvalidDefinitionException");
74+
} catch (InvalidDefinitionException idex) {
75+
assertTrue("InvalidDefinitionException message is as expected?",
76+
idex.getMessage().startsWith("Direct self-reference leading to cycle"));
77+
}
78+
}
79+
}
80+
}

avro/src/test/java/com/fasterxml/jackson/dataformat/avro/dos/CyclicDataSerTest.java

Lines changed: 0 additions & 46 deletions
This file was deleted.

cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORGenerator.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,14 @@ public int getMask() {
178178
/**********************************************************
179179
*/
180180

181-
final protected IOContext _ioContext;
181+
protected final IOContext _ioContext;
182182

183-
final protected OutputStream _out;
183+
/**
184+
* @since 2.16
185+
*/
186+
protected final StreamWriteConstraints _streamWriteConstraints;
187+
188+
protected final OutputStream _out;
184189

185190
/**
186191
* Bit flag composed of bits that indicate which
@@ -293,6 +298,7 @@ public CBORGenerator(IOContext ctxt, int stdFeatures, int formatFeatures,
293298
_cfgMinimalInts = Feature.WRITE_MINIMAL_INTS.enabledIn(formatFeatures);
294299
_cfgMinimalDoubles = Feature.WRITE_MINIMAL_DOUBLES.enabledIn(formatFeatures);
295300
_ioContext = ctxt;
301+
_streamWriteConstraints = ctxt.streamWriteConstraints();
296302
_out = out;
297303
_bufferRecyclable = true;
298304
_stringRefs = Feature.STRINGREF.enabledIn(formatFeatures) ? new HashMap<>() : null;
@@ -330,6 +336,7 @@ public CBORGenerator(IOContext ctxt, int stdFeatures, int formatFeatures,
330336
_cfgMinimalInts = Feature.WRITE_MINIMAL_INTS.enabledIn(formatFeatures);
331337
_cfgMinimalDoubles = Feature.WRITE_MINIMAL_DOUBLES.enabledIn(formatFeatures);
332338
_ioContext = ctxt;
339+
_streamWriteConstraints = ctxt.streamWriteConstraints();
333340
_out = out;
334341
_bufferRecyclable = bufferRecyclable;
335342
_outputTail = offset;
@@ -381,7 +388,7 @@ public JacksonFeatureSet<StreamWriteCapability> getWriteCapabilities() {
381388

382389
@Override
383390
public StreamWriteConstraints streamWriteConstraints() {
384-
return _ioContext.streamWriteConstraints();
391+
return _streamWriteConstraints;
385392
}
386393

387394
/**

cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/gen/dos/CyclicDataSerTest.java renamed to cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/gen/dos/CyclicCBORDataSerTest.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package com.fasterxml.jackson.dataformat.cbor.gen.dos;
22

3-
import com.fasterxml.jackson.core.StreamWriteConstraints;
4-
import com.fasterxml.jackson.databind.JsonMappingException;
5-
import com.fasterxml.jackson.databind.ObjectMapper;
6-
import com.fasterxml.jackson.dataformat.cbor.CBORTestBase;
7-
83
import java.util.ArrayList;
94
import java.util.List;
105

6+
import com.fasterxml.jackson.core.StreamWriteConstraints;
7+
import com.fasterxml.jackson.databind.*;
8+
import com.fasterxml.jackson.dataformat.cbor.CBORTestBase;
9+
1110
/**
1211
* Simple unit tests to verify that we fail gracefully if you attempt to serialize
1312
* data that is cyclic (eg a list that contains itself).
1413
*/
15-
public class CyclicDataSerTest extends CBORTestBase
14+
public class CyclicCBORDataSerTest extends CBORTestBase
1615
{
1716
private final ObjectMapper MAPPER = cborMapper();
1817

@@ -21,11 +20,11 @@ public void testListWithSelfReference() throws Exception {
2120
list.add(list);
2221
try {
2322
MAPPER.writeValueAsBytes(list);
24-
fail("expected JsonMappingException");
25-
} catch (JsonMappingException jmex) {
23+
fail("expected DatabindException");
24+
} catch (DatabindException jmex) {
2625
String exceptionPrefix = String.format("Document nesting depth (%d) exceeds the maximum allowed",
2726
StreamWriteConstraints.DEFAULT_MAX_DEPTH + 1);
28-
assertTrue("JsonMappingException message is as expected?",
27+
assertTrue("DatabindException message is as expected?",
2928
jmex.getMessage().startsWith(exceptionPrefix));
3029
}
3130
}

cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/parse/dos/DeepNestingCBORParserTest.java

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
package com.fasterxml.jackson.dataformat.cbor.parse.dos;
22

3-
import com.fasterxml.jackson.core.JsonGenerator;
4-
import com.fasterxml.jackson.core.JsonParser;
5-
import com.fasterxml.jackson.core.JsonToken;
6-
import com.fasterxml.jackson.core.StreamReadConstraints;
7-
import com.fasterxml.jackson.core.StreamWriteConstraints;
3+
import java.io.ByteArrayOutputStream;
4+
import java.io.IOException;
5+
6+
import com.fasterxml.jackson.core.*;
87
import com.fasterxml.jackson.core.exc.StreamConstraintsException;
8+
99
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
1010
import com.fasterxml.jackson.dataformat.cbor.CBORTestBase;
1111

12-
import java.io.ByteArrayOutputStream;
13-
import java.io.IOException;
14-
1512
/**
1613
* Unit tests for deeply nested JSON
1714
*/
@@ -22,10 +19,9 @@ public void testDeeplyNestedObjects() throws Exception
2219
final int depth = 1500;
2320
ByteArrayOutputStream out = new ByteArrayOutputStream();
2421
genDeepDoc(out, depth);
25-
try (JsonParser jp = cborParser(out)) {
26-
JsonToken jt;
27-
while ((jt = jp.nextToken()) != null) {
28-
22+
try (JsonParser p = cborParser(out)) {
23+
while (p.nextToken() != null) {
24+
;
2925
}
3026
fail("expected StreamConstraintsException");
3127
} catch (StreamConstraintsException e) {
@@ -44,10 +40,9 @@ public void testDeeplyNestedObjectsWithUnconstrainedMapper() throws Exception
4440
CBORFactory cborFactory = CBORFactory.builder()
4541
.streamReadConstraints(StreamReadConstraints.builder().maxNestingDepth(Integer.MAX_VALUE).build())
4642
.build();
47-
try (JsonParser jp = cborParser(cborFactory, out)) {
48-
JsonToken jt;
49-
while ((jt = jp.nextToken()) != null) {
50-
43+
try (JsonParser p = cborParser(cborFactory, out)) {
44+
while (p.nextToken() != null) {
45+
;
5146
}
5247
}
5348
}
@@ -57,10 +52,9 @@ public void testDeeplyNestedArrays() throws Exception
5752
final int depth = 750;
5853
ByteArrayOutputStream out = new ByteArrayOutputStream();
5954
genDeepArrayDoc(out, depth);
60-
try (JsonParser jp = cborParser(out)) {
61-
JsonToken jt;
62-
while ((jt = jp.nextToken()) != null) {
63-
55+
try (JsonParser p = cborParser(out)) {
56+
while (p.nextToken() != null) {
57+
;
6458
}
6559
fail("expected StreamConstraintsException");
6660
} catch (StreamConstraintsException e) {
@@ -79,10 +73,9 @@ public void testDeeplyNestedArraysWithUnconstrainedMapper() throws Exception
7973
CBORFactory cborFactory = CBORFactory.builder()
8074
.streamReadConstraints(StreamReadConstraints.builder().maxNestingDepth(Integer.MAX_VALUE).build())
8175
.build();
82-
try (JsonParser jp = cborParser(cborFactory, out)) {
83-
JsonToken jt;
84-
while ((jt = jp.nextToken()) != null) {
85-
76+
try (JsonParser p = cborParser(cborFactory, out)) {
77+
while (p.nextToken() != null) {
78+
;
8679
}
8780
}
8881
}

ion/src/main/java/com/fasterxml/jackson/dataformat/ion/IonGenerator.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ private Feature(boolean defaultState) {
111111

112112
protected final IOContext _ioContext;
113113

114+
/**
115+
* @since 2.16
116+
*/
117+
protected final StreamWriteConstraints _streamWriteConstraints;
118+
114119
/**
115120
* Bit flag composed of bits that indicate which
116121
* {@link IonGenerator.Feature}s
@@ -140,8 +145,8 @@ public IonGenerator(int jsonFeatures, final int ionFeatures, ObjectCodec codec,
140145
_writer = ion;
141146
_ionWriterIsManaged = ionWriterIsManaged;
142147
_ioContext = ctxt;
148+
_streamWriteConstraints = ctxt.streamWriteConstraints();
143149
_destination = dst;
144-
145150
}
146151

147152
@Override
@@ -151,7 +156,7 @@ public Version version() {
151156

152157
@Override
153158
public StreamWriteConstraints streamWriteConstraints() {
154-
return _ioContext.streamWriteConstraints();
159+
return _streamWriteConstraints;
155160
}
156161

157162
/*
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package com.fasterxml.jackson.dataformat.ion.dos;
22

3+
import java.util.ArrayList;
4+
import java.util.List;
5+
36
import com.fasterxml.jackson.core.StreamWriteConstraints;
4-
import com.fasterxml.jackson.databind.JsonMappingException;
5-
import com.fasterxml.jackson.databind.ObjectMapper;
7+
import com.fasterxml.jackson.databind.*;
8+
69
import com.fasterxml.jackson.dataformat.ion.IonObjectMapper;
7-
import org.junit.Test;
810

9-
import java.util.ArrayList;
10-
import java.util.List;
11+
import org.junit.Test;
1112

1213
import static org.junit.Assert.assertTrue;
1314
import static org.junit.Assert.fail;
@@ -16,7 +17,7 @@
1617
* Simple unit tests to verify that we fail gracefully if you attempt to serialize
1718
* data that is cyclic (eg a list that contains itself).
1819
*/
19-
public class CyclicDataSerTest
20+
public class CyclicIonDataSerTest
2021
{
2122
private final ObjectMapper MAPPER = IonObjectMapper.builderForTextualWriters().build();
2223

@@ -26,12 +27,12 @@ public void testListWithSelfReference() throws Exception {
2627
list.add(list);
2728
try {
2829
MAPPER.writeValueAsBytes(list);
29-
fail("expected JsonMappingException");
30-
} catch (JsonMappingException jmex) {
30+
fail("expected DatabindException");
31+
} catch (DatabindException e) {
3132
String exceptionPrefix = String.format("Document nesting depth (%d) exceeds the maximum allowed",
3233
StreamWriteConstraints.DEFAULT_MAX_DEPTH + 1);
33-
assertTrue("JsonMappingException message is as expected?",
34-
jmex.getMessage().startsWith(exceptionPrefix));
34+
assertTrue("DatabindException message is as expected?",
35+
e.getMessage().startsWith(exceptionPrefix));
3536
}
3637
}
3738
}

0 commit comments

Comments
 (0)