Skip to content

Commit 771c488

Browse files
committed
gateway: fix: aliasing of hashes in car etag generation
1 parent 6e5756a commit 771c488

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

gateway/handler_car.go

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package gateway
22

33
import (
44
"context"
5+
"encoding/binary"
56
"fmt"
67
"io"
78
"net/http"
@@ -224,31 +225,43 @@ func getCarRootCidAndLastSegment(imPath path.ImmutablePath) (cid.Cid, string, er
224225
}
225226

226227
func getCarEtag(imPath path.ImmutablePath, params CarParams, rootCid cid.Cid) string {
227-
data := imPath.String()
228+
h := xxhash.New()
229+
h.WriteString(imPath.String())
230+
// be careful with hashes here, we need boundries and per entry salt, we don't want a request that has:
231+
// - scope = dfs
232+
// and:
233+
// - order = dfs
234+
// to result in the same hash because if we just do hash(scope + order) they would both yield hash("dfs").
228235
if params.Scope != DagScopeAll {
229-
data += string(params.Scope)
236+
h.WriteString("\x00scope=")
237+
h.WriteString(string(params.Scope))
230238
}
231239

232240
// 'order' from IPIP-412 impact Etag only if set to something else
233241
// than DFS (which is the implicit default)
234242
if params.Order != DagOrderDFS {
235-
data += string(params.Order)
243+
h.WriteString("\x00order=")
244+
h.WriteString(string(params.Order))
236245
}
237246

238247
// 'dups' from IPIP-412 impact Etag only if 'y'
239-
if dups := params.Duplicates.String(); dups == "y" {
240-
data += dups
248+
if dups := params.Duplicates; dups == DuplicateBlocksIncluded {
249+
h.WriteString("\x00dups=y")
241250
}
242251

243252
if params.Range != nil {
244253
if params.Range.From != 0 || params.Range.To != nil {
245-
data += strconv.FormatInt(params.Range.From, 10)
254+
h.WriteString("\x00range=")
255+
var b [8]byte
256+
binary.LittleEndian.PutUint64(b[:], uint64(params.Range.From))
257+
h.Write(b[:])
246258
if params.Range.To != nil {
247-
data += strconv.FormatInt(*params.Range.To, 10)
259+
binary.LittleEndian.PutUint64(b[:], uint64(*params.Range.To))
260+
h.Write(b[:])
248261
}
249262
}
250263
}
251264

252-
suffix := strconv.FormatUint(xxhash.Sum64([]byte(data)), 32)
265+
suffix := strconv.FormatUint(h.Sum64(), 32)
253266
return `W/"` + rootCid.String() + ".car." + suffix + `"`
254267
}

0 commit comments

Comments
 (0)