7199551: (bf) CharBuffer.append(CharSequence) throws BufferOverflowException for read-only buffer

Reviewed-by: iris, dxu, chegar
diff --git a/jdk/src/share/classes/java/nio/X-Buffer.java.template b/jdk/src/share/classes/java/nio/X-Buffer.java.template
index 4150b1e..3226924 100644
--- a/jdk/src/share/classes/java/nio/X-Buffer.java.template
+++ b/jdk/src/share/classes/java/nio/X-Buffer.java.template
@@ -741,6 +741,8 @@
     public $Type$Buffer put($Type$Buffer src) {
         if (src == this)
             throw new IllegalArgumentException();
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
         int n = src.remaining();
         if (n > remaining())
             throw new BufferOverflowException();
@@ -888,6 +890,8 @@
      */
     public $Type$Buffer put(String src, int start, int end) {
         checkBounds(start, end - start, src.length());
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
         if (end - start > remaining())
             throw new BufferOverflowException();
         for (int i = start; i < end; i++)
diff --git a/jdk/test/java/nio/Buffer/Basic-X.java.template b/jdk/test/java/nio/Buffer/Basic-X.java.template
index 54435c2..1548a9f 100644
--- a/jdk/test/java/nio/Buffer/Basic-X.java.template
+++ b/jdk/test/java/nio/Buffer/Basic-X.java.template
@@ -335,7 +335,7 @@
         fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
     }
 
-    private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
+    private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) {
         boolean caught = false;
         try {
             thunk.run();
@@ -350,7 +350,7 @@
             fail(ex.getName() + " not thrown", b);
     }
 
-    private static void tryCatch($type$ [] t, Class ex, Runnable thunk) {
+    private static void tryCatch($type$ [] t, Class<?> ex, Runnable thunk) {
         tryCatch($Type$Buffer.wrap(t), ex, thunk);
     }
 
@@ -681,6 +681,14 @@
                     bulkPutBuffer(rb);
                 }});
 
+        // put($Type$Buffer) should not change source position
+        final $Type$Buffer src = $Type$Buffer.allocate(1);
+        tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
+                public void run() {
+                    rb.put(src);
+                 }});
+        ck(src, src.position(), 0);
+
         tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
                 public void run() {
                     rb.compact();
@@ -744,6 +752,22 @@
 
 #end[byte]
 
+#if[char]
+
+        // 7199551
+        tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
+            public void run() {
+                String s = new String(new char[rb.remaining() + 1]);
+                rb.put(s);
+            }});
+        tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
+            public void run() {
+                String s = new String(new char[rb.remaining() + 1]);
+                rb.append(s);
+            }});
+
+#end[char]
+
         if (rb.getClass().getName().startsWith("java.nio.Heap")) {
 
             tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
diff --git a/jdk/test/java/nio/Buffer/Basic.java b/jdk/test/java/nio/Buffer/Basic.java
index 86c1b44..0dba4c1 100644
--- a/jdk/test/java/nio/Buffer/Basic.java
+++ b/jdk/test/java/nio/Buffer/Basic.java
@@ -25,7 +25,7 @@
  * @summary Unit test for buffers
  * @bug 4413135 4414911 4416536 4416562 4418782 4471053 4472779 4490253 4523725
  *      4526177 4463011 4660660 4661219 4663521 4782970 4804304 4938424 6231529
- *      6221101 6234263 6535542 6591971 6593946 6795561 7190219
+ *      6221101 6234263 6535542 6591971 6593946 6795561 7190219 7199551
  * @author Mark Reinhold
  */
 
diff --git a/jdk/test/java/nio/Buffer/BasicByte.java b/jdk/test/java/nio/Buffer/BasicByte.java
index 34856fa..861a433 100644
--- a/jdk/test/java/nio/Buffer/BasicByte.java
+++ b/jdk/test/java/nio/Buffer/BasicByte.java
@@ -335,7 +335,7 @@
         fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
     }
 
-    private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
+    private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) {
         boolean caught = false;
         try {
             thunk.run();
@@ -350,7 +350,7 @@
             fail(ex.getName() + " not thrown", b);
     }
 
-    private static void tryCatch(byte [] t, Class ex, Runnable thunk) {
+    private static void tryCatch(byte [] t, Class<?> ex, Runnable thunk) {
         tryCatch(ByteBuffer.wrap(t), ex, thunk);
     }
 
@@ -681,6 +681,14 @@
                     bulkPutBuffer(rb);
                 }});
 
