瀏覽代碼

rlp: fix encoding of one element strings and byte slices

The encoder was missing a special case for one element strings whose
element is below 0x7f. Such strings must be encoded as a single byte
without a string header.
Felix Lange 10 年之前
父節點
當前提交
965c9babe3
共有 2 個文件被更改,包括 20 次插入7 次删除
  1. 14 7
      rlp/encode.go
  2. 6 0
      rlp/encode_test.go

+ 14 - 7
rlp/encode.go

@@ -203,8 +203,13 @@ func (w *encbuf) encodeStringHeader(size int) {
 }
 
 func (w *encbuf) encodeString(b []byte) {
-	w.encodeStringHeader(len(b))
-	w.str = append(w.str, b...)
+	if len(b) == 1 && b[0] <= 0x7F {
+		// fits single byte, no string header
+		w.str = append(w.str, b[0])
+	} else {
+		w.encodeStringHeader(len(b))
+		w.str = append(w.str, b...)
+	}
 }
 
 func (w *encbuf) list() *listhead {
@@ -404,9 +409,6 @@ func writeBigInt(i *big.Int, w *encbuf) error {
 		return fmt.Errorf("rlp: cannot encode negative *big.Int")
 	} else if cmp == 0 {
 		w.str = append(w.str, 0x80)
-	} else if bits := i.BitLen(); bits < 8 {
-		// fits single byte
-		w.str = append(w.str, byte(i.Uint64()))
 	} else {
 		w.encodeString(i.Bytes())
 	}
@@ -434,8 +436,13 @@ func writeByteArray(val reflect.Value, w *encbuf) error {
 
 func writeString(val reflect.Value, w *encbuf) error {
 	s := val.String()
-	w.encodeStringHeader(len(s))
-	w.str = append(w.str, s...)
+	if len(s) == 1 && s[0] <= 0x7f {
+		// fits single byte, no string header
+		w.str = append(w.str, s[0])
+	} else {
+		w.encodeStringHeader(len(s))
+		w.str = append(w.str, s...)
+	}
 	return nil
 }
 

+ 6 - 0
rlp/encode_test.go

@@ -103,12 +103,18 @@ var encTests = []encTest{
 
 	// byte slices, strings
 	{val: []byte{}, output: "80"},
+	{val: []byte{0x7E}, output: "7E"},
+	{val: []byte{0x7F}, output: "7F"},
+	{val: []byte{0x80}, output: "8180"},
 	{val: []byte{1, 2, 3}, output: "83010203"},
 
 	{val: []namedByteType{1, 2, 3}, output: "83010203"},
 	{val: [...]namedByteType{1, 2, 3}, output: "83010203"},
 
 	{val: "", output: "80"},
+	{val: "\x7E", output: "7E"},
+	{val: "\x7F", output: "7F"},
+	{val: "\x80", output: "8180"},
 	{val: "dog", output: "83646F67"},
 	{
 		val:    "Lorem ipsum dolor sit amet, consectetur adipisicing eli",