From 35e1369c771099583b09158453692e7ba26610ef Mon Sep 17 00:00:00 2001 From: Ralph Loader Date: Thu, 16 Oct 2003 21:35:42 +0000 Subject: [PATCH] StringBuffer.java (getChars): Fix array index checks. * java/lang/StringBuffer.java (getChars): Fix array index checks. (append, substring, insert): Likewise. * testsuite/libjava.lang/StringBuffer_overflow.java: New file. * testsuite/libjava.lang/StringBuffer_overflow.out: New file. From-SVN: r72579 --- libjava/ChangeLog | 7 ++ libjava/java/lang/StringBuffer.java | 11 +- .../libjava.lang/StringBuffer_overflow.java | 126 +++++++++++++++++++++ .../libjava.lang/StringBuffer_overflow.out | 1 + 4 files changed, 140 insertions(+), 5 deletions(-) create mode 100644 libjava/testsuite/libjava.lang/StringBuffer_overflow.java create mode 100644 libjava/testsuite/libjava.lang/StringBuffer_overflow.out diff --git a/libjava/ChangeLog b/libjava/ChangeLog index ef05117..d751c10 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,5 +1,12 @@ 2003-10-17 Ralph Loader + * java/lang/StringBuffer.java (getChars): Fix array index checks. + (append, substring, insert): Likewise. + * testsuite/libjava.lang/StringBuffer_overflow.java: New file. + * testsuite/libjava.lang/StringBuffer_overflow.out: New file. + +2003-10-17 Ralph Loader + * java/lang/natString.cc (getChars): Fix validation of array indexes. (getBytes, regionMatches, startsWith, valueOf): Likewise. diff --git a/libjava/java/lang/StringBuffer.java b/libjava/java/lang/StringBuffer.java index 0903b40..92f9615 100644 --- a/libjava/java/lang/StringBuffer.java +++ b/libjava/java/lang/StringBuffer.java @@ -244,10 +244,9 @@ public final class StringBuffer implements Serializable, CharSequence 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 final class StringBuffer implements Serializable, CharSequence */ 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 final class StringBuffer implements Serializable, CharSequence 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 @@ public final class StringBuffer implements Serializable, CharSequence 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); diff --git a/libjava/testsuite/libjava.lang/StringBuffer_overflow.java b/libjava/testsuite/libjava.lang/StringBuffer_overflow.java new file mode 100644 index 0000000..68e18da --- /dev/null +++ b/libjava/testsuite/libjava.lang/StringBuffer_overflow.java @@ -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); + } +} diff --git a/libjava/testsuite/libjava.lang/StringBuffer_overflow.out b/libjava/testsuite/libjava.lang/StringBuffer_overflow.out new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/libjava/testsuite/libjava.lang/StringBuffer_overflow.out @@ -0,0 +1 @@ +ok -- 2.7.4