This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Re: [PATCH] Fix PR libgcj/36252, OutOfMemoryError in String constructor.
Tom Tromey wrote:
>>>>>> "David" == David Daney <ddaney@avtrex.com> writes:
>
> David> My patch to String's native code is simple and lets the String contain
> David> all the valid characters. Throwing away invalid data is contemplated
> David> and allowed by the specification.
>
> In that case, this is ok. Thanks for digging into the details.
> If you want to put this in 4.3, that is also ok by me.
>
Thanks,
Since I made a change to the testcase so it doesn't print a stack trace
if the character set converter is not available, I am attaching the
updated patch.
This is what I committed to both the 4.3 branch and trunk:
2008-05-20 David Daney <ddaney@avtrex.com>
PR libgcj/36252
* java/lang/natString.ccn: Add
#include <java/io/CharConversionException.h>.
(init (byte[], int, int, String)): Catch and ignore
CharConversionException. Break out of conversion loop
on incomplete input.
* testsuite/libjava.lang/PR36252.java: New test.
* testsuite/libjava.lang/PR36252.out: New file, its expected output.
* testsuite/libjava.lang/PR36252.jar: New file, its pre-compiled
jar file.
Index: testsuite/libjava.lang/PR36252.out
===================================================================
--- testsuite/libjava.lang/PR36252.out (revision 0)
+++ testsuite/libjava.lang/PR36252.out (revision 0)
@@ -0,0 +1 @@
+ok
Index: testsuite/libjava.lang/PR36252.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: testsuite/libjava.lang/PR36252.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: testsuite/libjava.lang/PR36252.java
===================================================================
--- testsuite/libjava.lang/PR36252.java (revision 0)
+++ testsuite/libjava.lang/PR36252.java (revision 0)
@@ -0,0 +1,16 @@
+import java.io.UnsupportedEncodingException;
+
+public class PR36252
+{
+ public static void main(String[] args)
+ {
+ try {
+ byte[] txt = new byte[] {-55, 87, -55, -42, -55, -20};
+ // This new String(...) should not throw an OutOfMemoryError.
+ String s = new String(txt, 0, 6, "MS932");
+ } catch (UnsupportedEncodingException e) {
+ // Silently ignore.
+ }
+ System.out.println("ok");
+ }
+}
Index: java/lang/natString.cc
===================================================================
--- java/lang/natString.cc (revision 135124)
+++ java/lang/natString.cc (working copy)
@@ -1,6 +1,7 @@
// natString.cc - Implementation of java.lang.String native methods.
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+ 2007, 2008 Free Software Foundation
This file is part of libgcj.
@@ -23,6 +24,7 @@ details. */
#include <java/lang/NullPointerException.h>
#include <java/lang/StringBuffer.h>
#include <java/io/ByteArrayOutputStream.h>
+#include <java/io/CharConversionException.h>
#include <java/io/OutputStreamWriter.h>
#include <java/io/ByteArrayInputStream.h>
#include <java/io/InputStreamReader.h>
@@ -493,9 +495,28 @@ java::lang::String::init (jbyteArray byt
converter->setInput(bytes, offset, offset+count);
while (converter->inpos < converter->inlength)
{
- int done = converter->read(array, outpos, avail);
+ int done;
+ try
+ {
+ done = converter->read(array, outpos, avail);
+ }
+ catch (::java::io::CharConversionException *e)
+ {
+ // Ignore it and silently throw away the offending data.
+ break;
+ }
if (done == 0)
{
+ // done is zero if either there is no space available in the
+ // output *or* the input is incomplete. We assume that if
+ // there are 20 characters available in the output, the
+ // input must be incomplete and there is no more work to do.
+ // This means we may skip several bytes of input, but that
+ // is OK as the behavior is explicitly unspecified in this
+ // case.
+ if (avail - outpos > 20)
+ break;
+
jint new_size = 2 * (outpos + avail);
jcharArray new_array = JvNewCharArray (new_size);
memcpy (elements (new_array), elements (array),