+        // put(ByteBuffer) should not change source position
+        final ByteBuffer src = ByteBuffer.allocate(1);
+        tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
+                public void run() {
+                    rb.put(src);
+                 }});
+        ck(src, src.position(), 0);
+
         tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
                 public void run() {
                     rb.compact();
@@ -744,6 +752,22 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         if (rb.getClass().getName().startsWith("java.nio.Heap")) {
 
             tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
diff --git a/jdk/test/java/nio/Buffer/BasicChar.java b/jdk/test/java/nio/Buffer/BasicChar.java
index d06772a..b899161 100644
--- a/jdk/test/java/nio/Buffer/BasicChar.java
+++ b/jdk/test/java/nio/Buffer/BasicChar.java
@@ -335,7 +335,7 @@
         fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
     }
 
-    private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
+    private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) {
         boolean caught = false;
         try {
             thunk.run();
@@ -350,7 +350,7 @@
             fail(ex.getName() + " not thrown", b);
     }
 
-    private static void tryCatch(char [] t, Class ex, Runnable thunk) {
+    private static void tryCatch(char [] t, Class<?> ex, Runnable thunk) {
         tryCatch(CharBuffer.wrap(t), ex, thunk);
     }
 
@@ -681,6 +681,14 @@
                     bulkPutBuffer(rb);
                 }});
 
+        // put(CharBuffer) should not change source position
+        final CharBuffer src = CharBuffer.allocate(1);
+        tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
+                public void run() {
+                    rb.put(src);
+                 }});
+        ck(src, src.position(), 0);
+
         tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
                 public void run() {
                     rb.compact();
@@ -744,6 +752,22 @@
 
 
 
+
+
+        // 7199551
+        tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
+            public void run() {
+                String s = new String(new char[rb.remaining() + 1]);
+                rb.put(s);
+            }});
+        tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
+            public void run() {
+                String s = new String(new char[rb.remaining() + 1]);
+                rb.append(s);
+            }});
+
+
+
         if (rb.getClass().getName().startsWith("java.nio.Heap")) {
 
             tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
diff --git a/jdk/test/java/nio/Buffer/BasicDouble.java b/jdk/test/java/nio/Buffer/BasicDouble.java
index 8ff9eb1..97efe8f 100644
--- a/jdk/test/java/nio/Buffer/BasicDouble.java
+++ b/jdk/test/java/nio/Buffer/BasicDouble.java
@@ -335,7 +335,7 @@
         fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
     }
 
-    private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
+    private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) {
         boolean caught = false;
         try {
             thunk.run();
@@ -350,7 +350,7 @@
             fail(ex.getName() + " not thrown", b);
     }
 
-    private static void tryCatch(double [] t, Class ex, Runnable thunk) {
+    private static void tryCatch(double [] t, Class<?> ex, Runnable thunk) {
         tryCatch(DoubleBuffer.wrap(t), ex, thunk);
     }
 
@@ -681,6 +681,14 @@
                     bulkPutBuffer(rb);
                 }});
 
+        // put(DoubleBuffer) should not change source position
+        final DoubleBuffer src = DoubleBuffer.allocate(1);
+        tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
+                public void run() {
+                    rb.put(src);
+                 }});
+        ck(src, src.position(), 0);
+
         tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
                 public void run() {
                     rb.compact();
@@ -744,6 +752,22 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         if (rb.getClass().getName().startsWith("java.nio.Heap")) {
 
             tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
diff --git a/jdk/test/java/nio/Buffer/BasicFloat.java b/jdk/test/java/nio/Buffer/BasicFloat.java
index 98e1989..2f95493 100644
--- a/jdk/test/java/nio/Buffer/BasicFloat.java
+++ b/jdk/test/java/nio/Buffer/BasicFloat.java
@@ -335,7 +335,7 @@
         fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
     }
 
-    private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
+    private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) {
         boolean caught = false;
         try {
             thunk.run();
@@ -350,7 +350,7 @@
             fail(ex.getName() + " not thrown", b);
     }
 
-    private static void tryCatch(float [] t, Class ex, Runnable thunk) {
+    private static void tryCatch(float [] t, Class<?> ex, Runnable thunk) {
         tryCatch(FloatBuffer.wrap(t), ex, thunk);
     }
 
@@ -681,6 +681,14 @@
                     bulkPutBuffer(rb);
                 }});
 
