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]

[Updated Patch] StringBuffer.java index checking.


> This fixes 4 cases of index checking in StringBuffer, with test cases.

The patch was broken (luckily the broken patch was not committed).

Here is a new patch that fixes the breakage, and adds another check to
the testcases.

2003-09-24  Ralph Loader  <suckfish@ihug.co.nz>

        * java/lang/StringBuffer.java (getChars): Fix array index checks.
        (append, substring, insert): Likewide.
        * testsuite/libjava.lang/StringBuffer_overflow.java: New file.
        * testsuite/libjava.lang/StringBuffer_overflow.out: New file.

Ralph.

PS.  The gcc documentation at http://gcc.gnu.org/install/test.html says
that the testsuites "are part of the full distribution".  The mauve
testsuite is not included - maybe we should have a copy of mauve in gcc
cvs?



Index: libjava/java/lang/StringBuffer.java
===================================================================
RCS file: /cvsroot/gcc/gcc/libjava/java/lang/StringBuffer.java,v
retrieving revision 1.17
diff -u -u -r1.17 StringBuffer.java
--- libjava/java/lang/StringBuffer.java	24 Sep 2003 06:19:24 -0000	1.17
+++ libjava/java/lang/StringBuffer.java	26 Sep 2003 00:32:15 -0000
@@ -244,10 +244,9 @@
   public synchronized void getChars(int srcOffset, int srcEnd,
                                     char[] dst, int dstOffset)
   {
-    int todo = srcEnd - srcOffset;
-    if (srcOffset < 0 || srcEnd > count || todo < 0)
+    if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
       throw new StringIndexOutOfBoundsException();
-    System.arraycopy(value, srcOffset, dst, dstOffset, todo);
+    System.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
   }
 
   /**
@@ -355,6 +354,8 @@
    */
   public synchronized StringBuffer append(char[] data, int offset, int count)
   {
+    if (offset < 0 || count < 0 || offset > data.length - count)
+      throw new StringIndexOutOfBoundsException();
     ensureCapacity_unsynchronized(this.count + count);
     System.arraycopy(data, offset, value, this.count, count);
     this.count += count;
@@ -560,7 +561,7 @@
   public synchronized String substring(int beginIndex, int endIndex)
   {
     int len = endIndex - beginIndex;
-    if (beginIndex < 0 || endIndex > count || len < 0)
+    if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
       throw new StringIndexOutOfBoundsException();
     if (len == 0)
       return "";
@@ -589,7 +590,7 @@
                                           char[] str, int str_offset, int len)
   {
     if (offset < 0 || offset > count || len < 0
-        || str_offset < 0 || str_offset + len > str.length)
+        || str_offset < 0 || str_offset > str.length - len)
       throw new StringIndexOutOfBoundsException();
     ensureCapacity_unsynchronized(count + len);
     System.arraycopy(value, offset, value, offset + len, count - offset);
--- /dev/null	2003-09-16 01:40:47.000000000 +1200
+++ libjava/testsuite/libjava.lang/StringBuffer_overflow.java	2003-09-26 11:21:52.000000000 +1200
@@ -0,0 +1,126 @@
+/* This tests some corner cases of arithmetic in StringBuffer.  */
+
+/* These tests can all be run on a 32 bit machine with modest amounts
+ * of memory.  */
+
+/* The symptom of the problem is that ArrayIndexOutOfBoundsException
+ * gets thrown, while the documentation says that
+ * StringIndexOutOfBoundsException should be thrown.  */
+
+class StringBuffer_overflow
+{
+  /* Test correct exception on getChars.  */
+  static void getChars()
+  {
+    StringBuffer b = new StringBuffer ("x");
+    char[] s = new char [1];
+    try
+      {
+	// The substring we are attempting to obtain is invalid,
+	// so we should get a StringIndexOutOfBoundsException.
+	b.getChars (1, -1 << 31, s, 0);
+	Fail ("getChars", "no exception");
+      }
+    catch (Throwable e)
+      {
+	ExpectStringIndex ("getChars()", e);
+      }
+  }
+
+  /* Test correct exception on append with bogus count. */
+  static void append()
+  {
+    StringBuffer s = new StringBuffer("a");
+    try
+      {
+	s.append ("".toCharArray(), 1, (1<<31)-1);
+	Fail ("append", "no exception");
+      }
+    catch (Throwable e)
+      {
+	ExpectStringIndex ("append", e);
+      }
+  }
+
+  // Check that append still more or less works.
+  static void appendbasic()
+  {
+    StringBuffer s = new StringBuffer();
+
+    try
+      {
+	if (!new StringBuffer().append ("abcdefg".toCharArray())
+	    .toString().equals ("abcdefg"))
+	  {
+	    Fail ("appendbasic", "append gives incorrect result");
+	  }
+      }
+    catch (Throwable e)
+      {
+	Fail ("appendbasic", e);
+      }
+  }
+
+  /* Test correct expception on substring with bogus indexes.  */
+  static void substring()
+  {
+    StringBuffer s = new StringBuffer ("abc");
+    try
+      {
+	// end - begin == -2 - ((1<<31)-1) == (1<<31) - 1 > 0.  */
+	s.substring ((1<<31)-1, -2);
+	Fail ("substring", "no exception");
+      }
+    catch (Throwable e)
+      {
+	ExpectStringIndex ("substring", e);
+      }
+  }
+
+  static void insert()
+  {
+    StringBuffer s = new StringBuffer ("");
+    try
+      {
+	s.insert (0, "abcd".toCharArray(), (1<<31)-1, 1);
+	Fail ("insert", "no exception");
+      }
+    catch (Throwable e)
+      {
+	ExpectStringIndex ("insert", e);
+      }
+  }
+
+
+  public static void main (String[] unused)
+  {
+    getChars();
+    append();
+    appendbasic();
+    substring();
+    insert();
+
+    if (tests_failed == 0)
+      {
+	System.out.println ("ok");
+      }
+  }
+
+  static int tests_failed = 0;
+
+  static void ExpectStringIndex (String name, Throwable exception)
+  {
+    if (! (exception instanceof StringIndexOutOfBoundsException))
+      {
+	Fail (name, exception);
+      }
+  }
+  static void Fail (String name, Object why)
+  {
+    ++tests_failed;
+
+    System.err.print (name);
+    System.err.print ('\t');
+    System.err.println (why);
+  }
+}
--- /dev/null	2003-09-16 01:40:47.000000000 +1200
+++ libjava/testsuite/libjava.lang/StringBuffer_overflow.out	2003-09-23 18:52:32.000000000 +1200
@@ -0,0 +1 @@
+ok

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