JDK-8361308 : (bf) CharBuffer.getChars(int,int,char[],int) violates pre-existing specification
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.nio
  • Priority: P2
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 25,26
  • Submitted: 2025-07-02
  • Updated: 2025-07-03
  • Resolved: 2025-07-03
Related Reports
CSR :  
Description
Summary
-------

Correct `java.nio.CharBuffer.getChars(int,int,char[],int)` so that it adheres to the class level specification

> This class implements the CharSequence interface so that character
> buffers may be used wherever character sequences are accepted, for
> example in the regular-expression package java.util.regex. The methods
> defined by CharSequence operate relative to the current position of
> the buffer when they are invoked.

Problem
-------
`CharBuffer.getChars` was added in JDK 25 but failed to follow the specification in the class description that implemented `CharSequence` methods are relative to the buffer's current position and not absolute.

Solution
--------

Correct `CharBuffer.getChars` such that the index parameters referring to the buffer are interpreted as relative to the current buffer position and not as absolute positions.

Specification
-------------

    --- a/src/java.base/share/classes/java/nio/X-Buffer.java.template
    +++ b/src/java.base/share/classes/java/nio/X-Buffer.java.template
    @@ -1897,21 +1897,31 @@ public abstract sealed class $Type$Buffer
     #if[char]
     
         /**
    -     * Absolute bulk <i>get</i> method.
    +     * Relative bulk <i>get</i> method.
          *
          * <p> This method transfers {@code srcEnd-srcBegin} characters from this
    -     * buffer into the given array, starting at index {@code srcBegin} in this
    -     * buffer and at offset {@code dstBegin} in the array. The position of this
    -     * buffer is unchanged.
    +     * buffer into the given array, starting at index
    +     * {@code position() + srcBegin} in this buffer and at offset
    +     * {@code dstBegin} in the array. The position of this buffer is unchanged.
    +     *
    +     * <p> An invocation of this method behaves exactly the same was as the
    +     * invocation
    +     *
    +     * {@snippet lang=java :
    +     *     get(position() + srcBegin, dst, dstBegin, srcEnd - srcBegin)
    +     * }
          *
          * @param  srcBegin
    -     *         The index in this buffer from which the first character will be
    -     *         read; must be non-negative and less than {@code limit()}
    +     *         The index in this buffer, relative to the current position,
    +     *         of the first character to
    +     *         read; must be non-negative and less than
    +     *         {@code limit() - position()}
          *
          * @param  srcEnd
    -     *         The index in this buffer directly before the last character to
    -     *         read; must be non-negative and less or equal than {@code limit()}
    -     *         and must be greater or equal than {@code srcBegin}
    +     *         The index in this buffer, relative to the current position,
    +     *         after the last character to read;
    +     *         must be greater than or equal to {@code srcBegin} and less than
    +     *         or equal to {@code limit() - position()}
          *
          * @param  dst
          *         The destination array
    @@ -1924,14 +1934,11 @@ public abstract sealed class $Type$Buffer
          *          If the preconditions on the {@code srcBegin}, {@code srcEnd},
          *          and {@code dstBegin} parameters do not hold
          *
    -     * @implSpec This method is equivalent to
    -     *           {@code get(srcBegin, dst, dstBegin, srcEnd - srcBegin)}.
    -     *
          * @since 25
          */


Comments
Moving to Approved.
03-07-2025

I removed the implSpec to match the convention elsewhere in this file. The snippets could be converted to implSpecs at a later time.
03-07-2025

CharBuffer implementing CharSequence is always problematic, easy to forget or get something wrong. The change here looks good, and thankfully spotted in time to fix in 25. I think we want to continue to have an implSpec in this method.
03-07-2025

You should put both 25 and 26 into the fix version of this CSR. The updated specification looks good. For history, in the original PR review, Alan identified this implementation is an absolute method; that class-level specification was inadvertently omitted, and no nio area engineer was involved in the review of the CharBuffer override as the majority of the patch was in different area in the core libraries.
02-07-2025