| 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 | ||
|---|---|---|
| ||
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 | ||
|---|---|---|
| ||
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 | ||
|---|---|---|
| ||
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 | ||
|---|---|---|
| ||
final class Dup {
CharBuffer cb;
public Dup() {
cb = CharBuffer.allocate(10);
// Initialize
}
public CharBuffer getBufferCopy() {
return cb.duplicate();
}
}
|
...
| Code Block | ||
|---|---|---|
| ||
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 | ]]></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> |
...