# HG changeset patch # User bpb # Date 1552500742 25200 # Node ID 1d7aec80147a6d92b101a76aef92f3ddc88bedf4 # Parent 9a90236ab64c34aefddc5335e31e75ebcbfc793e 8219597: (bf) Heap buffer state changes could provoke unexpected exceptions Reviewed-by: alanb, rriggs diff -r 9a90236ab64c -r 1d7aec80147a src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template --- a/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template Wed Mar 13 14:10:18 2019 -0400 +++ b/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template Wed Mar 13 11:12:22 2019 -0700 @@ -104,11 +104,12 @@ } public $Type$Buffer slice() { + int rem = this.remaining(); return new Heap$Type$Buffer$RW$(hb, -1, 0, - this.remaining(), - this.remaining(), + rem, + rem, this.position() + offset); } @@ -174,10 +175,11 @@ public $Type$Buffer get($type$[] dst, int offset, int length) { checkBounds(offset, length, dst.length); - if (length > remaining()) + int pos = position(); + if (length > limit() - pos) throw new BufferUnderflowException(); - System.arraycopy(hb, ix(position()), dst, offset, length); - position(position() + length); + System.arraycopy(hb, ix(pos), dst, offset, length); + position(pos + length); return this; } @@ -219,10 +221,11 @@ public $Type$Buffer put($type$[] src, int offset, int length) { #if[rw] checkBounds(offset, length, src.length); - if (length > remaining()) + int pos = position(); + if (length > limit() - pos) throw new BufferOverflowException(); - System.arraycopy(src, offset, hb, ix(position()), length); - position(position() + length); + System.arraycopy(src, offset, hb, ix(pos), length); + position(pos + length); return this; #else[rw] throw new ReadOnlyBufferException(); @@ -235,19 +238,22 @@ if (src == this) throw createSameBufferException(); Heap$Type$Buffer sb = (Heap$Type$Buffer)src; - int n = sb.remaining(); - if (n > remaining()) + int pos = position(); + int sbpos = sb.position(); + int n = sb.limit() - sbpos; + if (n > limit() - pos) throw new BufferOverflowException(); - System.arraycopy(sb.hb, sb.ix(sb.position()), - hb, ix(position()), n); - sb.position(sb.position() + n); - position(position() + n); + System.arraycopy(sb.hb, sb.ix(sbpos), + hb, ix(pos), n); + sb.position(sbpos + n); + position(pos + n); } else if (src.isDirect()) { int n = src.remaining(); - if (n > remaining()) + int pos = position(); + if (n > limit() - pos) throw new BufferOverflowException(); - src.get(hb, ix(position()), n); - position(position() + n); + src.get(hb, ix(pos), n); + position(pos + n); } else { super.put(src); } @@ -289,8 +295,10 @@ public $Type$Buffer compact() { #if[rw] - System.arraycopy(hb, ix(position()), hb, ix(0), remaining()); - position(remaining()); + int pos = position(); + int rem = limit() - pos; + System.arraycopy(hb, ix(pos), hb, ix(0), rem); + position(rem); limit(capacity()); discardMark(); return this; @@ -348,8 +356,9 @@ } public CharBuffer asCharBuffer() { - int size = this.remaining() >> 1; - long addr = address + position(); + int pos = position(); + int size = (limit() - pos) >> 1; + long addr = address + pos; return (bigEndian ? (CharBuffer)(new ByteBufferAsCharBuffer$RW$B(this, -1, @@ -399,8 +408,9 @@ } public ShortBuffer asShortBuffer() { - int size = this.remaining() >> 1; - long addr = address + position(); + int pos = position(); + int size = (limit() - pos) >> 1; + long addr = address + pos; return (bigEndian ? (ShortBuffer)(new ByteBufferAsShortBuffer$RW$B(this, -1, @@ -450,8 +460,9 @@ } public IntBuffer asIntBuffer() { - int size = this.remaining() >> 2; - long addr = address + position(); + int pos = position(); + int size = (limit() - pos) >> 2; + long addr = address + pos; return (bigEndian ? (IntBuffer)(new ByteBufferAsIntBuffer$RW$B(this, -1, @@ -501,8 +512,9 @@ } public LongBuffer asLongBuffer() { - int size = this.remaining() >> 3; - long addr = address + position(); + int pos = position(); + int size = (limit() - pos) >> 3; + long addr = address + pos; return (bigEndian ? (LongBuffer)(new ByteBufferAsLongBuffer$RW$B(this, -1, @@ -556,8 +568,9 @@ } public FloatBuffer asFloatBuffer() { - int size = this.remaining() >> 2; - long addr = address + position(); + int pos = position(); + int size = (limit() - pos) >> 2; + long addr = address + pos; return (bigEndian ? (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$B(this, -1, @@ -611,8 +624,9 @@ } public DoubleBuffer asDoubleBuffer() { - int size = this.remaining() >> 3; - long addr = address + position(); + int pos = position(); + int size = (limit() - pos) >> 3; + long addr = address + pos; return (bigEndian ? (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$B(this, -1,