Skip to content

Commit 7229150

Browse files
committed
Fix a small problem wrt #265 fix (via backported 3.0 test)
1 parent 01b8835 commit 7229150

File tree

2 files changed

+176
-1
lines changed

2 files changed

+176
-1
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2642,6 +2642,7 @@ protected byte[] _finishBinary7BitLong(final int expLen) throws IOException
26422642
bb.write(buffer, 0, bufPtr);
26432643
bufPtr = 0;
26442644
}
2645+
left -= 7;
26452646
}
26462647

26472648
// And then the last one; we know there is room in buffer so:
@@ -2657,7 +2658,7 @@ protected byte[] _finishBinary7BitLong(final int expLen) throws IOException
26572658
}
26582659
// last byte is different, has remaining 1 - 6 bits, right-aligned
26592660
value <<= left;
2660-
buffer[bufPtr] = (byte) (value + _inputBuffer[_inputPtr++]);
2661+
buffer[bufPtr++] = (byte) (value + _inputBuffer[_inputPtr++]);
26612662
}
26622663
if (bufPtr > 0) {
26632664
bb.write(buffer, 0, bufPtr);
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
package com.fasterxml.jackson.dataformat.smile.mapper;
2+
3+
import java.io.*;
4+
import java.util.Arrays;
5+
import java.util.List;
6+
7+
import org.junit.Assert;
8+
9+
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
10+
11+
import com.fasterxml.jackson.core.JsonParser;
12+
import com.fasterxml.jackson.core.JsonToken;
13+
import com.fasterxml.jackson.databind.JsonNode;
14+
import com.fasterxml.jackson.databind.ObjectMapper;
15+
import com.fasterxml.jackson.databind.node.BinaryNode;
16+
import com.fasterxml.jackson.dataformat.smile.BaseTestForSmile;
17+
import com.fasterxml.jackson.dataformat.smile.testutil.ThrottledInputStream;
18+
19+
public class BinaryReadTest extends BaseTestForSmile
20+
{
21+
final static class Bytes {
22+
public byte[] bytes;
23+
24+
public Bytes() { }
25+
public Bytes(byte[] b) { bytes = b; }
26+
}
27+
28+
final static class ByteArrays {
29+
public List<byte[]> arrays;
30+
31+
public ByteArrays() { }
32+
public ByteArrays(byte[]... b) { arrays = Arrays.asList(b); }
33+
}
34+
35+
@JsonPropertyOrder({ "bytes1", "bytes2", "bytes3" })
36+
final static class Bytes3 {
37+
public byte[] bytes1, bytes2, bytes3;
38+
39+
public Bytes3() { }
40+
public Bytes3(byte[] b) {
41+
bytes1 = b;
42+
bytes2 = b;
43+
bytes3 = b;
44+
}
45+
}
46+
47+
private final ObjectMapper MAPPER = smileMapper();
48+
49+
public void testSmallBinaryValues() throws Exception {
50+
_testBinary(0);
51+
_testBinary(1);
52+
_testBinary(20);
53+
_testBinary(100);
54+
}
55+
56+
public void testMediumBinaryValues() throws Exception {
57+
_testBinary(500);
58+
_testBinary(1500);
59+
_testBinary(8900);
60+
}
61+
62+
public void testLargeBinaryValues() throws Exception {
63+
_testBinary(99000);
64+
_testBinary(299000);
65+
_testBinary(740000);
66+
}
67+
68+
// And then one test just to ensure no state corruption occurs
69+
public void testMultipleBinaryFields() throws Exception
70+
{
71+
byte[] inputBytes = new byte[900];
72+
for (int i = 0; i < inputBytes.length; ++i) {
73+
inputBytes[i] = (byte) i;
74+
}
75+
Bytes3 input = new Bytes3(inputBytes);
76+
byte[] raw = MAPPER.writeValueAsBytes(input);
77+
78+
Bytes3 result = MAPPER.readValue(raw, Bytes3.class);
79+
Assert.assertArrayEquals(input.bytes1, result.bytes1);
80+
Assert.assertArrayEquals(input.bytes2, result.bytes2);
81+
Assert.assertArrayEquals(input.bytes3, result.bytes3);
82+
}
83+
84+
public void _testBinary(int size) throws Exception
85+
{
86+
byte[] input = _bytes(size, 0);
87+
88+
// First, read/write as individual value
89+
byte[] raw = MAPPER.writeValueAsBytes(input);
90+
byte[] b2 = MAPPER.readValue(raw, byte[].class);
91+
assertNotNull(b2);
92+
Assert.assertArrayEquals(input, b2);
93+
94+
// then as POJO member
95+
raw = MAPPER.writeValueAsBytes(new Bytes(input));
96+
Bytes bytes = MAPPER.readValue(raw, Bytes.class);
97+
assertNotNull(bytes);
98+
assertNotNull(bytes.bytes);
99+
Assert.assertArrayEquals(input, bytes.bytes);
100+
101+
// then using incremental access method
102+
raw = MAPPER.writeValueAsBytes(input);
103+
104+
InputStream in = new ThrottledInputStream(raw, 3);
105+
JsonParser p = MAPPER.createParser(in);
106+
assertToken(JsonToken.VALUE_EMBEDDED_OBJECT, p.nextToken());
107+
ByteArrayOutputStream bout = new ByteArrayOutputStream(input.length / 3);
108+
assertEquals(input.length, p.readBinaryValue(bout));
109+
assertEquals(input.length, bout.size());
110+
b2 = bout.toByteArray();
111+
Assert.assertArrayEquals(input, b2);
112+
assertNull(p.nextToken());
113+
p.close();
114+
in.close();
115+
116+
// and finally streaming but skipping
117+
in = new ThrottledInputStream(raw, 3);
118+
p = MAPPER.createParser(in);
119+
assertToken(JsonToken.VALUE_EMBEDDED_OBJECT, p.nextToken());
120+
assertNull(p.nextToken());
121+
p.close();
122+
in.close();
123+
124+
// And once more! Read as tree
125+
JsonNode n = MAPPER.readTree(MAPPER.writeValueAsBytes(new Bytes(input)));
126+
assertTrue(n.isObject());
127+
assertEquals(1, n.size());
128+
129+
n = n.get("bytes");
130+
assertNotNull(n);
131+
assertTrue(n.isBinary());
132+
BinaryNode bn = (BinaryNode) n;
133+
Assert.assertArrayEquals(input, bn.binaryValue());
134+
135+
_testBinaryInArray(size);
136+
}
137+
138+
private void _testBinaryInArray(int size) throws Exception
139+
{
140+
byte[] b1 = _bytes(size, 1);
141+
byte[] b2 = _bytes(size, 7);
142+
byte[] doc = MAPPER.writeValueAsBytes(new ByteArrays(b1, b2));
143+
@SuppressWarnings("resource")
144+
ByteArrays result = MAPPER.readValue(new ThrottledInputStream(doc, 5),
145+
ByteArrays.class);
146+
assertNotNull(result.arrays);
147+
assertEquals(2, result.arrays.size());
148+
Assert.assertArrayEquals(b1, result.arrays.get(0));
149+
Assert.assertArrayEquals(b2, result.arrays.get(1));
150+
151+
// and once more, now as JsonNode
152+
JsonNode n = MAPPER.readTree(doc);
153+
assertTrue(n.isObject());
154+
JsonNode n2 = n.get("arrays");
155+
assertTrue(n2.isArray());
156+
assertEquals(2, n2.size());
157+
158+
JsonNode bin = n2.get(0);
159+
assertTrue(bin.isBinary());
160+
Assert.assertArrayEquals(b1, ((BinaryNode) bin).binaryValue());
161+
162+
bin = n2.get(1);
163+
assertTrue(bin.isBinary());
164+
Assert.assertArrayEquals(b2, ((BinaryNode) bin).binaryValue());
165+
}
166+
167+
private byte[] _bytes(int size, int offset) {
168+
byte[] input = new byte[size];
169+
for (int i = 0; i < input.length; ++i) {
170+
input[i] = (byte) (i + offset);
171+
}
172+
return input;
173+
}
174+
}

0 commit comments

Comments
 (0)