Skip to content

Commit 6fde245

Browse files
committed
Add release notes
1 parent d996feb commit 6fde245

3 files changed

Lines changed: 167 additions & 0 deletions

File tree

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.fasterxml.jackson.dataformat.cbor.gen.constraints;
2+
3+
import java.io.ByteArrayInputStream;
4+
import java.io.ByteArrayOutputStream;
5+
6+
import com.fasterxml.jackson.core.JsonGenerator;
7+
import com.fasterxml.jackson.core.JsonParser;
8+
import com.fasterxml.jackson.core.StreamReadConstraints;
9+
import com.fasterxml.jackson.core.exc.StreamConstraintsException;
10+
11+
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
12+
import com.fasterxml.jackson.dataformat.cbor.CBORTestBase;
13+
import com.fasterxml.jackson.dataformat.cbor.databind.CBORMapper;
14+
15+
// [dataformats-binary#651] Validate maxTokenCount support for CBOR
16+
public class TokenCountCBORReadTest extends CBORTestBase
17+
{
18+
private final CBORMapper MAPPER = cborMapper();
19+
20+
// Verify token count is tracked accurately
21+
public void testTokenCountIsTracked() throws Exception
22+
{
23+
// [1, 2, 3]: START_ARRAY, VALUE_NUMBER_INT x3, END_ARRAY = 5 tokens
24+
byte[] doc = createDoc(3);
25+
CBORMapper mapper = mapperWithMaxTokenCount(Long.MAX_VALUE);
26+
try (JsonParser p = mapper.createParser(doc)) {
27+
assertEquals(0L, p.currentTokenCount());
28+
while (p.nextToken() != null) { }
29+
assertEquals(5L, p.currentTokenCount());
30+
}
31+
}
32+
33+
public void testTokenCountLimitWithStream() throws Exception
34+
{
35+
// createDoc(100) produces START_ARRAY + 100xVALUE_NUMBER_INT + END_ARRAY = 102 tokens
36+
byte[] doc = createDoc(100);
37+
CBORMapper mapper = mapperWithMaxTokenCount(10);
38+
try (JsonParser p = mapper.createParser(new ByteArrayInputStream(doc))) {
39+
while (p.nextToken() != null) { }
40+
fail("expected StreamConstraintsException");
41+
} catch (StreamConstraintsException e) {
42+
verifyException(e, "Token count");
43+
verifyException(e, "exceeds the maximum allowed (10,");
44+
}
45+
}
46+
47+
public void testTokenCountLimitWithByteArray() throws Exception
48+
{
49+
// createDoc(100) produces START_ARRAY + 100xVALUE_NUMBER_INT + END_ARRAY = 102 tokens
50+
byte[] doc = createDoc(100);
51+
CBORMapper mapper = mapperWithMaxTokenCount(10);
52+
try (JsonParser p = mapper.createParser(doc)) {
53+
while (p.nextToken() != null) { }
54+
fail("expected StreamConstraintsException");
55+
} catch (StreamConstraintsException e) {
56+
verifyException(e, "Token count");
57+
verifyException(e, "exceeds the maximum allowed (10,");
58+
}
59+
}
60+
61+
private CBORMapper mapperWithMaxTokenCount(long maxTokenCount) {
62+
return cborMapper(
63+
CBORFactory.builder()
64+
.streamReadConstraints(StreamReadConstraints.builder()
65+
.maxTokenCount(maxTokenCount).build())
66+
.build());
67+
}
68+
69+
// Creates a CBOR-encoded array document with the given number of integer elements.
70+
// Token count = numValues + 2 (START_ARRAY + END_ARRAY)
71+
private byte[] createDoc(int numValues) throws Exception {
72+
ByteArrayOutputStream out = new ByteArrayOutputStream();
73+
try (JsonGenerator g = MAPPER.createGenerator(out)) {
74+
g.writeStartArray();
75+
for (int i = 0; i < numValues; i++) {
76+
g.writeNumber(i);
77+
}
78+
g.writeEndArray();
79+
}
80+
return out.toByteArray();
81+
}
82+
}

