diff options
author | Ito Kazumitsu <kaz@maczuka.gcd.org> | 2008-01-29 22:30:42 +0000 |
---|---|---|
committer | Ito Kazumitsu <kaz@maczuka.gcd.org> | 2008-01-29 22:30:42 +0000 |
commit | 1745554bbb5117a3bb9fbe3d90db73b112aa5ca4 (patch) | |
tree | 534743cdad2c703b551a7a5c3452eb0e3b941074 | |
parent | b3891c2b5980abfc7532ff9ef46e3539caab6cd2 (diff) | |
download | classpath-1745554bbb5117a3bb9fbe3d90db73b112aa5ca4.tar.gz |
2008-01-29 Ito Kazumitsu <kaz@maczuka.gcd.org>
Fixes bug #22941
* java/io/DataInputStream.java(readUTFLong): New method.
(readUTF): New private method.
* java/io/DataOutputStream.java(getUTFlength): Made package-private,
Return type changed to long.
(writeUTF): Use the new method writeUTFShort.
(writeUTFShort): New package-private method.
(writeUTFLong): New package-private method.
(writeUTFBytes): New private method.
* java/io/ObjectInputStream.java(parseContent): Separate the
handling of TC_LONGSTRING from TC_STRING.
* java/io/ObjectOutputStream.java(writeObject): When to write a
String, use writeUTFShort or writeUTFLong depending on the byte length.
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | java/io/DataInputStream.java | 50 | ||||
-rw-r--r-- | java/io/DataOutputStream.java | 84 | ||||
-rw-r--r-- | java/io/ObjectInputStream.java | 13 | ||||
-rw-r--r-- | java/io/ObjectOutputStream.java | 22 |
5 files changed, 158 insertions, 27 deletions
@@ -1,3 +1,19 @@ +2008-01-29 Ito Kazumitsu <kaz@maczuka.gcd.org> + + Fixes bug #22941 + * java/io/DataInputStream.java(readUTFLong): New method. + (readUTF): New private method. + * java/io/DataOutputStream.java(getUTFlength): Made package-private, + Return type changed to long. + (writeUTF): Use the new method writeUTFShort. + (writeUTFShort): New package-private method. + (writeUTFLong): New package-private method. + (writeUTFBytes): New private method. + * java/io/ObjectInputStream.java(parseContent): Separate the + handling of TC_LONGSTRING from TC_STRING. + * java/io/ObjectOutputStream.java(writeObject): When to write a + String, use writeUTFShort or writeUTFLong depending on the byte length. + 2008-01-27 Bernhard Fischer <rep.dot.nop@gmail.com> * java/util/SimpleTimeZone.java (SimpleTimeZone): Fix typo in comment. diff --git a/java/io/DataInputStream.java b/java/io/DataInputStream.java index d2604b51f..8b223ea84 100644 --- a/java/io/DataInputStream.java +++ b/java/io/DataInputStream.java @@ -1,5 +1,6 @@ /* DataInputStream.java -- FilteredInputStream that implements DataInput - Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation + Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2008 + Free Software Foundation This file is part of GNU Classpath. @@ -590,13 +591,56 @@ public class DataInputStream extends FilterInputStream implements DataInput public static final String readUTF(DataInput in) throws IOException { final int UTFlen = in.readUnsignedShort (); - byte[] buf = new byte [UTFlen]; + + return readUTF(in, UTFlen); + } + + /** + * This method is similar to <code>readUTF</code>, but the + * UTF-8 byte length is in 64 bits. + * This method is not public. It is used by <code>ObjectInputStream</code>. + * + * @return The <code>String</code> read + * + * @exception EOFException If end of file is reached before reading + * the String + * @exception UTFDataFormatException If the data is not in UTF-8 format + * @exception IOException If any other error occurs + * + * @see DataOutput#writeUTFLong + */ + final String readUTFLong () throws IOException + { + long l = readLong (); + if (l > Integer.MAX_VALUE) + throw new IOException("The string length > Integer.MAX_VALUE"); + final int UTFlen = (int)l; + return readUTF (this, UTFlen); + } + + /** + * This method performs the main task of <code>readUTF</code> and + * <code>readUTFLong</code>. + * + * @param in The <code>DataInput</code> source to read from + * + * @param len The UTF-8 byte length of the String to be read + * + * @return The String read from the source + * + * @exception IOException If an error occurs + * + * @see DataInput#readUTF + */ + private static final String readUTF(DataInput in, int len) throws IOException + { + byte[] buf = new byte [len]; // This blocks until the entire string is available rather than // doing partial processing on the bytes that are available and then // blocking. An advantage of the latter is that Exceptions // could be thrown earlier. The former is a bit cleaner. - in.readFully (buf, 0, UTFlen); + in.readFully (buf, 0, len); return convertFromUTF (buf); } diff --git a/java/io/DataOutputStream.java b/java/io/DataOutputStream.java index 6670c2dba..435ff76d1 100644 --- a/java/io/DataOutputStream.java +++ b/java/io/DataOutputStream.java @@ -1,5 +1,5 @@ /* DataOutputStream.java -- Writes primitive Java datatypes to streams - Copyright (C) 1998, 2001, 2003, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 2001, 2003, 2005, 2008 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -379,19 +379,20 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput /** * Calculate the length, in bytes, of a <code>String</code> in Utf8 format. + * This method is package-private so that <code>ObjectOutputStream</code> + * may use it. The return type is long so that a long string whose + * Utf8 byte count is 64 bit long may be handled. * * @param value The <code>String</code> to measure * @param start String index at which to begin count * @param sum Starting Utf8 byte count * - * @throws UTFDataFormatException if result would exceed 65535 */ - private int getUTFlength(String value, int start, int sum) - throws IOException + long getUTFlength(String value, int start, long sum) { int len = value.length(); - for (int i = start; i < len && sum <= 65535; ++i) + for (int i = start; i < len; ++i) { char c = value.charAt(i); if (c >= '\u0001' && c <= '\u007f') @@ -402,9 +403,6 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput sum += 3; } - if (sum > 65535) - throw new UTFDataFormatException (); - return sum; } @@ -442,10 +440,70 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput */ public final synchronized void writeUTF(String value) throws IOException { + long l = getUTFlength(value, 0, 0); + if (l > 65535) + throw new UTFDataFormatException (); + writeUTFShort(value, (int)l); + } + + /** + * This method performs the main task of <code>writeUTF</code>. + * This method is package-private because ObjectOutputStream uses it. + * + * @param value The <code>String</code> to write to the output in UTF format + * + * @param bytelen The UTF-8 byte length of the <code>String</code>. When + * this method is called, the expected byte length must have been calculated + * by <code>getUTFlength</code>. + * + * @exception IOException If an error occurs + * + * @see DataInput#readUTF + */ + final synchronized void writeUTFShort(String value, int bytelen) + throws IOException + { + writeShort(bytelen); + writeUTFBytes(value); + } + + /** + * This method is similar to <code>writeUTF</code>, but it writes the + * UTF-8 byte length in 64 bits. + * This method is not public but <code>ObjectOutputStream</code> uses it. + * + * @param value The <code>String</code> to write to the output in UTF format + * + * @param bytelen The UTF-8 byte length of the <code>String</code>. When + * this method is called, the expected byte length must have been calculated + * by <code>getUTFlength</code>. + * + * @exception IOException If an error occurs + * + */ + final synchronized void writeUTFLong(String value, long bytelen) + throws IOException + { + writeLong(bytelen); + writeUTFBytes(value); + } + + /** + * This method performes the main task of <code>writeUTF</code> and + * <code>WriteUTFLong</code>, which is to write the UTF-8 byte + * sequence to the output. + * + * @param value The <code>String</code> to write to the output in UTF format + * + * @exception IOException If an error occurs + * + */ + private final synchronized void writeUTFBytes(String value) + throws IOException + { int len = value.length(); int i = 0; int pos = 0; - boolean lengthWritten = false; if (buf == null) buf = new byte[512]; @@ -472,14 +530,6 @@ public class DataOutputStream extends FilterOutputStream implements DataOutput buf[pos++] = (byte) (0x80 | (0x3f & c)); } } - if (! lengthWritten) - { - if (i == len) - writeShort(pos); - else - writeShort(getUTFlength(value, i, pos)); - lengthWritten = true; - } write(buf, 0, pos); pos = 0; } diff --git a/java/io/ObjectInputStream.java b/java/io/ObjectInputStream.java index ea3ffde61..36e70d6a4 100644 --- a/java/io/ObjectInputStream.java +++ b/java/io/ObjectInputStream.java @@ -1,5 +1,5 @@ /* ObjectInputStream.java -- Class used to read serialized objects - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2008 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -356,7 +356,6 @@ public class ObjectInputStream extends InputStream } case TC_STRING: - case TC_LONGSTRING: { if(dump) dumpElement("STRING="); String s = this.realInputStream.readUTF(); @@ -366,6 +365,16 @@ public class ObjectInputStream extends InputStream break; } + case TC_LONGSTRING: + { + if(dump) dumpElement("STRING="); + String s = this.realInputStream.readUTFLong(); + if(dump) dumpElementln(s); + ret_val = processResolution(null, s, assignNewHandle(s,shared), + shared); + break; + } + case TC_ARRAY: { if(dump) dumpElementln("ARRAY"); diff --git a/java/io/ObjectOutputStream.java b/java/io/ObjectOutputStream.java index 5cb2a73f9..c09487536 100644 --- a/java/io/ObjectOutputStream.java +++ b/java/io/ObjectOutputStream.java @@ -1,5 +1,5 @@ /* ObjectOutputStream.java -- Class used to write serialized objects - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -363,10 +363,22 @@ public class ObjectOutputStream extends OutputStream if (obj instanceof String) { - realOutput.writeByte(TC_STRING); - if (shared) - assignNewHandle(obj); - realOutput.writeUTF((String)obj); + String s = (String)obj; + long l = realOutput.getUTFlength(s, 0, 0); + if (l <= 65535) + { + realOutput.writeByte(TC_STRING); + if (shared) + assignNewHandle(obj); + realOutput.writeUTFShort(s, (int)l); + } + else + { + realOutput.writeByte(TC_LONGSTRING); + if (shared) + assignNewHandle(obj); + realOutput.writeUTFLong(s, l); + } break; } |