Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: third_party/protobuf/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java

Issue 2600753002: Reverts third_party/protobuf: Update to HEAD (f52e188fe4) (Closed)
Patch Set: Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 17 matching lines...) Expand all
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 30
31 package com.google.protobuf; 31 package com.google.protobuf;
32 32
33 import protobuf_unittest.UnittestProto.BoolMessage; 33 import protobuf_unittest.UnittestProto.BoolMessage;
34 import protobuf_unittest.UnittestProto.Int32Message; 34 import protobuf_unittest.UnittestProto.Int32Message;
35 import protobuf_unittest.UnittestProto.Int64Message; 35 import protobuf_unittest.UnittestProto.Int64Message;
36 import protobuf_unittest.UnittestProto.TestAllTypes; 36 import protobuf_unittest.UnittestProto.TestAllTypes;
37 import protobuf_unittest.UnittestProto.TestRecursiveMessage; 37 import protobuf_unittest.UnittestProto.TestRecursiveMessage;
38
39 import junit.framework.TestCase;
40
38 import java.io.ByteArrayInputStream; 41 import java.io.ByteArrayInputStream;
39 import java.io.ByteArrayOutputStream; 42 import java.io.ByteArrayOutputStream;
40 import java.io.FilterInputStream; 43 import java.io.FilterInputStream;
41 import java.io.IOException; 44 import java.io.IOException;
42 import java.io.InputStream; 45 import java.io.InputStream;
43 import java.nio.ByteBuffer; 46 import java.nio.ByteBuffer;
44 import junit.framework.TestCase;
45 47
46 /** 48 /**
47 * Unit test for {@link CodedInputStream}. 49 * Unit test for {@link CodedInputStream}.
48 * 50 *
49 * @author kenton@google.com Kenton Varda 51 * @author kenton@google.com Kenton Varda
50 */ 52 */
51 public class CodedInputStreamTest extends TestCase { 53 public class CodedInputStreamTest extends TestCase {
52 private enum InputType {
53 ARRAY {
54 @Override
55 CodedInputStream newDecoder(byte[] data, int blockSize) {
56 return CodedInputStream.newInstance(data);
57 }
58 },
59 NIO_HEAP {
60 @Override
61 CodedInputStream newDecoder(byte[] data, int blockSize) {
62 return CodedInputStream.newInstance(ByteBuffer.wrap(data));
63 }
64 },
65 NIO_DIRECT {
66 @Override
67 CodedInputStream newDecoder(byte[] data, int blockSize) {
68 ByteBuffer buffer = ByteBuffer.allocateDirect(data.length);
69 buffer.put(data);
70 buffer.flip();
71 return CodedInputStream.newInstance(buffer);
72 }
73 },
74 STREAM {
75 @Override
76 CodedInputStream newDecoder(byte[] data, int blockSize) {
77 return CodedInputStream.newInstance(new SmallBlockInputStream(data, bloc kSize));
78 }
79 };
80
81 CodedInputStream newDecoder(byte[] data) {
82 return newDecoder(data, data.length);
83 }
84
85 abstract CodedInputStream newDecoder(byte[] data, int blockSize);
86 }
87
88 /** 54 /**
89 * Helper to construct a byte array from a bunch of bytes. The inputs are actu ally ints so that I 55 * Helper to construct a byte array from a bunch of bytes. The inputs are
90 * can use hex notation and not get stupid errors about precision. 56 * actually ints so that I can use hex notation and not get stupid errors
57 * about precision.
91 */ 58 */
92 private byte[] bytes(int... bytesAsInts) { 59 private byte[] bytes(int... bytesAsInts) {
93 byte[] bytes = new byte[bytesAsInts.length]; 60 byte[] bytes = new byte[bytesAsInts.length];
94 for (int i = 0; i < bytesAsInts.length; i++) { 61 for (int i = 0; i < bytesAsInts.length; i++) {
95 bytes[i] = (byte) bytesAsInts[i]; 62 bytes[i] = (byte) bytesAsInts[i];
96 } 63 }
97 return bytes; 64 return bytes;
98 } 65 }
99 66
100 /** 67 /**
101 * An InputStream which limits the number of bytes it reads at a time. We use this to make sure 68 * An InputStream which limits the number of bytes it reads at a time.
102 * that CodedInputStream doesn't screw up when reading in small blocks. 69 * We use this to make sure that CodedInputStream doesn't screw up when
70 * reading in small blocks.
103 */ 71 */
104 private static final class SmallBlockInputStream extends FilterInputStream { 72 private static final class SmallBlockInputStream extends FilterInputStream {
105 private final int blockSize; 73 private final int blockSize;
106 74
107 public SmallBlockInputStream(byte[] data, int blockSize) { 75 public SmallBlockInputStream(byte[] data, int blockSize) {
108 super(new ByteArrayInputStream(data)); 76 this(new ByteArrayInputStream(data), blockSize);
77 }
78
79 public SmallBlockInputStream(InputStream in, int blockSize) {
80 super(in);
109 this.blockSize = blockSize; 81 this.blockSize = blockSize;
110 } 82 }
111 83
112 @Override 84 @Override
113 public int read(byte[] b) throws IOException { 85 public int read(byte[] b) throws IOException {
114 return super.read(b, 0, Math.min(b.length, blockSize)); 86 return super.read(b, 0, Math.min(b.length, blockSize));
115 } 87 }
116 88
117 @Override 89 @Override
118 public int read(byte[] b, int off, int len) throws IOException { 90 public int read(byte[] b, int off, int len) throws IOException {
119 return super.read(b, off, Math.min(len, blockSize)); 91 return super.read(b, off, Math.min(len, blockSize));
120 } 92 }
121 } 93 }
122 94
123 private void assertDataConsumed(String msg, byte[] data, CodedInputStream inpu t) 95 private void assertDataConsumed(byte[] data, CodedInputStream input)
124 throws IOException { 96 throws IOException {
125 assertEquals(msg, data.length, input.getTotalBytesRead()); 97 assertEquals(data.length, input.getTotalBytesRead());
126 assertTrue(msg, input.isAtEnd()); 98 assertTrue(input.isAtEnd());
127 } 99 }
128 100
129 /** 101 /**
130 * Parses the given bytes using readRawVarint32() and readRawVarint64() and ch ecks that the result 102 * Parses the given bytes using readRawVarint32() and readRawVarint64() and
131 * matches the given value. 103 * checks that the result matches the given value.
132 */ 104 */
133 private void assertReadVarint(byte[] data, long value) throws Exception { 105 private void assertReadVarint(byte[] data, long value) throws Exception {
134 for (InputType inputType : InputType.values()) { 106 CodedInputStream input = CodedInputStream.newInstance(data);
135 // Try different block sizes. 107 assertEquals((int) value, input.readRawVarint32());
136 for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { 108 assertDataConsumed(data, input);
137 CodedInputStream input = inputType.newDecoder(data, blockSize);
138 assertEquals(inputType.name(), (int) value, input.readRawVarint32());
139 assertDataConsumed(inputType.name(), data, input);
140 109
141 input = inputType.newDecoder(data, blockSize); 110 input = CodedInputStream.newInstance(data);
142 assertEquals(inputType.name(), value, input.readRawVarint64()); 111 assertEquals(value, input.readRawVarint64());
143 assertDataConsumed(inputType.name(), data, input); 112 assertDataConsumed(data, input);
144 113
145 input = inputType.newDecoder(data, blockSize); 114 input = CodedInputStream.newInstance(data);
146 assertEquals(inputType.name(), value, input.readRawVarint64SlowPath()); 115 assertEquals(value, input.readRawVarint64SlowPath());
147 assertDataConsumed(inputType.name(), data, input); 116 assertDataConsumed(data, input);
148 117
149 input = inputType.newDecoder(data, blockSize); 118 input = CodedInputStream.newInstance(data);
150 assertTrue(inputType.name(), input.skipField(WireFormat.WIRETYPE_VARINT) ); 119 assertTrue(input.skipField(WireFormat.WIRETYPE_VARINT));
151 assertDataConsumed(inputType.name(), data, input); 120 assertDataConsumed(data, input);
152 } 121
122 // Try different block sizes.
123 for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
124 input = CodedInputStream.newInstance(
125 new SmallBlockInputStream(data, blockSize));
126 assertEquals((int) value, input.readRawVarint32());
127 assertDataConsumed(data, input);
128
129 input = CodedInputStream.newInstance(
130 new SmallBlockInputStream(data, blockSize));
131 assertEquals(value, input.readRawVarint64());
132 assertDataConsumed(data, input);
133
134 input = CodedInputStream.newInstance(
135 new SmallBlockInputStream(data, blockSize));
136 assertEquals(value, input.readRawVarint64SlowPath());
137 assertDataConsumed(data, input);
138
139 input = CodedInputStream.newInstance(
140 new SmallBlockInputStream(data, blockSize));
141 assertTrue(input.skipField(WireFormat.WIRETYPE_VARINT));
142 assertDataConsumed(data, input);
153 } 143 }
154 144
155 // Try reading direct from an InputStream. We want to verify that it 145 // Try reading direct from an InputStream. We want to verify that it
156 // doesn't read past the end of the input, so we copy to a new, bigger 146 // doesn't read past the end of the input, so we copy to a new, bigger
157 // array first. 147 // array first.
158 byte[] longerData = new byte[data.length + 1]; 148 byte[] longerData = new byte[data.length + 1];
159 System.arraycopy(data, 0, longerData, 0, data.length); 149 System.arraycopy(data, 0, longerData, 0, data.length);
160 InputStream rawInput = new ByteArrayInputStream(longerData); 150 InputStream rawInput = new ByteArrayInputStream(longerData);
161 assertEquals((int) value, CodedInputStream.readRawVarint32(rawInput)); 151 assertEquals((int) value, CodedInputStream.readRawVarint32(rawInput));
162 assertEquals(1, rawInput.available()); 152 assertEquals(1, rawInput.available());
163 } 153 }
164 154
165 /** 155 /**
166 * Parses the given bytes using readRawVarint32() and readRawVarint64() and ex pects them to fail 156 * Parses the given bytes using readRawVarint32() and readRawVarint64() and
167 * with an InvalidProtocolBufferException whose description matches the given one. 157 * expects them to fail with an InvalidProtocolBufferException whose
158 * description matches the given one.
168 */ 159 */
169 private void assertReadVarintFailure(InvalidProtocolBufferException expected, byte[] data) 160 private void assertReadVarintFailure(
161 InvalidProtocolBufferException expected, byte[] data)
170 throws Exception { 162 throws Exception {
171 for (InputType inputType : InputType.values()) { 163 CodedInputStream input = CodedInputStream.newInstance(data);
172 try { 164 try {
173 CodedInputStream input = inputType.newDecoder(data); 165 input.readRawVarint32();
174 input.readRawVarint32(); 166 fail("Should have thrown an exception.");
175 fail(inputType.name() + ": Should have thrown an exception."); 167 } catch (InvalidProtocolBufferException e) {
176 } catch (InvalidProtocolBufferException e) { 168 assertEquals(expected.getMessage(), e.getMessage());
177 assertEquals(inputType.name(), expected.getMessage(), e.getMessage()); 169 }
178 } 170
179 try { 171 input = CodedInputStream.newInstance(data);
180 CodedInputStream input = inputType.newDecoder(data); 172 try {
181 input.readRawVarint64(); 173 input.readRawVarint64();
182 fail(inputType.name() + ": Should have thrown an exception."); 174 fail("Should have thrown an exception.");
183 } catch (InvalidProtocolBufferException e) { 175 } catch (InvalidProtocolBufferException e) {
184 assertEquals(inputType.name(), expected.getMessage(), e.getMessage()); 176 assertEquals(expected.getMessage(), e.getMessage());
185 } 177 }
178
179 input = CodedInputStream.newInstance(data);
180 try {
181 input.readRawVarint64SlowPath();
182 fail("Should have thrown an exception.");
183 } catch (InvalidProtocolBufferException e) {
184 assertEquals(expected.getMessage(), e.getMessage());
186 } 185 }
187 186
188 // Make sure we get the same error when reading direct from an InputStream. 187 // Make sure we get the same error when reading direct from an InputStream.
189 try { 188 try {
190 CodedInputStream.readRawVarint32(new ByteArrayInputStream(data)); 189 CodedInputStream.readRawVarint32(new ByteArrayInputStream(data));
191 fail("Should have thrown an exception."); 190 fail("Should have thrown an exception.");
192 } catch (InvalidProtocolBufferException e) { 191 } catch (InvalidProtocolBufferException e) {
193 assertEquals(expected.getMessage(), e.getMessage()); 192 assertEquals(expected.getMessage(), e.getMessage());
194 } 193 }
195 } 194 }
196 195
197 /** Tests readRawVarint32() and readRawVarint64(). */ 196 /** Tests readRawVarint32() and readRawVarint64(). */
198 public void testReadVarint() throws Exception { 197 public void testReadVarint() throws Exception {
199 assertReadVarint(bytes(0x00), 0); 198 assertReadVarint(bytes(0x00), 0);
200 assertReadVarint(bytes(0x01), 1); 199 assertReadVarint(bytes(0x01), 1);
201 assertReadVarint(bytes(0x7f), 127); 200 assertReadVarint(bytes(0x7f), 127);
202 // 14882 201 // 14882
203 assertReadVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7)); 202 assertReadVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
204 // 2961488830 203 // 2961488830
205 assertReadVarint( 204 assertReadVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
206 bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b), 205 (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
207 (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | (0x0bL << 28)) ; 206 (0x0bL << 28));
208 207
209 // 64-bit 208 // 64-bit
210 // 7256456126 209 // 7256456126
211 assertReadVarint( 210 assertReadVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
212 bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b), 211 (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
213 (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | (0x1bL << 28)) ; 212 (0x1bL << 28));
214 // 41256202580718336 213 // 41256202580718336
215 assertReadVarint( 214 assertReadVarint(
216 bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49), 215 bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
217 (0x00 << 0) 216 (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
218 | (0x66 << 7) 217 (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
219 | (0x6b << 14)
220 | (0x1c << 21)
221 | (0x43L << 28)
222 | (0x49L << 35)
223 | (0x24L << 42)
224 | (0x49L << 49));
225 // 11964378330978735131 218 // 11964378330978735131
226 assertReadVarint( 219 assertReadVarint(
227 bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01), 220 bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
228 (0x1b << 0) 221 (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
229 | (0x28 << 7) 222 (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
230 | (0x79 << 14) 223 (0x05L << 49) | (0x26L << 56) | (0x01L << 63));
231 | (0x42 << 21)
232 | (0x3bL << 28)
233 | (0x56L << 35)
234 | (0x00L << 42)
235 | (0x05L << 49)
236 | (0x26L << 56)
237 | (0x01L << 63));
238 224
239 // Failures 225 // Failures
240 assertReadVarintFailure( 226 assertReadVarintFailure(
241 InvalidProtocolBufferException.malformedVarint(), 227 InvalidProtocolBufferException.malformedVarint(),
242 bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)) ; 228 bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
243 assertReadVarintFailure(InvalidProtocolBufferException.truncatedMessage(), b ytes(0x80)); 229 0x00));
230 assertReadVarintFailure(
231 InvalidProtocolBufferException.truncatedMessage(),
232 bytes(0x80));
244 } 233 }
245 234
246 /** 235 /**
247 * Parses the given bytes using readRawLittleEndian32() and checks that the re sult matches the 236 * Parses the given bytes using readRawLittleEndian32() and checks
248 * given value. 237 * that the result matches the given value.
249 */ 238 */
250 private void assertReadLittleEndian32(byte[] data, int value) throws Exception { 239 private void assertReadLittleEndian32(byte[] data, int value)
251 for (InputType inputType : InputType.values()) { 240 throws Exception {
252 // Try different block sizes. 241 CodedInputStream input = CodedInputStream.newInstance(data);
253 for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { 242 assertEquals(value, input.readRawLittleEndian32());
254 CodedInputStream input = inputType.newDecoder(data, blockSize); 243 assertTrue(input.isAtEnd());
255 assertEquals(inputType.name(), value, input.readRawLittleEndian32()); 244
256 assertTrue(inputType.name(), input.isAtEnd()); 245 // Try different block sizes.
257 } 246 for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
247 input = CodedInputStream.newInstance(
248 new SmallBlockInputStream(data, blockSize));
249 assertEquals(value, input.readRawLittleEndian32());
250 assertTrue(input.isAtEnd());
258 } 251 }
259 } 252 }
260 253
261 /** 254 /**
262 * Parses the given bytes using readRawLittleEndian64() and checks that the re sult matches the 255 * Parses the given bytes using readRawLittleEndian64() and checks
263 * given value. 256 * that the result matches the given value.
264 */ 257 */
265 private void assertReadLittleEndian64(byte[] data, long value) throws Exceptio n { 258 private void assertReadLittleEndian64(byte[] data, long value)
266 for (InputType inputType : InputType.values()) { 259 throws Exception {
267 // Try different block sizes. 260 CodedInputStream input = CodedInputStream.newInstance(data);
268 for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { 261 assertEquals(value, input.readRawLittleEndian64());
269 CodedInputStream input = inputType.newDecoder(data, blockSize); 262 assertTrue(input.isAtEnd());
270 assertEquals(inputType.name(), value, input.readRawLittleEndian64()); 263
271 assertTrue(inputType.name(), input.isAtEnd()); 264 // Try different block sizes.
272 } 265 for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
266 input = CodedInputStream.newInstance(
267 new SmallBlockInputStream(data, blockSize));
268 assertEquals(value, input.readRawLittleEndian64());
269 assertTrue(input.isAtEnd());
273 } 270 }
274 } 271 }
275 272
276 /** Tests readRawLittleEndian32() and readRawLittleEndian64(). */ 273 /** Tests readRawLittleEndian32() and readRawLittleEndian64(). */
277 public void testReadLittleEndian() throws Exception { 274 public void testReadLittleEndian() throws Exception {
278 assertReadLittleEndian32(bytes(0x78, 0x56, 0x34, 0x12), 0x12345678); 275 assertReadLittleEndian32(bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
279 assertReadLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0); 276 assertReadLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
280 277
281 assertReadLittleEndian64( 278 assertReadLittleEndian64(
282 bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12), 0x123456789abcdef 0L); 279 bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
280 0x123456789abcdef0L);
283 assertReadLittleEndian64( 281 assertReadLittleEndian64(
284 bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef01234567 8L); 282 bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a),
283 0x9abcdef012345678L);
285 } 284 }
286 285
287 /** Test decodeZigZag32() and decodeZigZag64(). */ 286 /** Test decodeZigZag32() and decodeZigZag64(). */
288 public void testDecodeZigZag() throws Exception { 287 public void testDecodeZigZag() throws Exception {
289 assertEquals(0, CodedInputStream.decodeZigZag32(0)); 288 assertEquals( 0, CodedInputStream.decodeZigZag32(0));
290 assertEquals(-1, CodedInputStream.decodeZigZag32(1)); 289 assertEquals(-1, CodedInputStream.decodeZigZag32(1));
291 assertEquals(1, CodedInputStream.decodeZigZag32(2)); 290 assertEquals( 1, CodedInputStream.decodeZigZag32(2));
292 assertEquals(-2, CodedInputStream.decodeZigZag32(3)); 291 assertEquals(-2, CodedInputStream.decodeZigZag32(3));
293 assertEquals(0x3FFFFFFF, CodedInputStream.decodeZigZag32(0x7FFFFFFE)); 292 assertEquals(0x3FFFFFFF, CodedInputStream.decodeZigZag32(0x7FFFFFFE));
294 assertEquals(0xC0000000, CodedInputStream.decodeZigZag32(0x7FFFFFFF)); 293 assertEquals(0xC0000000, CodedInputStream.decodeZigZag32(0x7FFFFFFF));
295 assertEquals(0x7FFFFFFF, CodedInputStream.decodeZigZag32(0xFFFFFFFE)); 294 assertEquals(0x7FFFFFFF, CodedInputStream.decodeZigZag32(0xFFFFFFFE));
296 assertEquals(0x80000000, CodedInputStream.decodeZigZag32(0xFFFFFFFF)); 295 assertEquals(0x80000000, CodedInputStream.decodeZigZag32(0xFFFFFFFF));
297 296
298 assertEquals(0, CodedInputStream.decodeZigZag64(0)); 297 assertEquals( 0, CodedInputStream.decodeZigZag64(0));
299 assertEquals(-1, CodedInputStream.decodeZigZag64(1)); 298 assertEquals(-1, CodedInputStream.decodeZigZag64(1));
300 assertEquals(1, CodedInputStream.decodeZigZag64(2)); 299 assertEquals( 1, CodedInputStream.decodeZigZag64(2));
301 assertEquals(-2, CodedInputStream.decodeZigZag64(3)); 300 assertEquals(-2, CodedInputStream.decodeZigZag64(3));
302 assertEquals(0x000000003FFFFFFFL, CodedInputStream.decodeZigZag64(0x00000000 7FFFFFFEL)); 301 assertEquals(0x000000003FFFFFFFL,
303 assertEquals(0xFFFFFFFFC0000000L, CodedInputStream.decodeZigZag64(0x00000000 7FFFFFFFL)); 302 CodedInputStream.decodeZigZag64(0x000000007FFFFFFEL));
304 assertEquals(0x000000007FFFFFFFL, CodedInputStream.decodeZigZag64(0x00000000 FFFFFFFEL)); 303 assertEquals(0xFFFFFFFFC0000000L,
305 assertEquals(0xFFFFFFFF80000000L, CodedInputStream.decodeZigZag64(0x00000000 FFFFFFFFL)); 304 CodedInputStream.decodeZigZag64(0x000000007FFFFFFFL));
306 assertEquals(0x7FFFFFFFFFFFFFFFL, CodedInputStream.decodeZigZag64(0xFFFFFFFF FFFFFFFEL)); 305 assertEquals(0x000000007FFFFFFFL,
307 assertEquals(0x8000000000000000L, CodedInputStream.decodeZigZag64(0xFFFFFFFF FFFFFFFFL)); 306 CodedInputStream.decodeZigZag64(0x00000000FFFFFFFEL));
307 assertEquals(0xFFFFFFFF80000000L,
308 CodedInputStream.decodeZigZag64(0x00000000FFFFFFFFL));
309 assertEquals(0x7FFFFFFFFFFFFFFFL,
310 CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFEL));
311 assertEquals(0x8000000000000000L,
312 CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFFL));
308 } 313 }
309 314
310 /** Tests reading and parsing a whole message with every field type. */ 315 /** Tests reading and parsing a whole message with every field type. */
311 public void testReadWholeMessage() throws Exception { 316 public void testReadWholeMessage() throws Exception {
312 TestAllTypes message = TestUtil.getAllSet(); 317 TestAllTypes message = TestUtil.getAllSet();
313 318
314 byte[] rawBytes = message.toByteArray(); 319 byte[] rawBytes = message.toByteArray();
315 assertEquals(rawBytes.length, message.getSerializedSize()); 320 assertEquals(rawBytes.length, message.getSerializedSize());
316 321
317 for (InputType inputType : InputType.values()) { 322 TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
318 // Try different block sizes. 323 TestUtil.assertAllFieldsSet(message2);
319 for (int blockSize = 1; blockSize < 256; blockSize *= 2) { 324
320 TestAllTypes message2 = TestAllTypes.parseFrom(inputType.newDecoder(rawB ytes, blockSize)); 325 // Try different block sizes.
321 TestUtil.assertAllFieldsSet(message2); 326 for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
322 } 327 message2 = TestAllTypes.parseFrom(
328 new SmallBlockInputStream(rawBytes, blockSize));
329 TestUtil.assertAllFieldsSet(message2);
323 } 330 }
324 } 331 }
325 332
326 /** Tests skipField(). */ 333 /** Tests skipField(). */
327 public void testSkipWholeMessage() throws Exception { 334 public void testSkipWholeMessage() throws Exception {
328 TestAllTypes message = TestUtil.getAllSet(); 335 TestAllTypes message = TestUtil.getAllSet();
329 byte[] rawBytes = message.toByteArray(); 336 byte[] rawBytes = message.toByteArray();
330 337
331 InputType[] inputTypes = InputType.values(); 338 // Create two parallel inputs. Parse one as unknown fields while using
332 CodedInputStream[] inputs = new CodedInputStream[inputTypes.length]; 339 // skipField() to skip each field on the other. Expect the same tags.
333 for (int i = 0; i < inputs.length; ++i) { 340 CodedInputStream input1 = CodedInputStream.newInstance(rawBytes);
334 inputs[i] = inputTypes[i].newDecoder(rawBytes); 341 CodedInputStream input2 = CodedInputStream.newInstance(rawBytes);
335 }
336 UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder(); 342 UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder();
337 343
338 while (true) { 344 while (true) {
339 CodedInputStream input1 = inputs[0];
340 int tag = input1.readTag(); 345 int tag = input1.readTag();
341 // Ensure that the rest match. 346 assertEquals(tag, input2.readTag());
342 for (int i = 1; i < inputs.length; ++i) {
343 assertEquals(inputTypes[i].name(), tag, inputs[i].readTag());
344 }
345 if (tag == 0) { 347 if (tag == 0) {
346 break; 348 break;
347 } 349 }
348 unknownFields.mergeFieldFrom(tag, input1); 350 unknownFields.mergeFieldFrom(tag, input1);
349 // Skip the field for the rest of the inputs. 351 input2.skipField(tag);
350 for (int i = 1; i < inputs.length; ++i) {
351 inputs[i].skipField(tag);
352 }
353 } 352 }
354 } 353 }
355 354
356 355
357 /** 356 /**
358 * Test that a bug in skipRawBytes() has been fixed: if the skip skips exactly up to a limit, this 357 * Test that a bug in skipRawBytes() has been fixed: if the skip skips
359 * should not break things. 358 * exactly up to a limit, this should not break things.
360 */ 359 */
361 public void testSkipRawBytesBug() throws Exception { 360 public void testSkipRawBytesBug() throws Exception {
362 byte[] rawBytes = new byte[] {1, 2}; 361 byte[] rawBytes = new byte[] { 1, 2 };
363 for (InputType inputType : InputType.values()) { 362 CodedInputStream input = CodedInputStream.newInstance(rawBytes);
364 CodedInputStream input = inputType.newDecoder(rawBytes); 363
365 int limit = input.pushLimit(1); 364 int limit = input.pushLimit(1);
366 input.skipRawBytes(1); 365 input.skipRawBytes(1);
367 input.popLimit(limit); 366 input.popLimit(limit);
368 assertEquals(inputType.name(), 2, input.readRawByte()); 367 assertEquals(2, input.readRawByte());
369 }
370 } 368 }
371 369
372 /** 370 /**
373 * Test that a bug in skipRawBytes() has been fixed: if the skip skips past th e end of a buffer 371 * Test that a bug in skipRawBytes() has been fixed: if the skip skips
374 * with a limit that has been set past the end of that buffer, this should not break things. 372 * past the end of a buffer with a limit that has been set past the end of
373 * that buffer, this should not break things.
375 */ 374 */
376 public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception { 375 public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception {
377 byte[] rawBytes = new byte[] {1, 2, 3, 4, 5}; 376 byte[] rawBytes = new byte[] { 1, 2, 3, 4, 5 };
378 for (InputType inputType : InputType.values()) { 377 CodedInputStream input = CodedInputStream.newInstance(
379 CodedInputStream input = inputType.newDecoder(rawBytes); 378 new SmallBlockInputStream(rawBytes, 3));
380 int limit = input.pushLimit(4); 379
381 // In order to expose the bug we need to read at least one byte to prime t he 380 int limit = input.pushLimit(4);
382 // buffer inside the CodedInputStream. 381 // In order to expose the bug we need to read at least one byte to prime the
383 assertEquals(inputType.name(), 1, input.readRawByte()); 382 // buffer inside the CodedInputStream.
384 // Skip to the end of the limit. 383 assertEquals(1, input.readRawByte());
385 input.skipRawBytes(3); 384 // Skip to the end of the limit.
386 assertTrue(inputType.name(), input.isAtEnd()); 385 input.skipRawBytes(3);
387 input.popLimit(limit); 386 assertTrue(input.isAtEnd());
388 assertEquals(inputType.name(), 5, input.readRawByte()); 387 input.popLimit(limit);
389 } 388 assertEquals(5, input.readRawByte());
390 } 389 }
391 390
392 public void testReadHugeBlob() throws Exception { 391 public void testReadHugeBlob() throws Exception {
393 // Allocate and initialize a 1MB blob. 392 // Allocate and initialize a 1MB blob.
394 byte[] blob = new byte[1 << 20]; 393 byte[] blob = new byte[1 << 20];
395 for (int i = 0; i < blob.length; i++) { 394 for (int i = 0; i < blob.length; i++) {
396 blob[i] = (byte) i; 395 blob[i] = (byte) i;
397 } 396 }
398 397
399 // Make a message containing it. 398 // Make a message containing it.
400 TestAllTypes.Builder builder = TestAllTypes.newBuilder(); 399 TestAllTypes.Builder builder = TestAllTypes.newBuilder();
401 TestUtil.setAllFields(builder); 400 TestUtil.setAllFields(builder);
402 builder.setOptionalBytes(ByteString.copyFrom(blob)); 401 builder.setOptionalBytes(ByteString.copyFrom(blob));
403 TestAllTypes message = builder.build(); 402 TestAllTypes message = builder.build();
404 403
405 byte[] data = message.toByteArray(); 404 // Serialize and parse it. Make sure to parse from an InputStream, not
406 for (InputType inputType : InputType.values()) { 405 // directly from a ByteString, so that CodedInputStream uses buffered
407 // Serialize and parse it. Make sure to parse from an InputStream, not 406 // reading.
408 // directly from a ByteString, so that CodedInputStream uses buffered 407 TestAllTypes message2 =
409 // reading. 408 TestAllTypes.parseFrom(message.toByteString().newInput());
410 TestAllTypes message2 = TestAllTypes.parseFrom(inputType.newDecoder(data)) ;
411 409
412 assertEquals(inputType.name(), message.getOptionalBytes(), message2.getOpt ionalBytes()); 410 assertEquals(message.getOptionalBytes(), message2.getOptionalBytes());
413 411
414 // Make sure all the other fields were parsed correctly. 412 // Make sure all the other fields were parsed correctly.
415 TestAllTypes message3 = 413 TestAllTypes message3 = TestAllTypes.newBuilder(message2)
416 TestAllTypes.newBuilder(message2) 414 .setOptionalBytes(TestUtil.getAllSet().getOptionalBytes())
417 .setOptionalBytes(TestUtil.getAllSet().getOptionalBytes()) 415 .build();
418 .build(); 416 TestUtil.assertAllFieldsSet(message3);
419 TestUtil.assertAllFieldsSet(message3);
420 }
421 } 417 }
422 418
423 public void testReadMaliciouslyLargeBlob() throws Exception { 419 public void testReadMaliciouslyLargeBlob() throws Exception {
424 ByteString.Output rawOutput = ByteString.newOutput(); 420 ByteString.Output rawOutput = ByteString.newOutput();
425 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); 421 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
426 422
427 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); 423 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
428 output.writeRawVarint32(tag); 424 output.writeRawVarint32(tag);
429 output.writeRawVarint32(0x7FFFFFFF); 425 output.writeRawVarint32(0x7FFFFFFF);
430 output.writeRawBytes(new byte[32]); // Pad with a few random bytes. 426 output.writeRawBytes(new byte[32]); // Pad with a few random bytes.
431 output.flush(); 427 output.flush();
432 428
433 byte[] data = rawOutput.toByteString().toByteArray(); 429 CodedInputStream input = rawOutput.toByteString().newCodedInput();
434 for (InputType inputType : InputType.values()) { 430 assertEquals(tag, input.readTag());
435 CodedInputStream input = inputType.newDecoder(data); 431
436 assertEquals(tag, input.readTag()); 432 try {
437 try { 433 input.readBytes();
438 input.readBytes(); 434 fail("Should have thrown an exception!");
439 fail(inputType.name() + ": Should have thrown an exception!"); 435 } catch (InvalidProtocolBufferException e) {
440 } catch (InvalidProtocolBufferException e) { 436 // success.
441 // success.
442 }
443 } 437 }
444 } 438 }
445 439
446 /**
447 * Test we can do messages that are up to CodedInputStream#DEFAULT_SIZE_LIMIT
448 * in size (2G or Integer#MAX_SIZE).
449 * @throws IOException
450 */
451 public void testParseMessagesCloseTo2G() throws IOException {
452 byte[] serializedMessage = getBigSerializedMessage();
453 // How many of these big messages do we need to take us near our 2G limit?
454 int count = Integer.MAX_VALUE / serializedMessage.length;
455 // Now make an inputstream that will fake a near 2G message of messages
456 // returning our big serialized message 'count' times.
457 InputStream is = new RepeatingInputStream(serializedMessage, count);
458 // Parse should succeed!
459 TestAllTypes.parseFrom(is);
460 }
461
462 /**
463 * Test there is an exception if a message exceeds
464 * CodedInputStream#DEFAULT_SIZE_LIMIT in size (2G or Integer#MAX_SIZE).
465 * @throws IOException
466 */
467 public void testParseMessagesOver2G() throws IOException {
468 byte[] serializedMessage = getBigSerializedMessage();
469 // How many of these big messages do we need to take us near our 2G limit?
470 int count = Integer.MAX_VALUE / serializedMessage.length;
471 // Now add one to take us over the limit
472 count++;
473 // Now make an inputstream that will fake a near 2G message of messages
474 // returning our big serialized message 'count' times.
475 InputStream is = new RepeatingInputStream(serializedMessage, count);
476 try {
477 TestAllTypes.parseFrom(is);
478 fail("Should have thrown an exception!");
479 } catch (InvalidProtocolBufferException e) {
480 assertTrue(e.getMessage().contains("too large"));
481 }
482 }
483
484 /*
485 * @return A serialized big message.
486 */
487 private static byte[] getBigSerializedMessage() {
488 byte[] value = new byte[16 * 1024 * 1024];
489 ByteString bsValue = ByteString.wrap(value);
490 return TestAllTypes.newBuilder().setOptionalBytes(bsValue).build().toByteArr ay();
491 }
492
493 /*
494 * An input stream that repeats a byte arrays' content a number of times.
495 * Simulates really large input without consuming loads of memory. Used above
496 * to test the parsing behavior when the input size exceeds 2G or close to it.
497 */
498 private static class RepeatingInputStream extends InputStream {
499 private final byte[] serializedMessage;
500 private final int count;
501 private int index = 0;
502 private int offset = 0;
503
504 RepeatingInputStream(byte[] serializedMessage, int count) {
505 this.serializedMessage = serializedMessage;
506 this.count = count;
507 }
508
509 @Override
510 public int read() throws IOException {
511 if (this.offset == this.serializedMessage.length) {
512 this.index++;
513 this.offset = 0;
514 }
515 if (this.index == this.count) {
516 return -1;
517 }
518 return this.serializedMessage[offset++];
519 }
520 }
521
522 private TestRecursiveMessage makeRecursiveMessage(int depth) { 440 private TestRecursiveMessage makeRecursiveMessage(int depth) {
523 if (depth == 0) { 441 if (depth == 0) {
524 return TestRecursiveMessage.newBuilder().setI(5).build(); 442 return TestRecursiveMessage.newBuilder().setI(5).build();
525 } else { 443 } else {
526 return TestRecursiveMessage.newBuilder().setA(makeRecursiveMessage(depth - 1)).build(); 444 return TestRecursiveMessage.newBuilder()
445 .setA(makeRecursiveMessage(depth - 1)).build();
527 } 446 }
528 } 447 }
529 448
530 private void assertMessageDepth(String msg, TestRecursiveMessage message, int depth) { 449 private void assertMessageDepth(TestRecursiveMessage message, int depth) {
531 if (depth == 0) { 450 if (depth == 0) {
532 assertFalse(msg, message.hasA()); 451 assertFalse(message.hasA());
533 assertEquals(msg, 5, message.getI()); 452 assertEquals(5, message.getI());
534 } else { 453 } else {
535 assertTrue(msg, message.hasA()); 454 assertTrue(message.hasA());
536 assertMessageDepth(msg, message.getA(), depth - 1); 455 assertMessageDepth(message.getA(), depth - 1);
537 } 456 }
538 } 457 }
539 458
540 public void testMaliciousRecursion() throws Exception { 459 public void testMaliciousRecursion() throws Exception {
541 byte[] data100 = makeRecursiveMessage(100).toByteArray(); 460 ByteString data100 = makeRecursiveMessage(100).toByteString();
542 byte[] data101 = makeRecursiveMessage(101).toByteArray(); 461 ByteString data101 = makeRecursiveMessage(101).toByteString();
543 462
544 for (InputType inputType : InputType.values()) { 463 assertMessageDepth(TestRecursiveMessage.parseFrom(data100), 100);
545 assertMessageDepth(
546 inputType.name(), TestRecursiveMessage.parseFrom(inputType.newDecoder( data100)), 100);
547 464
548 try { 465 try {
549 TestRecursiveMessage.parseFrom(inputType.newDecoder(data101)); 466 TestRecursiveMessage.parseFrom(data101);
550 fail("Should have thrown an exception!"); 467 fail("Should have thrown an exception!");
551 } catch (InvalidProtocolBufferException e) { 468 } catch (InvalidProtocolBufferException e) {
552 // success. 469 // success.
553 } 470 }
554 471
555 CodedInputStream input = inputType.newDecoder(data100); 472 CodedInputStream input = data100.newCodedInput();
556 input.setRecursionLimit(8); 473 input.setRecursionLimit(8);
557 try { 474 try {
558 TestRecursiveMessage.parseFrom(input); 475 TestRecursiveMessage.parseFrom(input);
559 fail(inputType.name() + ": Should have thrown an exception!"); 476 fail("Should have thrown an exception!");
560 } catch (InvalidProtocolBufferException e) { 477 } catch (InvalidProtocolBufferException e) {
561 // success. 478 // success.
562 }
563 } 479 }
564 } 480 }
565 481
566 private void checkSizeLimitExceeded(InvalidProtocolBufferException e) { 482 private void checkSizeLimitExceeded(InvalidProtocolBufferException e) {
567 assertEquals(InvalidProtocolBufferException.sizeLimitExceeded().getMessage() , e.getMessage()); 483 assertEquals(
484 InvalidProtocolBufferException.sizeLimitExceeded().getMessage(),
485 e.getMessage());
568 } 486 }
569 487
570 public void testSizeLimit() throws Exception { 488 public void testSizeLimit() throws Exception {
571 // NOTE: Size limit only applies to the stream-backed CIS. 489 CodedInputStream input = CodedInputStream.newInstance(
572 CodedInputStream input = 490 new SmallBlockInputStream(
573 CodedInputStream.newInstance( 491 TestUtil.getAllSet().toByteString().newInput(), 16));
574 new SmallBlockInputStream(TestUtil.getAllSet().toByteArray(), 16));
575 input.setSizeLimit(16); 492 input.setSizeLimit(16);
576 493
577 try { 494 try {
578 TestAllTypes.parseFrom(input); 495 TestAllTypes.parseFrom(input);
579 fail("Should have thrown an exception!"); 496 fail("Should have thrown an exception!");
580 } catch (InvalidProtocolBufferException expected) { 497 } catch (InvalidProtocolBufferException expected) {
581 checkSizeLimitExceeded(expected); 498 checkSizeLimitExceeded(expected);
582 } 499 }
583 } 500 }
584 501
585 public void testResetSizeCounter() throws Exception { 502 public void testResetSizeCounter() throws Exception {
586 // NOTE: Size limit only applies to the stream-backed CIS. 503 CodedInputStream input = CodedInputStream.newInstance(
587 CodedInputStream input = 504 new SmallBlockInputStream(new byte[256], 8));
588 CodedInputStream.newInstance(new SmallBlockInputStream(new byte[256], 8) );
589 input.setSizeLimit(16); 505 input.setSizeLimit(16);
590 input.readRawBytes(16); 506 input.readRawBytes(16);
591 assertEquals(16, input.getTotalBytesRead()); 507 assertEquals(16, input.getTotalBytesRead());
592 508
593 try { 509 try {
594 input.readRawByte(); 510 input.readRawByte();
595 fail("Should have thrown an exception!"); 511 fail("Should have thrown an exception!");
596 } catch (InvalidProtocolBufferException expected) { 512 } catch (InvalidProtocolBufferException expected) {
597 checkSizeLimitExceeded(expected); 513 checkSizeLimitExceeded(expected);
598 } 514 }
599 515
600 input.resetSizeCounter(); 516 input.resetSizeCounter();
601 assertEquals(0, input.getTotalBytesRead()); 517 assertEquals(0, input.getTotalBytesRead());
602 input.readRawByte(); // No exception thrown. 518 input.readRawByte(); // No exception thrown.
603 input.resetSizeCounter(); 519 input.resetSizeCounter();
604 assertEquals(0, input.getTotalBytesRead()); 520 assertEquals(0, input.getTotalBytesRead());
605 input.readRawBytes(16); 521 input.readRawBytes(16);
606 assertEquals(16, input.getTotalBytesRead()); 522 assertEquals(16, input.getTotalBytesRead());
607 input.resetSizeCounter(); 523 input.resetSizeCounter();
608 524
609 try { 525 try {
610 input.readRawBytes(17); // Hits limit again. 526 input.readRawBytes(17); // Hits limit again.
611 fail("Should have thrown an exception!"); 527 fail("Should have thrown an exception!");
612 } catch (InvalidProtocolBufferException expected) { 528 } catch (InvalidProtocolBufferException expected) {
613 checkSizeLimitExceeded(expected); 529 checkSizeLimitExceeded(expected);
614 } 530 }
615 } 531 }
616 532
617 public void testSizeLimitMultipleMessages() throws Exception { 533 public void testSizeLimitMultipleMessages() throws Exception {
618 // NOTE: Size limit only applies to the stream-backed CIS.
619 byte[] bytes = new byte[256]; 534 byte[] bytes = new byte[256];
620 for (int i = 0; i < bytes.length; i++) { 535 for (int i = 0; i < bytes.length; i++) {
621 bytes[i] = (byte) i; 536 bytes[i] = (byte) i;
622 } 537 }
623 CodedInputStream input = CodedInputStream.newInstance(new SmallBlockInputStr eam(bytes, 7)); 538 CodedInputStream input = CodedInputStream.newInstance(
539 new SmallBlockInputStream(bytes, 7));
624 input.setSizeLimit(16); 540 input.setSizeLimit(16);
625 for (int i = 0; i < 256 / 16; i++) { 541 for (int i = 0; i < 256 / 16; i++) {
626 byte[] message = input.readRawBytes(16); 542 byte[] message = input.readRawBytes(16);
627 for (int j = 0; j < message.length; j++) { 543 for (int j = 0; j < message.length; j++) {
628 assertEquals(i * 16 + j, message[j] & 0xff); 544 assertEquals(i * 16 + j, message[j] & 0xff);
629 } 545 }
630 assertEquals(16, input.getTotalBytesRead()); 546 assertEquals(16, input.getTotalBytesRead());
631 input.resetSizeCounter(); 547 input.resetSizeCounter();
632 assertEquals(0, input.getTotalBytesRead()); 548 assertEquals(0, input.getTotalBytesRead());
633 } 549 }
634 } 550 }
635 551
636 public void testReadString() throws Exception { 552 public void testReadString() throws Exception {
637 String lorem = "Lorem ipsum dolor sit amet "; 553 String lorem = "Lorem ipsum dolor sit amet ";
638 StringBuilder builder = new StringBuilder(); 554 StringBuilder builder = new StringBuilder();
639 for (int i = 0; i < 4096; i += lorem.length()) { 555 for (int i = 0; i < 4096; i += lorem.length()) {
640 builder.append(lorem); 556 builder.append(lorem);
641 } 557 }
642 lorem = builder.toString().substring(0, 4096); 558 lorem = builder.toString().substring(0, 4096);
643 byte[] bytes = lorem.getBytes("UTF-8"); 559 byte[] bytes = lorem.getBytes("UTF-8");
644 ByteString.Output rawOutput = ByteString.newOutput(); 560 ByteString.Output rawOutput = ByteString.newOutput();
645 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.le ngth); 561 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.le ngth);
646 562
647 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); 563 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
648 output.writeRawVarint32(tag); 564 output.writeRawVarint32(tag);
649 output.writeRawVarint32(bytes.length); 565 output.writeRawVarint32(bytes.length);
650 output.writeRawBytes(bytes); 566 output.writeRawBytes(bytes);
651 output.flush(); 567 output.flush();
652 568
653 byte[] rawInput = rawOutput.toByteString().toByteArray(); 569 CodedInputStream input =
654 for (InputType inputType : InputType.values()) { 570 CodedInputStream.newInstance(
655 CodedInputStream input = inputType.newDecoder(rawInput); 571 new ByteArrayInputStream(rawOutput.toByteString().toByteArray()));
656 assertEquals(inputType.name(), tag, input.readTag()); 572 assertEquals(tag, input.readTag());
657 String text = input.readString(); 573 String text = input.readString();
658 assertEquals(inputType.name(), lorem, text); 574 assertEquals(lorem, text);
659 }
660 } 575 }
661 576
662 public void testReadStringRequireUtf8() throws Exception { 577 public void testReadStringRequireUtf8() throws Exception {
663 String lorem = "Lorem ipsum dolor sit amet "; 578 String lorem = "Lorem ipsum dolor sit amet ";
664 StringBuilder builder = new StringBuilder(); 579 StringBuilder builder = new StringBuilder();
665 for (int i = 0; i < 4096; i += lorem.length()) { 580 for (int i = 0; i < 4096; i += lorem.length()) {
666 builder.append(lorem); 581 builder.append(lorem);
667 } 582 }
668 lorem = builder.toString().substring(0, 4096); 583 lorem = builder.toString().substring(0, 4096);
669 byte[] bytes = lorem.getBytes("UTF-8"); 584 byte[] bytes = lorem.getBytes("UTF-8");
670 ByteString.Output rawOutput = ByteString.newOutput(); 585 ByteString.Output rawOutput = ByteString.newOutput();
671 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.le ngth); 586 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.le ngth);
672 587
673 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); 588 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
674 output.writeRawVarint32(tag); 589 output.writeRawVarint32(tag);
675 output.writeRawVarint32(bytes.length); 590 output.writeRawVarint32(bytes.length);
676 output.writeRawBytes(bytes); 591 output.writeRawBytes(bytes);
677 output.flush(); 592 output.flush();
678 593
679 byte[] rawInput = rawOutput.toByteString().toByteArray(); 594 CodedInputStream input =
680 for (InputType inputType : InputType.values()) { 595 CodedInputStream.newInstance(
681 CodedInputStream input = inputType.newDecoder(rawInput); 596 new ByteArrayInputStream(rawOutput.toByteString().toByteArray()));
682 assertEquals(inputType.name(), tag, input.readTag()); 597 assertEquals(tag, input.readTag());
683 String text = input.readStringRequireUtf8(); 598 String text = input.readStringRequireUtf8();
684 assertEquals(inputType.name(), lorem, text); 599 assertEquals(lorem, text);
685 }
686 } 600 }
687 601
688 /** 602 /**
689 * Tests that if we readString invalid UTF-8 bytes, no exception is thrown. In stead, the invalid 603 * Tests that if we readString invalid UTF-8 bytes, no exception
690 * bytes are replaced with the Unicode "replacement character" U+FFFD. 604 * is thrown. Instead, the invalid bytes are replaced with the Unicode
605 * "replacement character" U+FFFD.
691 */ 606 */
692 public void testReadStringInvalidUtf8() throws Exception { 607 public void testReadStringInvalidUtf8() throws Exception {
693 ByteString.Output rawOutput = ByteString.newOutput(); 608 ByteString.Output rawOutput = ByteString.newOutput();
694 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); 609 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
695 610
696 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); 611 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
697 output.writeRawVarint32(tag); 612 output.writeRawVarint32(tag);
698 output.writeRawVarint32(1); 613 output.writeRawVarint32(1);
699 output.writeRawBytes(new byte[] {(byte) 0x80}); 614 output.writeRawBytes(new byte[] { (byte) 0x80 });
700 output.flush(); 615 output.flush();
701 616
702 byte[] rawInput = rawOutput.toByteString().toByteArray(); 617 CodedInputStream input = rawOutput.toByteString().newCodedInput();
703 for (InputType inputType : InputType.values()) { 618 assertEquals(tag, input.readTag());
704 CodedInputStream input = inputType.newDecoder(rawInput); 619 String text = input.readString();
705 assertEquals(inputType.name(), tag, input.readTag()); 620 assertEquals(0xfffd, text.charAt(0));
706 String text = input.readString();
707 assertEquals(inputType.name(), 0xfffd, text.charAt(0));
708 }
709 } 621 }
710 622
711 /** 623 /**
712 * Tests that if we readStringRequireUtf8 invalid UTF-8 bytes, an InvalidProto colBufferException 624 * Tests that if we readStringRequireUtf8 invalid UTF-8 bytes, an
713 * is thrown. 625 * InvalidProtocolBufferException is thrown.
714 */ 626 */
715 public void testReadStringRequireUtf8InvalidUtf8() throws Exception { 627 public void testReadStringRequireUtf8InvalidUtf8() throws Exception {
716 ByteString.Output rawOutput = ByteString.newOutput(); 628 ByteString.Output rawOutput = ByteString.newOutput();
717 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); 629 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
718 630
719 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); 631 int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
720 output.writeRawVarint32(tag); 632 output.writeRawVarint32(tag);
721 output.writeRawVarint32(1); 633 output.writeRawVarint32(1);
722 output.writeRawBytes(new byte[] {(byte) 0x80}); 634 output.writeRawBytes(new byte[] { (byte) 0x80 });
723 output.flush(); 635 output.flush();
724 636
725 byte[] rawInput = rawOutput.toByteString().toByteArray(); 637 CodedInputStream input = rawOutput.toByteString().newCodedInput();
726 for (InputType inputType : InputType.values()) { 638 assertEquals(tag, input.readTag());
727 CodedInputStream input = inputType.newDecoder(rawInput); 639 try {
728 assertEquals(tag, input.readTag()); 640 input.readStringRequireUtf8();
729 try { 641 fail("Expected invalid UTF-8 exception.");
730 input.readStringRequireUtf8(); 642 } catch (InvalidProtocolBufferException exception) {
731 fail(inputType.name() + ": Expected invalid UTF-8 exception."); 643 assertEquals("Protocol message had invalid UTF-8.", exception.getMessage() );
732 } catch (InvalidProtocolBufferException exception) {
733 assertEquals(
734 inputType.name(), "Protocol message had invalid UTF-8.", exception.g etMessage());
735 }
736 } 644 }
737 } 645 }
738 646
739 public void testReadFromSlice() throws Exception { 647 public void testReadFromSlice() throws Exception {
740 byte[] bytes = bytes(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); 648 byte[] bytes = bytes(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
741 CodedInputStream in = CodedInputStream.newInstance(bytes, 3, 5); 649 CodedInputStream in = CodedInputStream.newInstance(bytes, 3, 5);
742 assertEquals(0, in.getTotalBytesRead()); 650 assertEquals(0, in.getTotalBytesRead());
743 for (int i = 3; i < 8; i++) { 651 for (int i = 3; i < 8; i++) {
744 assertEquals(i, in.readRawByte()); 652 assertEquals(i, in.readRawByte());
745 assertEquals(i - 2, in.getTotalBytesRead()); 653 assertEquals(i - 2, in.getTotalBytesRead());
746 } 654 }
747 // eof 655 // eof
748 assertEquals(0, in.readTag()); 656 assertEquals(0, in.readTag());
749 assertEquals(5, in.getTotalBytesRead()); 657 assertEquals(5, in.getTotalBytesRead());
750 } 658 }
751 659
752 public void testInvalidTag() throws Exception { 660 public void testInvalidTag() throws Exception {
753 // Any tag number which corresponds to field number zero is invalid and 661 // Any tag number which corresponds to field number zero is invalid and
754 // should throw InvalidProtocolBufferException. 662 // should throw InvalidProtocolBufferException.
755 for (InputType inputType : InputType.values()) { 663 for (int i = 0; i < 8; i++) {
756 for (int i = 0; i < 8; i++) { 664 try {
757 try { 665 CodedInputStream.newInstance(bytes(i)).readTag();
758 inputType.newDecoder(bytes(i)).readTag(); 666 fail("Should have thrown an exception.");
759 fail(inputType.name() + ": Should have thrown an exception."); 667 } catch (InvalidProtocolBufferException e) {
760 } catch (InvalidProtocolBufferException e) { 668 assertEquals(InvalidProtocolBufferException.invalidTag().getMessage(),
761 assertEquals( 669 e.getMessage());
762 inputType.name(),
763 InvalidProtocolBufferException.invalidTag().getMessage(),
764 e.getMessage());
765 }
766 } 670 }
767 } 671 }
768 } 672 }
769 673
770 public void testReadByteArray() throws Exception { 674 public void testReadByteArray() throws Exception {
771 ByteString.Output rawOutput = ByteString.newOutput(); 675 ByteString.Output rawOutput = ByteString.newOutput();
772 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); 676 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
773 // Zero-sized bytes field. 677 // Zero-sized bytes field.
774 output.writeRawVarint32(0); 678 output.writeRawVarint32(0);
775 // One one-byte bytes field 679 // One one-byte bytes field
776 output.writeRawVarint32(1); 680 output.writeRawVarint32(1);
777 output.writeRawBytes(new byte[] {(byte) 23}); 681 output.writeRawBytes(new byte[] { (byte) 23 });
778 // Another one-byte bytes field 682 // Another one-byte bytes field
779 output.writeRawVarint32(1); 683 output.writeRawVarint32(1);
780 output.writeRawBytes(new byte[] {(byte) 45}); 684 output.writeRawBytes(new byte[] { (byte) 45 });
781 // A bytes field large enough that won't fit into the 4K buffer. 685 // A bytes field large enough that won't fit into the 4K buffer.
782 final int bytesLength = 16 * 1024; 686 final int bytesLength = 16 * 1024;
783 byte[] bytes = new byte[bytesLength]; 687 byte[] bytes = new byte[bytesLength];
784 bytes[0] = (byte) 67; 688 bytes[0] = (byte) 67;
785 bytes[bytesLength - 1] = (byte) 89; 689 bytes[bytesLength - 1] = (byte) 89;
786 output.writeRawVarint32(bytesLength); 690 output.writeRawVarint32(bytesLength);
787 output.writeRawBytes(bytes); 691 output.writeRawBytes(bytes);
788 692
789 output.flush(); 693 output.flush();
694 CodedInputStream inputStream = rawOutput.toByteString().newCodedInput();
790 695
791 byte[] rawInput = rawOutput.toByteString().toByteArray(); 696 byte[] result = inputStream.readByteArray();
792 for (InputType inputType : InputType.values()) { 697 assertEquals(0, result.length);
793 CodedInputStream inputStream = inputType.newDecoder(rawInput); 698 result = inputStream.readByteArray();
794 699 assertEquals(1, result.length);
795 byte[] result = inputStream.readByteArray(); 700 assertEquals((byte) 23, result[0]);
796 assertEquals(inputType.name(), 0, result.length); 701 result = inputStream.readByteArray();
797 result = inputStream.readByteArray(); 702 assertEquals(1, result.length);
798 assertEquals(inputType.name(), 1, result.length); 703 assertEquals((byte) 45, result[0]);
799 assertEquals(inputType.name(), (byte) 23, result[0]); 704 result = inputStream.readByteArray();
800 result = inputStream.readByteArray(); 705 assertEquals(bytesLength, result.length);
801 assertEquals(inputType.name(), 1, result.length); 706 assertEquals((byte) 67, result[0]);
802 assertEquals(inputType.name(), (byte) 45, result[0]); 707 assertEquals((byte) 89, result[bytesLength - 1]);
803 result = inputStream.readByteArray();
804 assertEquals(inputType.name(), bytesLength, result.length);
805 assertEquals(inputType.name(), (byte) 67, result[0]);
806 assertEquals(inputType.name(), (byte) 89, result[bytesLength - 1]);
807 }
808 } 708 }
809 709
810 public void testReadByteBuffer() throws Exception { 710 public void testReadByteBuffer() throws Exception {
811 ByteString.Output rawOutput = ByteString.newOutput(); 711 ByteString.Output rawOutput = ByteString.newOutput();
812 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); 712 CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
813 // Zero-sized bytes field. 713 // Zero-sized bytes field.
814 output.writeRawVarint32(0); 714 output.writeRawVarint32(0);
815 // One one-byte bytes field 715 // One one-byte bytes field
816 output.writeRawVarint32(1); 716 output.writeRawVarint32(1);
817 output.writeRawBytes(new byte[] {(byte) 23}); 717 output.writeRawBytes(new byte[]{(byte) 23});
818 // Another one-byte bytes field 718 // Another one-byte bytes field
819 output.writeRawVarint32(1); 719 output.writeRawVarint32(1);
820 output.writeRawBytes(new byte[] {(byte) 45}); 720 output.writeRawBytes(new byte[]{(byte) 45});
821 // A bytes field large enough that won't fit into the 4K buffer. 721 // A bytes field large enough that won't fit into the 4K buffer.
822 final int bytesLength = 16 * 1024; 722 final int bytesLength = 16 * 1024;
823 byte[] bytes = new byte[bytesLength]; 723 byte[] bytes = new byte[bytesLength];
824 bytes[0] = (byte) 67; 724 bytes[0] = (byte) 67;
825 bytes[bytesLength - 1] = (byte) 89; 725 bytes[bytesLength - 1] = (byte) 89;
826 output.writeRawVarint32(bytesLength); 726 output.writeRawVarint32(bytesLength);
827 output.writeRawBytes(bytes); 727 output.writeRawBytes(bytes);
828 728
829 output.flush(); 729 output.flush();
730 CodedInputStream inputStream = rawOutput.toByteString().newCodedInput();
830 731
831 byte[] rawInput = rawOutput.toByteString().toByteArray(); 732 ByteBuffer result = inputStream.readByteBuffer();
832 for (InputType inputType : InputType.values()) { 733 assertEquals(0, result.capacity());
833 CodedInputStream inputStream = inputType.newDecoder(rawInput); 734 result = inputStream.readByteBuffer();
834 735 assertEquals(1, result.capacity());
835 ByteBuffer result = inputStream.readByteBuffer(); 736 assertEquals((byte) 23, result.get());
836 assertEquals(inputType.name(), 0, result.capacity()); 737 result = inputStream.readByteBuffer();
837 result = inputStream.readByteBuffer(); 738 assertEquals(1, result.capacity());
838 assertEquals(inputType.name(), 1, result.capacity()); 739 assertEquals((byte) 45, result.get());
839 assertEquals(inputType.name(), (byte) 23, result.get()); 740 result = inputStream.readByteBuffer();
840 result = inputStream.readByteBuffer(); 741 assertEquals(bytesLength, result.capacity());
841 assertEquals(inputType.name(), 1, result.capacity()); 742 assertEquals((byte) 67, result.get());
842 assertEquals(inputType.name(), (byte) 45, result.get()); 743 result.position(bytesLength - 1);
843 result = inputStream.readByteBuffer(); 744 assertEquals((byte) 89, result.get());
844 assertEquals(inputType.name(), bytesLength, result.capacity());
845 assertEquals(inputType.name(), (byte) 67, result.get());
846 result.position(bytesLength - 1);
847 assertEquals(inputType.name(), (byte) 89, result.get());
848 }
849 } 745 }
850 746
851 public void testReadByteBufferAliasing() throws Exception { 747 public void testReadByteBufferAliasing() throws Exception {
852 ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream(); 748 ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
853 CodedOutputStream output = CodedOutputStream.newInstance(byteArrayStream); 749 CodedOutputStream output = CodedOutputStream.newInstance(byteArrayStream);
854 // Zero-sized bytes field. 750 // Zero-sized bytes field.
855 output.writeRawVarint32(0); 751 output.writeRawVarint32(0);
856 // One one-byte bytes field 752 // One one-byte bytes field
857 output.writeRawVarint32(1); 753 output.writeRawVarint32(1);
858 output.writeRawBytes(new byte[] {(byte) 23}); 754 output.writeRawBytes(new byte[]{(byte) 23});
859 // Another one-byte bytes field 755 // Another one-byte bytes field
860 output.writeRawVarint32(1); 756 output.writeRawVarint32(1);
861 output.writeRawBytes(new byte[] {(byte) 45}); 757 output.writeRawBytes(new byte[]{(byte) 45});
862 // A bytes field large enough that won't fit into the 4K buffer. 758 // A bytes field large enough that won't fit into the 4K buffer.
863 final int bytesLength = 16 * 1024; 759 final int bytesLength = 16 * 1024;
864 byte[] bytes = new byte[bytesLength]; 760 byte[] bytes = new byte[bytesLength];
865 bytes[0] = (byte) 67; 761 bytes[0] = (byte) 67;
866 bytes[bytesLength - 1] = (byte) 89; 762 bytes[bytesLength - 1] = (byte) 89;
867 output.writeRawVarint32(bytesLength); 763 output.writeRawVarint32(bytesLength);
868 output.writeRawBytes(bytes); 764 output.writeRawBytes(bytes);
869 output.flush(); 765 output.flush();
870
871 byte[] data = byteArrayStream.toByteArray(); 766 byte[] data = byteArrayStream.toByteArray();
872 767
873 for (InputType inputType : InputType.values()) { 768 // Without aliasing
874 if (inputType == InputType.STREAM) { 769 CodedInputStream inputStream = CodedInputStream.newInstance(data);
875 // Aliasing doesn't apply to stream-backed CIS. 770 ByteBuffer result = inputStream.readByteBuffer();
876 continue; 771 assertEquals(0, result.capacity());
877 } 772 result = inputStream.readByteBuffer();
773 assertTrue(result.array() != data);
774 assertEquals(1, result.capacity());
775 assertEquals((byte) 23, result.get());
776 result = inputStream.readByteBuffer();
777 assertTrue(result.array() != data);
778 assertEquals(1, result.capacity());
779 assertEquals((byte) 45, result.get());
780 result = inputStream.readByteBuffer();
781 assertTrue(result.array() != data);
782 assertEquals(bytesLength, result.capacity());
783 assertEquals((byte) 67, result.get());
784 result.position(bytesLength - 1);
785 assertEquals((byte) 89, result.get());
878 786
879 // Without aliasing 787 // Enable aliasing
880 CodedInputStream inputStream = inputType.newDecoder(data); 788 inputStream = CodedInputStream.newInstance(data);
881 ByteBuffer result = inputStream.readByteBuffer(); 789 inputStream.enableAliasing(true);
882 assertEquals(inputType.name(), 0, result.capacity()); 790 result = inputStream.readByteBuffer();
883 result = inputStream.readByteBuffer(); 791 assertEquals(0, result.capacity());
884 assertTrue(inputType.name(), result.array() != data); 792 result = inputStream.readByteBuffer();
885 assertEquals(inputType.name(), 1, result.capacity()); 793 assertTrue(result.array() == data);
886 assertEquals(inputType.name(), (byte) 23, result.get()); 794 assertEquals(1, result.capacity());
887 result = inputStream.readByteBuffer(); 795 assertEquals((byte) 23, result.get());
888 assertTrue(inputType.name(), result.array() != data); 796 result = inputStream.readByteBuffer();
889 assertEquals(inputType.name(), 1, result.capacity()); 797 assertTrue(result.array() == data);
890 assertEquals(inputType.name(), (byte) 45, result.get()); 798 assertEquals(1, result.capacity());
891 result = inputStream.readByteBuffer(); 799 assertEquals((byte) 45, result.get());
892 assertTrue(inputType.name(), result.array() != data); 800 result = inputStream.readByteBuffer();
893 assertEquals(inputType.name(), bytesLength, result.capacity()); 801 assertTrue(result.array() == data);
894 assertEquals(inputType.name(), (byte) 67, result.get()); 802 assertEquals(bytesLength, result.capacity());
895 result.position(bytesLength - 1); 803 assertEquals((byte) 67, result.get());
896 assertEquals(inputType.name(), (byte) 89, result.get()); 804 result.position(bytesLength - 1);
897 805 assertEquals((byte) 89, result.get());
898 // Enable aliasing
899 inputStream = inputType.newDecoder(data);
900 inputStream.enableAliasing(true);
901 result = inputStream.readByteBuffer();
902 assertEquals(inputType.name(), 0, result.capacity());
903 result = inputStream.readByteBuffer();
904 if (result.hasArray()) {
905 assertTrue(inputType.name(), result.array() == data);
906 }
907 assertEquals(inputType.name(), 1, result.capacity());
908 assertEquals(inputType.name(), (byte) 23, result.get());
909 result = inputStream.readByteBuffer();
910 if (result.hasArray()) {
911 assertTrue(inputType.name(), result.array() == data);
912 }
913 assertEquals(inputType.name(), 1, result.capacity());
914 assertEquals(inputType.name(), (byte) 45, result.get());
915 result = inputStream.readByteBuffer();
916 if (result.hasArray()) {
917 assertTrue(inputType.name(), result.array() == data);
918 }
919 assertEquals(inputType.name(), bytesLength, result.capacity());
920 assertEquals(inputType.name(), (byte) 67, result.get());
921 result.position(bytesLength - 1);
922 assertEquals(inputType.name(), (byte) 89, result.get());
923 }
924 } 806 }
925 807
926 public void testCompatibleTypes() throws Exception { 808 public void testCompatibleTypes() throws Exception {
927 long data = 0x100000000L; 809 long data = 0x100000000L;
928 Int64Message message = Int64Message.newBuilder().setData(data).build(); 810 Int64Message message = Int64Message.newBuilder().setData(data).build();
929 byte[] serialized = message.toByteArray(); 811 ByteString serialized = message.toByteString();
930 for (InputType inputType : InputType.values()) {
931 CodedInputStream inputStream = inputType.newDecoder(serialized);
932 812
933 // Test int64(long) is compatible with bool(boolean) 813 // Test int64(long) is compatible with bool(boolean)
934 BoolMessage msg2 = BoolMessage.parseFrom(inputStream); 814 BoolMessage msg2 = BoolMessage.parseFrom(serialized);
935 assertTrue(msg2.getData()); 815 assertTrue(msg2.getData());
936 816
937 // Test int64(long) is compatible with int32(int) 817 // Test int64(long) is compatible with int32(int)
938 inputStream = inputType.newDecoder(serialized); 818 Int32Message msg3 = Int32Message.parseFrom(serialized);
939 Int32Message msg3 = Int32Message.parseFrom(inputStream); 819 assertEquals((int) data, msg3.getData());
940 assertEquals((int) data, msg3.getData());
941 }
942 }
943
944 public void testSkipInvalidVarint_FastPath() throws Exception {
945 // Fast path: We have >= 10 bytes available. Ensure we properly recognize a non-ending varint.
946 byte[] data = new byte[] {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0};
947 for (InputType inputType : InputType.values()) {
948 try {
949 CodedInputStream input = inputType.newDecoder(data);
950 input.skipField(WireFormat.makeTag(1, WireFormat.WIRETYPE_VARINT));
951 fail(inputType.name() + ": Should have thrown an exception.");
952 } catch (InvalidProtocolBufferException e) {
953 // Expected
954 }
955 }
956 }
957
958 public void testSkipInvalidVarint_SlowPath() throws Exception {
959 // Slow path: < 10 bytes available. Ensure we properly recognize a non-endin g varint.
960 byte[] data = new byte[] {-1, -1, -1, -1, -1, -1, -1, -1, -1};
961 for (InputType inputType : InputType.values()) {
962 try {
963 CodedInputStream input = inputType.newDecoder(data);
964 input.skipField(WireFormat.makeTag(1, WireFormat.WIRETYPE_VARINT));
965 fail(inputType.name() + ": Should have thrown an exception.");
966 } catch (InvalidProtocolBufferException e) {
967 // Expected
968 }
969 }
970 } 820 }
971 } 821 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698