Skip to content

Commit

Permalink
types: Prevent unmarshalHex panic on too-long input
Browse files Browse the repository at this point in the history
  • Loading branch information
lukechampine committed May 20, 2024
1 parent 0b8d963 commit f2102ae
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
29 changes: 29 additions & 0 deletions types/currency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package types
import (
"encoding/json"
"math"
"strings"
"testing"
)

Expand Down Expand Up @@ -754,3 +755,31 @@ func TestParseCurrency(t *testing.T) {
}
}
}

func TestUnmarshalHex(t *testing.T) {
for _, test := range []struct {
prefix string
data string
dstLen int
err string
}{
{"", strings.Repeat("0", 2), 1, ""},
{"", strings.Repeat("_", 2), 1, "decoding :<hex> failed: encoding/hex: invalid byte: U+005F '_'"},
{"ed25519", strings.Repeat("0", 62), 32, "decoding ed25519:<hex> failed: unexpected EOF"},
{"ed25519", strings.Repeat("0", 63), 32, "decoding ed25519:<hex> failed: encoding/hex: odd length hex string"},
{"ed25519", strings.Repeat("0", 64), 32, ""},
{"ed25519", strings.Repeat("0", 65), 32, "decoding ed25519:<hex> failed: input too long"},
} {
dst := make([]byte, test.dstLen)
err := unmarshalHex(dst, test.prefix, []byte(test.data))
if err == nil {
if test.err != "" {
t.Errorf("unmarshalHex(%s, %s) expected error %q, got nil", test.prefix, test.data, test.err)
}
} else {
if err.Error() != test.err {
t.Errorf("unmarshalHex(%s, %s) expected error %q, got %q", test.prefix, test.data, test.err, err)
}
}
}
}
8 changes: 6 additions & 2 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -812,8 +812,12 @@ func marshalHex(prefix string, data []byte) ([]byte, error) {
}

func unmarshalHex(dst []byte, prefix string, data []byte) error {
n, err := hex.Decode(dst, bytes.TrimPrefix(data, []byte(prefix+":")))
if n < len(dst) {
data = bytes.TrimPrefix(data, []byte(prefix+":"))
if len(data) > len(dst)*2 {
return fmt.Errorf("decoding %v:<hex> failed: input too long", prefix)
}
n, err := hex.Decode(dst, data)
if err == nil && n < len(dst) {
err = io.ErrUnexpectedEOF
}
if err != nil {
Expand Down

0 comments on commit f2102ae

Please sign in to comment.