Commit 5ccc98a7 authored by Jeromy Johnson's avatar Jeromy Johnson Committed by GitHub

Merge pull request #7 from ipfs/feat/fuzz

Add fuzz tests, fix panic
parents eae3431c ba97b640
cid-fuzz.zip
...@@ -3,6 +3,7 @@ package cid ...@@ -3,6 +3,7 @@ package cid
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"errors"
"fmt" "fmt"
"strings" "strings"
...@@ -88,6 +89,23 @@ func Decode(v string) (*Cid, error) { ...@@ -88,6 +89,23 @@ func Decode(v string) (*Cid, error) {
return Cast(data) return Cast(data)
} }
var (
ErrVarintBuffSmall = errors.New("reading varint: buffer to small")
ErrVarintTooBig = errors.New("reading varint: varint bigger than 64bits" +
" and not supported")
)
func uvError(read int) error {
switch {
case read == 0:
return ErrVarintBuffSmall
case read < 0:
return ErrVarintTooBig
default:
return nil
}
}
func Cast(data []byte) (*Cid, error) { func Cast(data []byte) (*Cid, error) {
if len(data) == 34 && data[0] == 18 && data[1] == 32 { if len(data) == 34 && data[0] == 18 && data[1] == 32 {
h, err := mh.Cast(data) h, err := mh.Cast(data)
...@@ -103,11 +121,18 @@ func Cast(data []byte) (*Cid, error) { ...@@ -103,11 +121,18 @@ func Cast(data []byte) (*Cid, error) {
} }
vers, n := binary.Uvarint(data) vers, n := binary.Uvarint(data)
if err := uvError(n); err != nil {
return nil, err
}
if vers != 0 && vers != 1 { if vers != 0 && vers != 1 {
return nil, fmt.Errorf("invalid cid version number: %d", vers) return nil, fmt.Errorf("invalid cid version number: %d", vers)
} }
codec, cn := binary.Uvarint(data[n:]) codec, cn := binary.Uvarint(data[n:])
if err := uvError(cn); err != nil {
return nil, err
}
rest := data[n+cn:] rest := data[n+cn:]
h, err := mh.Cast(rest) h, err := mh.Cast(rest)
...@@ -162,10 +187,14 @@ func (c *Cid) bytesV0() []byte { ...@@ -162,10 +187,14 @@ func (c *Cid) bytesV0() []byte {
} }
func (c *Cid) bytesV1() []byte { func (c *Cid) bytesV1() []byte {
buf := make([]byte, 8+len(c.hash)) // two 8 bytes (max) numbers plus hash
buf := make([]byte, 2*binary.MaxVarintLen64+len(c.hash))
n := binary.PutUvarint(buf, c.version) n := binary.PutUvarint(buf, c.version)
n += binary.PutUvarint(buf[n:], c.codec) n += binary.PutUvarint(buf[n:], c.codec)
copy(buf[n:], c.hash) cn := copy(buf[n:], c.hash)
if cn != len(c.hash) {
panic("copy hash length is inconsistent")
}
return buf[:n+len(c.hash)] return buf[:n+len(c.hash)]
} }
...@@ -240,7 +269,7 @@ func (p Prefix) Sum(data []byte) (*Cid, error) { ...@@ -240,7 +269,7 @@ func (p Prefix) Sum(data []byte) (*Cid, error) {
} }
func (p Prefix) Bytes() []byte { func (p Prefix) Bytes() []byte {
buf := make([]byte, 16) buf := make([]byte, 4*binary.MaxVarintLen64)
n := binary.PutUvarint(buf, p.Version) n := binary.PutUvarint(buf, p.Version)
n += binary.PutUvarint(buf[n:], p.Codec) n += binary.PutUvarint(buf[n:], p.Codec)
n += binary.PutUvarint(buf[n:], uint64(p.MhType)) n += binary.PutUvarint(buf[n:], uint64(p.MhType))
......
// +build gofuzz
package cid
func Fuzz(data []byte) int {
cid, err := Cast(data)
if err != nil {
return 0
}
_ = cid.Bytes()
_ = cid.String()
p := cid.Prefix()
_ = p.Bytes()
if !cid.Equals(cid) {
panic("inequality")
}
// json loop
json, err := cid.MarshalJSON()
if err != nil {
panic(err.Error())
}
cid2 := &Cid{}
err = cid2.UnmarshalJSON(json)
if err != nil {
panic(err.Error())
}
if !cid.Equals(cid2) {
panic("json loop not equal")
}
return 1
}
...@@ -119,6 +119,15 @@ func TestPrefixRoundtrip(t *testing.T) { ...@@ -119,6 +119,15 @@ func TestPrefixRoundtrip(t *testing.T) {
} }
} }
func Test16BytesVarint(t *testing.T) {
data := []byte("this is some test content")
hash, _ := mh.Sum(data, mh.SHA2_256, -1)
c := NewCidV1(CBOR, hash)
c.codec = 1 << 63
_ = c.Bytes()
}
func TestFuzzCid(t *testing.T) { func TestFuzzCid(t *testing.T) {
buf := make([]byte, 128) buf := make([]byte, 128)
for i := 0; i < 200; i++ { for i := 0; i < 200; i++ {
......
 gD1e-D/q3~(7`8n
\ No newline at end of file
q -[ïh[ (ΰ[)D
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment