JDK-6535542 : (bf spec) ByteBuffer.allocate{Direct}?() has undocumented zero-initialization
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 6
  • Priority: P5
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-03-16
  • Updated: 2017-05-16
  • Resolved: 2011-05-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 Other
7 b15Fixed OpenJDK6Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
One of the basic traditions of Java language is that all objects or fields, by default, are always zero-filled while initialization. In particular, if I create new array by "new byte[1000000]" operator, I can be sure that it is initialized by zeros. This feature is important for creating stable and reliable programs.

However, the situation is another for ByteBuffer instances, created by ByteBuffer.allocate or ByteBuffer.allocateDirect method. Java API documentation does not contain any statements about the content of newly created ByteBuffer. The only thing, that I've found in the documentation, is the following phrase (in comments to "Buffer" class):

"...The initial content of a buffer is, in general, undefined."

This would be not so bad if the newly allocated byte buffers would be REALLY filled by random values: for example, by a dump of current RAM (as in C or Pascal languages). But, unfortunately, all new buffers are always filled by zero: for heap ByteBuffer it is a result of zero-filling of Java arrays, for direct ByteBuffer it is a result of call "unsafe.setMemory(base,cap+ps,(byte)0)" inside the package-private DirectByteBuffer constructor.

It is very dangerous situation. Now, if I create ByteBuffer and forget to initialize it by any values, my program usually works normally, because it is really initialized by zero. But it is possible that under the next Java version, or on another platform, where ByteBuffer is not really zero-filled (API documentation allows it!), my program will not work. It can be very difficult to find such a bug in a large project.

Moreover, if I need to create stable library method that returns some new buffer, zero-filled or partially filled by another values, I'm enforced to fill it by zeros after creation. In other case, there will be a risk that behaviour of my program will change in future Java versions or another OS. So, any buffers, that are not used immediately after creation, MUST BE ZERO-FILLED TWICE: first in the DirectByteBuffer constructor (or while creating Java array in HeapByteBuffer), second in my code.

I think you should either correct API documentation or remove zero-initialization from (at least) DirectByteBuffer constructor. The first variant looks better: please write in comments to allocate/allocateDirect methods that the created ByteBuffer is initialized by zero. Another possible solution is add the special boolean argument that specifies whether zero-initialization will be performed or no.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The statement in comments to ByteBuffer.allocate/allocateDirect methods that the created ByteBuffer is initially filled by zeros.


REPRODUCIBILITY :
This bug can be reproduced always.

Comments
SUGGESTED FIX Modify the specification of {Big}?ByteBuffer.allocate{Direct}?() to indicate that the buffer will be zero-initialized.
19-03-2007

EVALUATION Buffers must always be initialized with some fixed value for security purposes. Zero seems to be the logical choice since arrays are also zero-filled. I know of no compliant implementation that uses another value, so it seems reasonable to further constrain the specification to require zero initialization.
19-03-2007