blob: d38aaf4d860d9b6f545048bdf1bd3d0cddae1cb1 (
about) (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
package reading
import (
"encoding/binary"
"fmt"
)
const (
idxMagicV2 = 0xff744f63
idxVersionV2 = 2
)
// parse validates mapped idx v2 structure and stores table boundaries.
func (index *idxFile) parse() error {
hashSize := index.algo.Size()
if hashSize <= 0 {
return fmt.Errorf("objectstore/packed: idx %q has invalid hash algorithm", index.idxName)
}
minLen := 8 + 256*4 + 2*hashSize
if len(index.data) < minLen {
return fmt.Errorf("objectstore/packed: idx %q too short", index.idxName)
}
if binary.BigEndian.Uint32(index.data[:4]) != idxMagicV2 {
return fmt.Errorf("objectstore/packed: idx %q invalid magic", index.idxName)
}
if binary.BigEndian.Uint32(index.data[4:8]) != idxVersionV2 {
return fmt.Errorf("objectstore/packed: idx %q unsupported version", index.idxName)
}
prev := uint32(0)
for i := range 256 {
base := 8 + i*4
cur := binary.BigEndian.Uint32(index.data[base : base+4])
if cur < prev {
return fmt.Errorf("objectstore/packed: idx %q has non-monotonic fanout table", index.idxName)
}
index.fanout[i] = cur
prev = cur
}
index.numObjects = int(index.fanout[255])
if index.numObjects < 0 {
return fmt.Errorf("objectstore/packed: idx %q has invalid object count", index.idxName)
}
namesBytes := index.numObjects * hashSize
crcBytes := index.numObjects * 4
offset32Bytes := index.numObjects * 4
minSize := 8 + 256*4 + namesBytes + crcBytes + offset32Bytes + 2*hashSize
if minSize < 0 || len(index.data) < minSize {
return fmt.Errorf("objectstore/packed: idx %q has truncated tables", index.idxName)
}
index.namesOffset = 8 + 256*4
index.offset32Offset = index.namesOffset + namesBytes + crcBytes
index.offset64Offset = index.offset32Offset + offset32Bytes
offset64Bytes := len(index.data) - index.offset64Offset - 2*hashSize
if offset64Bytes < 0 || offset64Bytes%8 != 0 {
return fmt.Errorf("objectstore/packed: idx %q has malformed 64-bit offset table", index.idxName)
}
index.offset64Count = offset64Bytes / 8
maxOffset64Count := max(index.numObjects-1, 0)
if index.offset64Count > maxOffset64Count {
return fmt.Errorf("objectstore/packed: idx %q has oversized 64-bit offset table", index.idxName)
}
return nil
}
|