Skip to content

Commit 0334a27

Browse files
authored
uptake read constrained text buffer (#357)
1 parent 2f12257 commit 0334a27

File tree

8 files changed

+117
-11
lines changed

8 files changed

+117
-11
lines changed

avro/src/test/java/com/fasterxml/jackson/dataformat/avro/RoundtripTest.java

+28-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.fasterxml.jackson.core.JsonGenerator;
44

5+
import com.fasterxml.jackson.core.StreamReadConstraints;
56
import com.fasterxml.jackson.databind.*;
67

78
public class RoundtripTest extends MapTest
@@ -69,14 +70,8 @@ public void testCharSequences() throws Exception
6970
input.id = "123";
7071
input.name = "John";
7172

72-
byte[] avroData = null;
73-
try {
74-
avroData = writ.writeValueAsBytes(input);
75-
assertNotNull(avroData);
76-
} catch (Exception e) {
77-
e.printStackTrace();
78-
throw e;
79-
}
73+
byte[] avroData = writ.writeValueAsBytes(input);
74+
assertNotNull(avroData);
8075

8176
CharSeqBean output = mapper.reader(CHARSEQ_SCHEMA)
8277
.forType(CharSeqBean.class).readValue(avroData);
@@ -85,4 +80,29 @@ public void testCharSequences() throws Exception
8580
assertEquals(input.id, output.id);
8681
assertEquals(input.name, output.name);
8782
}
83+
84+
public void testCharSequencesLowStringLimit() throws Exception
85+
{
86+
AvroFactory factory = AvroFactory.builder()
87+
.streamReadConstraints(StreamReadConstraints.builder().maxStringLength(1).build())
88+
.build();
89+
ObjectMapper mapper = new AvroMapper(factory)
90+
.enable(JsonGenerator.Feature.IGNORE_UNKNOWN);
91+
ObjectWriter writ = mapper.writer(CHARSEQ_SCHEMA);
92+
93+
CharSeqBean input = new CharSeqBean();
94+
input.id = "123";
95+
input.name = "John";
96+
97+
byte[] avroData = writ.writeValueAsBytes(input);
98+
assertNotNull(avroData);
99+
100+
try {
101+
mapper.reader(CHARSEQ_SCHEMA)
102+
.forType(CharSeqBean.class).readValue(avroData);
103+
fail("expected IllegalStateException");
104+
} catch (IllegalStateException ise) {
105+
assertEquals("String length (3) exceeds the maximum length (1)", ise.getMessage());
106+
}
107+
}
88108
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ public CBORParser(IOContext ctxt, int parserFeatures, int cborFeatures,
525525
_inputPtr = start;
526526
_inputEnd = end;
527527
_bufferRecyclable = bufferRecyclable;
528-
_textBuffer = ctxt.constructTextBuffer();
528+
_textBuffer = ctxt.constructReadConstrainedTextBuffer();
529529
DupDetector dups = JsonParser.Feature.STRICT_DUPLICATE_DETECTION.enabledIn(parserFeatures)
530530
? DupDetector.rootDetector(this) : null;
531531
_streamReadContext = CBORReadContext.createRootContext(dups);

cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/CBORTestBase.java

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ protected CBORMapper cborMapper() {
4545
return new CBORMapper(cborFactory());
4646
}
4747

48+
protected CBORMapper cborMapper(CBORFactory cborFactory) {
49+
return new CBORMapper(cborFactory);
50+
}
51+
4852
protected CBORFactory cborFactory() {
4953
return new CBORFactory();
5054
}

cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/seq/ReadTreesTest.java

+25
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import java.util.List;
44

5+
import com.fasterxml.jackson.core.StreamReadConstraints;
56
import com.fasterxml.jackson.databind.*;
67

8+
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
79
import com.fasterxml.jackson.dataformat.cbor.CBORTestBase;
810

911
public class ReadTreesTest extends CBORTestBase
@@ -62,4 +64,27 @@ public void testReadTreeSequence() throws Exception
6264
/* not differ)
6365
/**********************************************************
6466
*/
67+
68+
public void testReadTreeSequenceLowStringLimit() throws Exception
69+
{
70+
final byte[] INPUT = concat(
71+
cborDoc(a2q("{\"id\":1, \"value\":137 }")),
72+
cborDoc(a2q("{\"id\":2, \"value\":256 }\n")),
73+
cborDoc(a2q("{\"id\":3, \"value\":-89 }"))
74+
);
75+
76+
CBORFactory cborFactory = cborFactoryBuilder()
77+
.streamReadConstraints(StreamReadConstraints.builder().maxStringLength(1).build())
78+
.build();
79+
try (MappingIterator<JsonNode> it = cborMapper(cborFactory).readerFor(JsonNode.class)
80+
.readValues(INPUT)) {
81+
assertTrue(it.hasNextValue());
82+
try {
83+
it.nextValue();
84+
fail("expected IllegalStateException");
85+
} catch (IllegalStateException ise) {
86+
assertEquals("String length (2) exceeds the maximum length (1)", ise.getMessage());
87+
}
88+
}
89+
}
6590
}

