Files
Gitea/modules/git/object_format.go
T
2026-09-19 12:41:41 +00:00

118 lines
4.0 KiB
Go

// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package git
import (
"crypto/sha1"
"crypto/sha256"
"strconv"
)
type ObjectFormat interface {
// Name returns the name of the object format
Name() string
// EmptyObjectID creates a new empty ObjectID from an object format hash name
EmptyObjectID() ObjectID
// EmptyTree is the hash of an empty tree
EmptyTree() ObjectID
// FullLength is the length of the hash's hex string
FullLength() int
// MustID creates a new ObjectID from a byte slice
MustID(b []byte) ObjectID
// ComputeHash compute the hash for a given ObjectType and content
ComputeHash(t ObjectType, content []byte) ObjectID
}
type Sha1ObjectFormatImpl struct{}
var (
emptySha1ObjectID = &Sha1Hash{}
// emptySha1Tree: 4b825dc642cb6eb9a060e54bf8d69288fbee4904
emptySha1Tree = &Sha1Hash{0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04}
)
func (Sha1ObjectFormatImpl) Name() string { return "sha1" }
func (Sha1ObjectFormatImpl) EmptyObjectID() ObjectID { return emptySha1ObjectID }
func (Sha1ObjectFormatImpl) EmptyTree() ObjectID { return emptySha1Tree }
func (Sha1ObjectFormatImpl) FullLength() int { return 40 }
func (Sha1ObjectFormatImpl) MustID(b []byte) ObjectID {
var id Sha1Hash
copy(id[0:20], b)
return &id
}
// ComputeHash compute the hash for a given ObjectType and content
func (h Sha1ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID {
hasher := sha1.New()
_, _ = hasher.Write(t.Bytes())
_, _ = hasher.Write([]byte(" "))
_, _ = hasher.Write([]byte(strconv.FormatInt(int64(len(content)), 10)))
_, _ = hasher.Write([]byte{0})
_, _ = hasher.Write(content)
return h.MustID(hasher.Sum(nil))
}
type Sha256ObjectFormatImpl struct{}
var (
emptySha256ObjectID = &Sha256Hash{}
emptySha256Tree = &Sha256Hash{
0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1,
0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5,
0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc,
0x53, 0x21,
}
)
func (Sha256ObjectFormatImpl) Name() string { return "sha256" }
func (Sha256ObjectFormatImpl) EmptyObjectID() ObjectID { return emptySha256ObjectID }
func (Sha256ObjectFormatImpl) EmptyTree() ObjectID { return emptySha256Tree }
func (Sha256ObjectFormatImpl) FullLength() int { return 64 }
func (Sha256ObjectFormatImpl) MustID(b []byte) ObjectID {
var id Sha256Hash
copy(id[0:32], b)
return &id
}
// ComputeHash compute the hash for a given ObjectType and content
func (h Sha256ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID {
hasher := sha256.New()
_, _ = hasher.Write(t.Bytes())
_, _ = hasher.Write([]byte(" "))
_, _ = hasher.Write([]byte(strconv.FormatInt(int64(len(content)), 10)))
_, _ = hasher.Write([]byte{0})
_, _ = hasher.Write(content)
return h.MustID(hasher.Sum(nil))
}
type invalidObjectFormatImpl struct{}
func (h invalidObjectFormatImpl) Name() string { return "invalid-object-format" }
func (h invalidObjectFormatImpl) EmptyObjectID() ObjectID { return &Sha1Hash{} }
func (h invalidObjectFormatImpl) EmptyTree() ObjectID { return h.EmptyObjectID() }
func (h invalidObjectFormatImpl) FullLength() int { return len(h.EmptyObjectID().RawValue()) * 2 }
func (h invalidObjectFormatImpl) MustID(b []byte) ObjectID { return h.EmptyObjectID() }
func (h invalidObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID {
return h.EmptyObjectID()
}
var (
Sha1ObjectFormat ObjectFormat = Sha1ObjectFormatImpl{}
Sha256ObjectFormat ObjectFormat = Sha256ObjectFormatImpl{}
invalidObjectFormat ObjectFormat = invalidObjectFormatImpl{}
)
func ObjectFormatFromName(name string) ObjectFormat {
for _, objectFormat := range DefaultFeatures().SupportedObjectFormats {
if name == objectFormat.Name() {
return objectFormat
}
}
return invalidObjectFormat
}
func IsValidObjectFormat(name string) bool {
return ObjectFormatFromName(name) != invalidObjectFormat
}