This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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),

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]