From 641f174f48b4b1cb5471331c7c77554c1b271206 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 20 Jun 2017 11:57:08 -0700 Subject: [PATCH 1/2] Store the multihash length as an uint32. Some code constructs prefixes with negative lengths which means: 1. `cid1.Bytes() == cid2.Bytes()` does not imply `cid1.Prefix() == cid2.Prefix()`. 2. `Prefix.Bytes()` is broken. This commit fixes those issues by simply forbidding negative hash lengths in `Prefix` and providing nice constructors that lookup the default hash length. This is clearly a breaking change. --- cid.go | 31 ++++++++++++++++++++++++---- cid_test.go | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/cid.go b/cid.go index eb426ed..be0e0b6 100644 --- a/cid.go +++ b/cid.go @@ -25,6 +25,7 @@ import ( "encoding/json" "errors" "fmt" + "math" "strings" mbase "github.com/multiformats/go-multibase" @@ -123,6 +124,24 @@ func NewCidV1(codecType uint64, mhash mh.Multihash) *Cid { } } +func NewPrefixV0(mhType uint64) Prefix { + return Prefix{ + MhType: mhType, + MhLength: uint32(mh.DefaultLengths[mhType]), + Version: 0, + Codec: DagProtobuf, + } +} + +func NewPrefixV1(codecType uint64, mhType uint64) Prefix { + return Prefix{ + MhType: mhType, + MhLength: uint32(mh.DefaultLengths[mhType]), + Version: 1, + Codec: codecType, + } +} + // Cid represents a self-describing content adressed // identifier. It is formed by a Version, a Codec (which indicates // a multicodec-packed content type) and a Multihash. @@ -390,7 +409,7 @@ func (c *Cid) Prefix() Prefix { dec, _ := mh.Decode(c.hash) // assuming we got a valid multiaddr, this will not error return Prefix{ MhType: dec.Code, - MhLength: dec.Length, + MhLength: uint32(dec.Length), Version: c.version, Codec: c.codec, } @@ -404,13 +423,13 @@ type Prefix struct { Version uint64 Codec uint64 MhType uint64 - MhLength int + MhLength uint32 } // Sum uses the information in a prefix to perform a multihash.Sum() // and return a newly constructed Cid with the resulting multihash. func (p Prefix) Sum(data []byte) (*Cid, error) { - hash, err := mh.Sum(data, p.MhType, p.MhLength) + hash, err := mh.Sum(data, p.MhType, int(p.MhLength)) if err != nil { return nil, err } @@ -461,10 +480,14 @@ func PrefixFromBytes(buf []byte) (Prefix, error) { return Prefix{}, err } + if mhlen > math.MaxInt32 { + return Prefix{}, errors.New("digest too long, supporting only <= 2^31-1") + } + return Prefix{ Version: vers, Codec: codec, MhType: mhtype, - MhLength: int(mhlen), + MhLength: uint32(mhlen), }, nil } diff --git a/cid_test.go b/cid_test.go index 11cdb63..b7bdd89 100644 --- a/cid_test.go +++ b/cid_test.go @@ -189,6 +189,64 @@ func TestV0ErrorCases(t *testing.T) { } } +func TestNewPrefixV1(t *testing.T) { + data := []byte("this is some test content") + + // Construct c1 + prefix := NewPrefixV1(DagCBOR, mh.SHA2_256) + c1, err := prefix.Sum(data) + if err != nil { + t.Fatal(err) + } + + if c1.Prefix() != prefix { + t.Fatal("prefix not preserved") + } + + // Construct c2 + hash, err := mh.Sum(data, mh.SHA2_256, -1) + if err != nil { + t.Fatal(err) + } + c2 := NewCidV1(DagCBOR, hash) + + if !c1.Equals(c2) { + t.Fatal("cids mismatch") + } + if c1.Prefix() != c2.Prefix() { + t.Fatal("prefixes mismatch") + } +} + +func TestNewPrefixV0(t *testing.T) { + data := []byte("this is some test content") + + // Construct c1 + prefix := NewPrefixV0(mh.SHA2_256) + c1, err := prefix.Sum(data) + if err != nil { + t.Fatal(err) + } + + if c1.Prefix() != prefix { + t.Fatal("prefix not preserved") + } + + // Construct c2 + hash, err := mh.Sum(data, mh.SHA2_256, -1) + if err != nil { + t.Fatal(err) + } + c2 := NewCidV0(hash) + + if !c1.Equals(c2) { + t.Fatal("cids mismatch") + } + if c1.Prefix() != c2.Prefix() { + t.Fatal("prefixes mismatch") + } +} + func TestPrefixRoundtrip(t *testing.T) { data := []byte("this is some test content") hash, _ := mh.Sum(data, mh.SHA2_256, -1) From b7f0912618e44103a04394f379fd0594df3103af Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 12 Jul 2017 13:52:36 -0700 Subject: [PATCH 2/2] gx publish 0.8.0 --- .gx/lastpubver | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gx/lastpubver b/.gx/lastpubver index 1be0bb7..fc46413 100644 --- a/.gx/lastpubver +++ b/.gx/lastpubver @@ -1 +1 @@ -0.7.17: QmTprEaAA2A9bst5XH7exuyi5KzNMK3SEDNN8rBDnKWcUS +0.8.0: QmRwpQU6ysjKZoTFtZ2PhajRatNVwTBR6TbfLkaGMb5xDf diff --git a/package.json b/package.json index 7e63e51..2183df1 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,6 @@ "license": "MIT", "name": "go-cid", "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", - "version": "0.7.17" + "version": "0.8.0" }