Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Wiki Markup
            Buffer classes defined in the {{java.nio}} package, such as {{IntBuffer}}, {{CharBuffer}} and {{ByteBuffer}},  define a variety of {{wrap()}} methods that wrap an array of some primitive data type into a buffer, and return the buffer as a {{Buffer}} object. Although these methods create a new {{Buffer}} object, the new {{Buffer}} is backed by the same given input array. According to the Java API for these methods \[[API 2006|AA. Bibliography#API 06]\]:,

The new buffer will be backed by the given character array; that is, modifications to the buffer will cause the array to be modified and vice versa.

...

This noncompliant code example declares a char array, wraps it within a Buffer, and exposes that Buffer to untrusted code via the getBufferCopy() method.

Code Block
bgColor#FFCCCC
final class Wrap {
  private char[] dataArray;
  
  public Wrap () {
    dataArray = new char[10];
    // Initialize
  }
	
  public CharBuffer getBufferCopy() {
    return CharBuffer.wrap(dataArray);	
  }
}

Compliant Solution (asReadOnlyBuffer())

This compliant solution returns a read-only view of the char array , in the form of a read-only CharBuffer. The standard library implementation of CharBuffer guarantees that attempts to modify the elements of a read-only CharBuffer will result in a java.nio.ReadOnlyBufferException.

Code Block
bgColor#ccccff
final class Wrap {
  private char[] dataArray;

  public Wrap () {
    dataArray = new char[10];
    // Initialize
  }
	
  public CharBuffer getBufferCopy() {
    return CharBuffer.wrap(dataArray).asReadOnlyBuffer();
  }
}

...

This compliant solution allocates a new CharBuffer and explicitly copies the contents of the char array into it , before returning the copy. Consequently, malicious callers can modify the copy of the array , but cannot modify the original.

Code Block
bgColor#ccccff
final class Wrap {
  private char[] dataArray;
  
  public Wrap () {
    dataArray = new char[10];
    // Initialize
  }
	
  public CharBuffer getBufferCopy() {
    CharBuffer cb = CharBuffer.allocate(dataArray.length);
    cb.put(dataArray);
    return cb;
  }
}

...

Code Block
bgColor#FFCCCC
final class Dup {
  CharBuffer cb;
 
  public Dup() {
    cb = CharBuffer.allocate(10);
    // Initialize
  }

  public CharBuffer getBufferCopy() {	
    return cb.duplicate();
  }
}

...

Code Block
bgColor#ccccff
final class Dup {
  CharBuffer cb;
 
  public Dup() {
    cb = CharBuffer.allocate(10);
    // Initialize
  }

  public CharBuffer getBufferCopy() {	
    return cb.asReadOnlyBuffer();
  }
}

...

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="a0c823c51b3d4646-65bb411d-454c415b-840892e2-719556bbe4ea97f5b442149a"><ac:plain-text-body><![CDATA[

[[API 2006

AA. Bibliography#API 06]]

class CharBuffer

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="05ce728146c62801-e4442d33-414e492b-85278b9b-da86fe1532b2ed08d6e950bb"><ac:plain-text-body><![CDATA[

[[Hitchens 2002

AA. Bibliography#Hitchens 02]]

2.3 Duplicating Buffers

]]></ac:plain-text-body></ac:structured-macro>

...