summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIto Kazumitsu <kaz@maczuka.gcd.org>2008-01-29 22:30:42 +0000
committerIto Kazumitsu <kaz@maczuka.gcd.org>2008-01-29 22:30:42 +0000
commit1745554bbb5117a3bb9fbe3d90db73b112aa5ca4 (patch)
tree534743cdad2c703b551a7a5c3452eb0e3b941074
parentb3891c2b5980abfc7532ff9ef46e3539caab6cd2 (diff)
downloadclasspath-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--ChangeLog16
-rw-r--r--java/io/DataInputStream.java50
-rw-r--r--java/io/DataOutputStream.java84
-rw-r--r--java/io/ObjectInputStream.java13
-rw-r--r--java/io/ObjectOutputStream.java22
5 files changed, 158 insertions, 27 deletions
diff --git a/ChangeLog b/ChangeLog
index da1c640ab..f625f84b9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;
}