blob: 3155b3a4cae89b5afbf78d4af70038b08a141c84 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/* @test
25 * @bug 4450867
26 * @summary Although technically the behavior of ObjectInputStream following a
27 * UTFDataFormatException is unspecified, verify that
28 * ObjectInputStream consumes at most the expected number of utf
29 * bytes, even if the last byte(s) of the utf string indicate that the
30 * string overflows its expected length.
31 */
32
33import java.io.*;
34import java.util.Random;
35
36public class CorruptedUTFConsumption {
37
38 static Random rand = new Random(System.currentTimeMillis());
39
40 public static void main(String[] args) throws Exception {
41 StringBuffer sbuf = new StringBuffer();
42 ByteArrayOutputStream bout = new ByteArrayOutputStream();
43 DataOutputStream dout = new DataOutputStream(bout);
44
45 for (int i = 0; i < 1200; i++) {
46 sbuf.append(i % 10);
47 bout.reset();
48 dout.writeUTF(sbuf.toString());
49 byte[] utf = bout.toByteArray();
50
51 // set last byte to first byte of 2-char sequence
52 utf[utf.length - 1] = (byte) (0xC0 | rand.nextInt() & 0x1F);
53 checkConsume(utf);
54
55 // set last byte to first byte of 3-char sequence
56 utf[utf.length - 1] = (byte) (0xE0 | rand.nextInt() & 0x0F);
57 checkConsume(utf);
58
59 if (utf.length >= 4) { // don't touch utf length bytes
60 // set last 2 bytes to first, second byte of 3-char sequence
61 utf[utf.length - 2] = (byte) (0xE0 | rand.nextInt() & 0x0F);
62 utf[utf.length - 1] = (byte) (0x80 | rand.nextInt() & 0x3F);
63 checkConsume(utf);
64 }
65 }
66 }
67
68 static void checkConsume(byte[] utf) throws Exception {
69 ByteArrayOutputStream bout = new ByteArrayOutputStream();
70 ObjectOutputStream oout = new ObjectOutputStream(bout);
71 oout.write(utf);
72 oout.writeByte(0); // leave one byte of padding
73 oout.close();
74 ObjectInputStream oin = new ObjectInputStream(
75 new ByteArrayInputStream(bout.toByteArray()));
76 try {
77 oin.readUTF();
78 throw new Error();
79 } catch (UTFDataFormatException ex) {
80 }
81 // if readUTF consumed padding byte, readByte will throw EOFException
82 oin.readByte();
83 }
84}