Fix RLP bug: single byte 0 should be encoded differently from byte array length 1 with value 0

This commit is contained in:
nicksavers 2014-10-10 12:59:36 +02:00
parent 8730e760c1
commit 5905566a1f
2 changed files with 26 additions and 9 deletions

View File

@ -71,14 +71,16 @@ public class RLP {
* its own RLP encoding. * its own RLP encoding.
*/ */
/* /**
* [0x80]
* If a string is 0-55 bytes long, the RLP encoding consists of a single * If a string is 0-55 bytes long, the RLP encoding consists of a single
* byte with value 0x80 plus the length of the string followed by the * byte with value 0x80 plus the length of the string followed by the
* string. The range of the first byte is thus [0x80, 0xb7]. * string. The range of the first byte is thus [0x80, 0xb7].
*/ */
private static int OFFSET_SHORT_ITEM = 0x80; private static int OFFSET_SHORT_ITEM = 0x80;
/* /**
* [0xb7]
* If a string is more than 55 bytes long, the RLP encoding consists of a * If a string is more than 55 bytes long, the RLP encoding consists of a
* single byte with value 0xb7 plus the length of the length of the string * single byte with value 0xb7 plus the length of the length of the string
* in binary form, followed by the length of the string, followed by the * in binary form, followed by the length of the string, followed by the
@ -88,7 +90,8 @@ public class RLP {
*/ */
private static int OFFSET_LONG_ITEM = 0xb7; private static int OFFSET_LONG_ITEM = 0xb7;
/* /**
* [0xc0]
* If the total payload of a list (i.e. the combined length of all its * If the total payload of a list (i.e. the combined length of all its
* items) is 0-55 bytes long, the RLP encoding consists of a single byte * items) is 0-55 bytes long, the RLP encoding consists of a single byte
* with value 0xc0 plus the length of the list followed by the concatenation * with value 0xc0 plus the length of the list followed by the concatenation
@ -97,7 +100,8 @@ public class RLP {
*/ */
private static int OFFSET_SHORT_LIST = 0xc0; private static int OFFSET_SHORT_LIST = 0xc0;
/* /**
* [0xf7]
* If the total payload of a list is more than 55 bytes long, the RLP * If the total payload of a list is more than 55 bytes long, the RLP
* encoding consists of a single byte with value 0xf7 plus the length of the * encoding consists of a single byte with value 0xf7 plus the length of the
* length of the list in binary form, followed by the length of the list, * length of the list in binary form, followed by the length of the list,
@ -824,10 +828,9 @@ public class RLP {
public static byte[] encodeElement(byte[] srcData) { public static byte[] encodeElement(byte[] srcData) {
if ( srcData == null || if (srcData == null)
(srcData.length == 1 && srcData[0] == 0)) { return new byte[]{(byte) OFFSET_SHORT_ITEM};
return new byte[]{(byte) 0x80}; else if (srcData.length == 1 && (srcData[0] & 0xFF) < 0x80) {
} if (srcData.length == 1 && (srcData[0] & 0xFF) < 0x80) {
return srcData; return srcData;
} else if (srcData.length < SIZE_THRESHOLD) { } else if (srcData.length < SIZE_THRESHOLD) {
// length = 8X // length = 8X

View File

@ -266,13 +266,27 @@ public class RLPTest {
assertArrayEquals(new byte[] { (byte) 0xc0 }, actuals); assertArrayEquals(new byte[] { (byte) 0xc0 }, actuals);
} }
@Test /** encode list */ @Test /** encode null value */
public void testEncodeElementNull() { public void testEncodeElementNull() {
byte[] actuals = RLP.encodeElement(null); byte[] actuals = RLP.encodeElement(null);
assertArrayEquals(new byte[] { (byte) 0x80 }, actuals); assertArrayEquals(new byte[] { (byte) 0x80 }, actuals);
} }
@Test /** encode single byte 0x00 */
public void testEncodeElementZero() {
byte[] actuals = RLP.encodeElement(new byte[] {0x00});
assertArrayEquals(new byte[] { (byte) 0x00 }, actuals);
}
@Test /** encode single byte 0x01 */
public void testEncodeElementOne() {
byte[] actuals = RLP.encodeElement(new byte[] {0x00});
assertArrayEquals(new byte[] { (byte) 0x00 }, actuals);
}
@Test /** found bug encode list affects element value, @Test /** found bug encode list affects element value,
hhh... not really at the end but keep the test */ hhh... not really at the end but keep the test */
public void test10() { public void test10() {