...
The read methods (readByte, readShort, readInt, readLong, readFloat and readDouble
) and the corresponding write methods defined by class java.io.DataInputStream
operate only on big-endian data. Use of these methods while interoperating with traditional languages, such as C or C++, is insecure because such languages lack any guarantees about endianness. This noncompliant code example shows such a discrepancy.
Code Block | ||
---|---|---|
| ||
try { DataInputStream dis = null; try { dis = new DataInputStream( new FileInputStream("data")); // Little-endian data might be read as big-endian int serialNumber = dis.readInt(); } finally { if (dis != null) { dis.close(); } } catch (IOException x) { // handle error } } |
Compliant Solution (Use ByteBuffer
)
Wiki Markup |
---|
This compliant solution uses methods provided by class {{ByteBuffer}} (see \[[API 2006|AA. Bibliography#API 06]\] [ByteBuffer|http://download.oracle.com/javase/6/docs/api/java/nio/ByteBuffer.html]) to correctly extract an {{int}} from the original input value. It wraps the input byte array with a {{ByteBuffer}}, sets the byte order to little-endian, and extracts the {{int}}. The result is stored in the integer {{serialNumber}}. |
Code Block | ||
---|---|---|
| ||
try { DataInputStream dis = null; try { dis = new DataInputStream( new FileInputStream("data")); byte[] buffer = new byte[4]; int bytesRead = dis.read(buffer); // Bytes are read into buffer if (bytesRead != 4) { throw new IOException("Unexpected End of Stream"); } int serialNumber = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getInt(); } finally { if (dis != null) { dis.close(); } } } catch (IOException x) { // handle error } |
Class ByteBuffer
provides analogous get and put methods for the other numeric types.
...
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="335b1484af9f659c-c6b04681-4a044476-b53381e5-f0a80567be5da7746f350c6f"><ac:plain-text-body><![CDATA[ | [[API 2006 | AA. Bibliography#API 06]] | Class [ByteBuffer | http://download.oracle.com/javase/6/docs/api/java/nio/ByteBuffer.html]: Methods | http://download.oracle.com/javase/6/docs/api/java/lang/Integer.html]: method | ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="0a62283898add198-c884343d-4b024e36-b40a8ce6-e571de72914a4f9ccc9e8fd5"><ac:plain-text-body><![CDATA[ | [[Cohen 1981 | AA. Bibliography#Cohen 81]] | "On Holy Wars and a Plea for Peace" | ]]></ac:plain-text-body></ac:structured-macro> | ||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="ac6ccb20d08f062d-8cd820bc-491e4566-975c9db5-ca9ccd8375933cd73a486356"><ac:plain-text-body><![CDATA[ | [[Harold 1997 | AA. Bibliography#Harold 97]] | Chapter 2: "Primitive Data Types, Cross Platform issues" | ]]></ac:plain-text-body></ac:structured-macro> |
...