+        // put(FloatBuffer) should not change source position
+        final FloatBuffer src = FloatBuffer.allocate(1);
+        tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
+                public void run() {
+                    rb.put(src);
+                 }});
+        ck(src, src.position(), 0);
+
         tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
                 public void run() {
                     rb.compact();
@@ -744,6 +752,22 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         if (rb.getClass().getName().startsWith("java.nio.Heap")) {
 
             tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
diff --git a/jdk/test/java/nio/Buffer/BasicInt.java b/jdk/test/java/nio/Buffer/BasicInt.java
index 571d62f..a9ce0fb 100644
--- a/jdk/test/java/nio/Buffer/BasicInt.java
+++ b/jdk/test/java/nio/Buffer/BasicInt.java
@@ -335,7 +335,7 @@
         fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
     }
 
-    private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
+    private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) {
         boolean caught = false;
         try {
             thunk.run();
@@ -350,7 +350,7 @@
             fail(ex.getName() + " not thrown", b);
     }
 
-    private static void tryCatch(int [] t, Class ex, Runnable thunk) {
+    private static void tryCatch(int [] t, Class<?> ex, Runnable thunk) {
         tryCatch(IntBuffer.wrap(t), ex, thunk);
     }
 
@@ -681,6 +681,14 @@
                     bulkPutBuffer(rb);
                 }});
 
+        // put(IntBuffer) should not change source position
+        final IntBuffer src = IntBuffer.allocate(1);
+        tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
+                public void run() {
+                    rb.put(src);
+                 }});
+        ck(src, src.position(), 0);
+
         tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
                 public void run() {
                     rb.compact();
@@ -744,6 +752,22 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         if (rb.getClass().getName().startsWith("java.nio.Heap")) {
 
             tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
diff --git a/jdk/test/java/nio/Buffer/BasicLong.java b/jdk/test/java/nio/Buffer/BasicLong.java
index 7ea5d03..82fb25b 100644
--- a/jdk/test/java/nio/Buffer/BasicLong.java
+++ b/jdk/test/java/nio/Buffer/BasicLong.java
@@ -335,7 +335,7 @@
         fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
     }
 
-    private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
+    private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) {
         boolean caught = false;
         try {
             thunk.run();
@@ -350,7 +350,7 @@
             fail(ex.getName() + " not thrown", b);
     }
 
-    private static void tryCatch(long [] t, Class ex, Runnable thunk) {
+    private static void tryCatch(long [] t, Class<?> ex, Runnable thunk) {
         tryCatch(LongBuffer.wrap(t), ex, thunk);
     }
 
@@ -681,6 +681,14 @@
                     bulkPutBuffer(rb);
                 }});
 
+        // put(LongBuffer) should not change source position
+        final LongBuffer src = LongBuffer.allocate(1);
+        tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
+                public void run() {
+                    rb.put(src);
+                 }});
+        ck(src, src.position(), 0);
+
         tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
                 public void run() {
                     rb.compact();
@@ -744,6 +752,22 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         if (rb.getClass().getName().startsWith("java.nio.Heap")) {
 
             tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
diff --git a/jdk/test/java/nio/Buffer/BasicShort.java b/jdk/test/java/nio/Buffer/BasicShort.java
index 176a53f..9f8579d 100644
--- a/jdk/test/java/nio/Buffer/BasicShort.java
+++ b/jdk/test/java/nio/Buffer/BasicShort.java
@@ -335,7 +335,7 @@
         fail(problem + String.format(": x=%s y=%s", x, y), xb, yb);
     }
 
-    private static void tryCatch(Buffer b, Class ex, Runnable thunk) {
+    private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) {
         boolean caught = false;
         try {
             thunk.run();
@@ -350,7 +350,7 @@
             fail(ex.getName() + " not thrown", b);
     }
 
-    private static void tryCatch(short [] t, Class ex, Runnable thunk) {
+    private static void tryCatch(short [] t, Class<?> ex, Runnable thunk) {
         tryCatch(ShortBuffer.wrap(t), ex, thunk);
     }
 
@@ -681,6 +681,14 @@
                     bulkPutBuffer(rb);
                 }});
 
+        // put(ShortBuffer) should not change source position
+        final ShortBuffer src = ShortBuffer.allocate(1);
+        tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
+                public void run() {
+                    rb.put(src);
+                 }});
+        ck(src, src.position(), 0);
+
         tryCatch(b, ReadOnlyBufferException.class, new Runnable() {
                 public void run() {
                     rb.compact();
@@ -744,6 +752,22 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
         if (rb.getClass().getName().startsWith("java.nio.Heap")) {
 
             tryCatch(b, ReadOnlyBufferException.class, new Runnable() {