aboutsummaryrefslogtreecommitdiff
path: root/pack_pack.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2025-11-17 00:00:00 +0000
committerGravatar Runxi Yu2025-11-17 00:00:00 +0000
commit1dcb92427c23d0a8b23c0154b892243c749afa5a (patch)
tree0683fa19e05d2ea0ceac324dafdcd49eb6cdb2ec /pack_pack.go
parentAdd internal todo (diff)
signature
Compute checksum when reading packfiles
Diffstat (limited to 'pack_pack.go')
-rw-r--r--pack_pack.go24
1 files changed, 22 insertions, 2 deletions
diff --git a/pack_pack.go b/pack_pack.go
index 5c2c8628..6d740b73 100644
--- a/pack_pack.go
+++ b/pack_pack.go
@@ -487,7 +487,7 @@ type packFile struct {
closeMu sync.Once
}
-func openPackFile(absPath, rel string) (*packFile, error) {
+func openPackFile(absPath, rel string, hashSize int) (*packFile, error) {
f, err := os.Open(absPath)
if err != nil {
return nil, err
@@ -498,7 +498,7 @@ func openPackFile(absPath, rel string) (*packFile, error) {
_ = f.Close()
return nil, err
}
- if stat.Size() < 12 {
+ if stat.Size() < 12+int64(hashSize) {
_ = f.Close()
return nil, ErrInvalidObject
}
@@ -532,6 +532,26 @@ func openPackFile(absPath, rel string) (*packFile, error) {
_ = syscall.Munmap(region)
return nil, err
}
+
+ if len(region) < hashSize {
+ _ = syscall.Munmap(region)
+ return nil, ErrInvalidObject
+ }
+ dataEnd := len(region) - hashSize
+ checksumInFile := region[dataEnd:]
+
+ hashFn, ok := hashFuncs[hashSize]
+ if !ok {
+ _ = syscall.Munmap(region)
+ return nil, fmt.Errorf("furgit: unsupported hash size %d", hashSize)
+ }
+
+ computedHash := hashFn(region[:dataEnd])
+ if !bytes.Equal(computedHash.data[:hashSize], checksumInFile) {
+ _ = syscall.Munmap(region)
+ return nil, fmt.Errorf("furgit: pack checksum mismatch in %s", rel)
+ }
+
return &packFile{
relPath: rel,
size: stat.Size(),