protobuf/src/main/java/com/fasterxml/jackson/dataformat/protobuf/ProtobufParser.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ public ProtobufParser(IOContext ctxt, int parserFeatures,
305305
_inputPtr = start;
306306
_inputEnd = end;
307307
_bufferRecyclable = bufferRecyclable;
308-
_textBuffer = ctxt.constructTextBuffer();
308+
_textBuffer = ctxt.constructReadConstrainedTextBuffer();
309309
_parsingContext = ProtobufReadContext.createRootContext();
310310

311311
_tokenInputRow = -1;

protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/ReadSimpleTest.java

+26
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
import com.fasterxml.jackson.core.JsonParser;
77
import com.fasterxml.jackson.core.JsonToken;
8+
import com.fasterxml.jackson.core.StreamReadConstraints;
9+
import com.fasterxml.jackson.databind.JsonMappingException;
810
import com.fasterxml.jackson.databind.ObjectMapper;
911
import com.fasterxml.jackson.databind.ObjectWriter;
1012
import com.fasterxml.jackson.dataformat.protobuf.schema.ProtobufSchema;
@@ -357,4 +359,28 @@ public void testSkipUnknown() throws Exception
357359
assertEquals(input.x, result.x);
358360
assertEquals(input.y, result.y);
359361
}
362+
363+
public void testStringArraySimpleLowLimit() throws Exception
364+
{
365+
ProtobufSchema schema = ProtobufSchemaLoader.std.parse(PROTOC_STRINGS);
366+
ProtobufFactory protobufFactory = ProtobufFactory.builder()
367+
.streamReadConstraints(StreamReadConstraints.builder().maxStringLength(1).build())
368+
.build();
369+
ProtobufMapper protobufMapper = ProtobufMapper.builder(protobufFactory).build();
370+
final ObjectWriter w = protobufMapper.writerFor(Strings.class)
371+
.with(schema);
372+
Strings input = new Strings("Dogs", "like", "Baco\u00F1");
373+
byte[] bytes = w.writeValueAsBytes(input);
374+
assertNotNull(bytes);
375+
assertEquals(20, bytes.length);
376+
377+
try {
378+
protobufMapper.readerFor(Strings.class).with(schema).readValue(bytes);
379+
fail("Expected JsonMappingException");
380+
} catch (JsonMappingException jme) {
381+
String message = jme.getMessage();
382+
assertTrue("unexpected message: " + message,
383+
message.startsWith("String length (4) exceeds the maximum length (1)"));
384+
}
385+
}
360386
}

smile/src/main/java/com/fasterxml/jackson/dataformat/smile/SmileParserBase.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ public SmileParserBase(IOContext ctxt, int parserFeatures, int formatFeatures,
269269
? DupDetector.rootDetector(this) : null;
270270
_streamReadContext = JsonReadContext.createRootContext(dups);
271271

272-
_textBuffer = ctxt.constructTextBuffer();
272+
_textBuffer = ctxt.constructReadConstrainedTextBuffer();
273273
_smileBufferRecycler = _smileBufferRecycler();
274274
}
275275

smile/src/test/java/com/fasterxml/jackson/dataformat/smile/async/SimpleStringArrayTest.java

+31
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import com.fasterxml.jackson.core.JsonGenerator;
77
import com.fasterxml.jackson.core.JsonToken;
8+
import com.fasterxml.jackson.core.StreamReadConstraints;
89
import com.fasterxml.jackson.dataformat.smile.SmileFactory;
910
import com.fasterxml.jackson.dataformat.smile.SmileGenerator;
1011
import com.fasterxml.jackson.dataformat.smile.SmileParser;
@@ -109,6 +110,36 @@ public void testLongAsciiStrings() throws IOException
109110
_testStrings(f, input, data, 1, 1);
110111
}
111112

113+
public void testLongAsciiStringsLowStringLimit() throws IOException
114+
{
115+
final String[] input = new String[] {
116+
// ~100 chars for long(er) content
117+
String.format("%s %s %s %s %s %s %s %s %s %s %s %s",
118+
str0to9,str0to9,"...",str0to9,"/", str0to9,
119+
str0to9,"",str0to9,str0to9,"...",str0to9),
120+
LONG_ASCII
121+
};
122+
SmileFactory f = SmileFactory.builder()
123+
.streamReadConstraints(StreamReadConstraints.builder().maxStringLength(10).build())
124+
.enable(SmileParser.Feature.REQUIRE_HEADER)
125+
.enable(SmileGenerator.Feature.CHECK_SHARED_NAMES)
126+
.enable(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES)
127+
.build();
128+
byte[] data = _stringDoc(f, input);
129+
130+
AsyncReaderWrapper r = asyncForBytes(f, 1, data, 0);
131+
// start with "no token"
132+
assertNull(r.currentToken());
133+
assertToken(JsonToken.START_ARRAY, r.nextToken());
134+
assertToken(JsonToken.VALUE_STRING, r.nextToken());
135+
try {
136+
r.currentText();
137+
fail("expected IllegalStateException");
138+
} catch (IllegalStateException ise) {
139+
assertEquals("String length (98) exceeds the maximum length (10)", ise.getMessage());
140+
}
141+
}
142+
112143
public void testLongUnicodeStrings() throws IOException
113144
{
114145
// ~100 chars for long(er) content

0 commit comments

Comments
 (0)