Skip to content

Commit

Permalink
Revive TestSmallerLengthHashID, and add a special case for identity m…
Browse files Browse the repository at this point in the history
…ultihash that rejects truncations.

See #136 (comment)
for discussion.

This change means Sum behaves slightly differently for identity
multihashes than it does for any other multihash.  I'm not keeping
score on the number of ways identity multihash is weird anymore,
just documenting it and keeping tests passing.

The error message is lifted from the old `sumID` function verbatim.
  • Loading branch information
warpfork committed Mar 10, 2021
1 parent cbd218c commit 393ba0d
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
7 changes: 7 additions & 0 deletions sum.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package multihash

import (
"errors"
"fmt"
)

// ErrSumNotSupported is returned when the Sum function code is not implemented
Expand All @@ -27,13 +28,19 @@ func Sum(data []byte, code uint64, length int) (Multihash, error) {
sum := hasher.Sum(nil)

// Deal with any truncation.
// Unless it's an identity multihash. Those have different rules.
if length < 0 {
length = hasher.Size()
}
if len(sum) < length {
return nil, ErrLenTooLarge
}
if length >= 0 {
if code == IDENTITY {
if length != len(sum) {
return nil, fmt.Errorf("the length of the identity hash (%d) must be equal to the length of the data (%d)", length, len(sum))
}
}
sum = sum[:length]
}

Expand Down
27 changes: 27 additions & 0 deletions sum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,33 @@ func BenchmarkBlake2B(b *testing.B) {
}
}

func TestSmallerLengthHashID(t *testing.T) {

data := []byte("Identity hash input data.")
dataLength := len(data)

// Normal case: `length == len(data)`.
_, err := multihash.Sum(data, multihash.ID, dataLength)
if err != nil {
t.Fatal(err)
}

// Unconstrained length (-1): also allowed.
_, err = multihash.Sum(data, multihash.ID, -1)
if err != nil {
t.Fatal(err)
}

// Any other variation of those two scenarios should fail.
for l := (dataLength - 1); l >= 0; l-- {
_, err = multihash.Sum(data, multihash.ID, l)
if err == nil {
t.Fatal(fmt.Sprintf("identity hash of length %d smaller than data length %d didn't fail",
l, dataLength))
}
}
}

func TestTooLargeLength(t *testing.T) {
_, err := multihash.Sum([]byte("test"), multihash.SHA2_256, 33)
if err != multihash.ErrLenTooLarge {
Expand Down

0 comments on commit 393ba0d

Please sign in to comment.