mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-20 07:35:00 +00:00
cc34c26172
* Fixes #39339 --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
143 lines
3.2 KiB
Go
143 lines
3.2 KiB
Go
// Copyright 2023 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package git
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"fmt"
|
|
|
|
"gitea.dev/modules/util"
|
|
)
|
|
|
|
type ObjectID interface {
|
|
String() string
|
|
RefName() RefName
|
|
IsZero() bool
|
|
RawValue() []byte
|
|
Type() ObjectFormat
|
|
}
|
|
|
|
type Sha1Hash [20]byte
|
|
|
|
var _ ObjectID = (*Sha1Hash)(nil)
|
|
|
|
func (h *Sha1Hash) String() string {
|
|
return hex.EncodeToString(h[:])
|
|
}
|
|
|
|
func (h *Sha1Hash) RefName() RefName {
|
|
return RefName(h.String())
|
|
}
|
|
|
|
func (h *Sha1Hash) IsZero() bool {
|
|
empty := Sha1Hash{}
|
|
return bytes.Equal(empty[:], h[:])
|
|
}
|
|
func (h *Sha1Hash) RawValue() []byte { return h[:] }
|
|
func (*Sha1Hash) Type() ObjectFormat { return Sha1ObjectFormat }
|
|
|
|
func MustIDFromString(hexHash string) ObjectID {
|
|
id, err := NewIDFromString(hexHash)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return id
|
|
}
|
|
|
|
type Sha256Hash [32]byte
|
|
|
|
var _ ObjectID = (*Sha256Hash)(nil)
|
|
|
|
func (h *Sha256Hash) String() string {
|
|
return hex.EncodeToString(h[:])
|
|
}
|
|
|
|
func (h *Sha256Hash) RefName() RefName {
|
|
return RefName(h.String())
|
|
}
|
|
|
|
func (h *Sha256Hash) IsZero() bool {
|
|
empty := Sha256Hash{}
|
|
return bytes.Equal(empty[:], h[:])
|
|
}
|
|
func (h *Sha256Hash) RawValue() []byte { return h[:] }
|
|
func (*Sha256Hash) Type() ObjectFormat { return Sha256ObjectFormat }
|
|
|
|
func NewIDFromString(hexHash string) (ObjectID, error) {
|
|
var theObjectFormat ObjectFormat
|
|
for _, objectFormat := range DefaultFeatures().SupportedObjectFormats {
|
|
if len(hexHash) == objectFormat.FullLength() {
|
|
theObjectFormat = objectFormat
|
|
break
|
|
}
|
|
}
|
|
|
|
if theObjectFormat == nil {
|
|
return nil, fmt.Errorf("length %d has no matched object format: %s", len(hexHash), hexHash)
|
|
}
|
|
|
|
b, err := hex.DecodeString(hexHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(b) != theObjectFormat.FullLength()/2 {
|
|
return theObjectFormat.EmptyObjectID(), fmt.Errorf("length must be %d: %v", theObjectFormat.FullLength(), b)
|
|
}
|
|
return theObjectFormat.MustID(b), nil
|
|
}
|
|
|
|
func IsEmptyCommitID(commitID string) bool {
|
|
if commitID == "" {
|
|
return true
|
|
}
|
|
|
|
id, err := NewIDFromString(commitID)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return id.IsZero()
|
|
}
|
|
|
|
// ComputeBlobHash compute the hash for a given blob content
|
|
func ComputeBlobHash(hashType ObjectFormat, content []byte) ObjectID {
|
|
return hashType.ComputeHash(ObjectBlob, content)
|
|
}
|
|
|
|
func IsStringValidObjectID(objFmt ObjectFormat, s string, optMinLen ...int) bool {
|
|
if objFmt == invalidObjectFormat {
|
|
return false
|
|
}
|
|
var minLen, maxLen int
|
|
if objFmt != nil {
|
|
maxLen = objFmt.FullLength()
|
|
minLen = util.OptionalArg(optMinLen, maxLen)
|
|
} else {
|
|
if len(optMinLen) == 0 {
|
|
// if no "min length" is applied, then the length must exactly match one of the formats
|
|
if len(s) != Sha1ObjectFormat.FullLength() && len(s) != Sha256ObjectFormat.FullLength() {
|
|
return false
|
|
}
|
|
}
|
|
maxLen = Sha256ObjectFormat.FullLength()
|
|
minLen = util.OptionalArg(optMinLen, Sha1ObjectFormat.FullLength())
|
|
}
|
|
if len(s) < minLen || len(s) > maxLen {
|
|
return false
|
|
}
|
|
return isStringLowerHex(s)
|
|
}
|
|
|
|
func isStringLowerHex(s string) bool {
|
|
for _, c := range s {
|
|
isHex := (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')
|
|
if !isHex {
|
|
return false
|
|
}
|
|
}
|
|
return len(s) > 0 // it accepts odd length because "shorten commit id" can be 7-chars
|
|
}
|