release-notes/VERSION-2.x

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Active maintainers:
2020
use of Avro core 1.12.1 (2.x)
2121
#649: (cbor, smile) `StreamReadConstraints.maxDocumentLength` not checked
2222
when creating parser with fixed buffer
23+
#651: (smile) Ensure Smile backend supports `StreamReadConstraints.maxTokenCount`
24+
#652: (cbor) Ensure CBOR backend supports `StreamReadConstraints.maxTokenCount`
2325

2426
2.18.5 (27-Oct-2025)
2527

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.fasterxml.jackson.dataformat.smile.constraints;
2+
3+
import java.io.ByteArrayInputStream;
4+
import java.io.ByteArrayOutputStream;
5+
6+
import com.fasterxml.jackson.core.JsonGenerator;
7+
import com.fasterxml.jackson.core.JsonParser;
8+
import com.fasterxml.jackson.core.StreamReadConstraints;
9+
import com.fasterxml.jackson.core.exc.StreamConstraintsException;
10+
11+
import com.fasterxml.jackson.dataformat.smile.BaseTestForSmile;
12+
import com.fasterxml.jackson.dataformat.smile.SmileFactory;
13+
import com.fasterxml.jackson.dataformat.smile.databind.SmileMapper;
14+
15+
// [dataformats-binary#651] Validate maxTokenCount support for Smile
16+
public class TokenCountSmileReadTest extends BaseTestForSmile
17+
{
18+
private final SmileMapper MAPPER = new SmileMapper();
19+
20+
// Verify token count is tracked accurately
21+
public void testTokenCountIsTracked() throws Exception
22+
{
23+
// [1, 2, 3]: START_ARRAY, VALUE_NUMBER_INT x3, END_ARRAY = 5 tokens
24+
byte[] doc = createDoc(3);
25+
SmileMapper mapper = mapperWithMaxTokenCount(Long.MAX_VALUE);
26+
try (JsonParser p = mapper.createParser(doc)) {
27+
assertEquals(0L, p.currentTokenCount());
28+
while (p.nextToken() != null) { }
29+
assertEquals(5L, p.currentTokenCount());
30+
}
31+
}
32+
33+
public void testTokenCountLimitWithStream() throws Exception
34+
{
35+
// createDoc(100) produces START_ARRAY + 100xVALUE_NUMBER_INT + END_ARRAY = 102 tokens
36+
byte[] doc = createDoc(100);
37+
SmileMapper mapper = mapperWithMaxTokenCount(10);
38+
try (JsonParser p = mapper.createParser(new ByteArrayInputStream(doc))) {
39+
while (p.nextToken() != null) { }
40+
fail("expected StreamConstraintsException");
41+
} catch (StreamConstraintsException e) {
42+
verifyException(e, "Token count");
43+
verifyException(e, "exceeds the maximum allowed (10,");
44+
}
45+
}
46+
47+
public void testTokenCountLimitWithByteArray() throws Exception
48+
{
49+
// createDoc(100) produces START_ARRAY + 100xVALUE_NUMBER_INT + END_ARRAY = 102 tokens
50+
byte[] doc = createDoc(100);
51+
SmileMapper mapper = mapperWithMaxTokenCount(10);
52+
try (JsonParser p = mapper.createParser(doc)) {
53+
while (p.nextToken() != null) { }
54+
fail("expected StreamConstraintsException");
55+
} catch (StreamConstraintsException e) {
56+
verifyException(e, "Token count");
57+
verifyException(e, "exceeds the maximum allowed (10,");
58+
}
59+
}
60+
61+
private SmileMapper mapperWithMaxTokenCount(long maxTokenCount) {
62+
return SmileMapper.builder(
63+
SmileFactory.builder()
64+
.streamReadConstraints(StreamReadConstraints.builder()
65+
.maxTokenCount(maxTokenCount).build())
66+
.build())
67+
.build();
68+
}
69+
70+
// Creates a Smile-encoded array document with the given number of integer elements.
71+
// Token count = numValues + 2 (START_ARRAY + END_ARRAY)
72+
private byte[] createDoc(int numValues) throws Exception {
73+
ByteArrayOutputStream out = new ByteArrayOutputStream();
74+
try (JsonGenerator g = MAPPER.createGenerator(out)) {
75+
g.writeStartArray();
76+
for (int i = 0; i < numValues; i++) {
77+
g.writeNumber(i);
78+
}
79+
g.writeEndArray();
80+
}
81+
return out.toByteArray();
82+
}
83+
}

0 commit comments

Comments
 (0)