code.gitea.io/gitea@v1.22.3/modules/git/object_format.go (about) 1 // Copyright 2023 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package git 5 6 import ( 7 "crypto/sha1" 8 "crypto/sha256" 9 "regexp" 10 "strconv" 11 ) 12 13 // sha1Pattern can be used to determine if a string is an valid sha 14 var sha1Pattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`) 15 16 // sha256Pattern can be used to determine if a string is an valid sha 17 var sha256Pattern = regexp.MustCompile(`^[0-9a-f]{4,64}$`) 18 19 type ObjectFormat interface { 20 // Name returns the name of the object format 21 Name() string 22 // EmptyObjectID creates a new empty ObjectID from an object format hash name 23 EmptyObjectID() ObjectID 24 // EmptyTree is the hash of an empty tree 25 EmptyTree() ObjectID 26 // FullLength is the length of the hash's hex string 27 FullLength() int 28 // IsValid returns true if the input is a valid hash 29 IsValid(input string) bool 30 // MustID creates a new ObjectID from a byte slice 31 MustID(b []byte) ObjectID 32 // ComputeHash compute the hash for a given ObjectType and content 33 ComputeHash(t ObjectType, content []byte) ObjectID 34 } 35 36 type Sha1ObjectFormatImpl struct{} 37 38 var ( 39 emptySha1ObjectID = &Sha1Hash{} 40 emptySha1Tree = &Sha1Hash{ 41 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, 42 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04, 43 } 44 ) 45 46 func (Sha1ObjectFormatImpl) Name() string { return "sha1" } 47 func (Sha1ObjectFormatImpl) EmptyObjectID() ObjectID { 48 return emptySha1ObjectID 49 } 50 51 func (Sha1ObjectFormatImpl) EmptyTree() ObjectID { 52 return emptySha1Tree 53 } 54 func (Sha1ObjectFormatImpl) FullLength() int { return 40 } 55 func (Sha1ObjectFormatImpl) IsValid(input string) bool { 56 return sha1Pattern.MatchString(input) 57 } 58 59 func (Sha1ObjectFormatImpl) MustID(b []byte) ObjectID { 60 var id Sha1Hash 61 copy(id[0:20], b) 62 return &id 63 } 64 65 // ComputeHash compute the hash for a given ObjectType and content 66 func (h Sha1ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID { 67 hasher := sha1.New() 68 _, _ = hasher.Write(t.Bytes()) 69 _, _ = hasher.Write([]byte(" ")) 70 _, _ = hasher.Write([]byte(strconv.FormatInt(int64(len(content)), 10))) 71 _, _ = hasher.Write([]byte{0}) 72 _, _ = hasher.Write(content) 73 return h.MustID(hasher.Sum(nil)) 74 } 75 76 type Sha256ObjectFormatImpl struct{} 77 78 var ( 79 emptySha256ObjectID = &Sha256Hash{} 80 emptySha256Tree = &Sha256Hash{ 81 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1, 82 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5, 83 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc, 84 0x53, 0x21, 85 } 86 ) 87 88 func (Sha256ObjectFormatImpl) Name() string { return "sha256" } 89 func (Sha256ObjectFormatImpl) EmptyObjectID() ObjectID { 90 return emptySha256ObjectID 91 } 92 93 func (Sha256ObjectFormatImpl) EmptyTree() ObjectID { 94 return emptySha256Tree 95 } 96 func (Sha256ObjectFormatImpl) FullLength() int { return 64 } 97 func (Sha256ObjectFormatImpl) IsValid(input string) bool { 98 return sha256Pattern.MatchString(input) 99 } 100 101 func (Sha256ObjectFormatImpl) MustID(b []byte) ObjectID { 102 var id Sha256Hash 103 copy(id[0:32], b) 104 return &id 105 } 106 107 // ComputeHash compute the hash for a given ObjectType and content 108 func (h Sha256ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID { 109 hasher := sha256.New() 110 _, _ = hasher.Write(t.Bytes()) 111 _, _ = hasher.Write([]byte(" ")) 112 _, _ = hasher.Write([]byte(strconv.FormatInt(int64(len(content)), 10))) 113 _, _ = hasher.Write([]byte{0}) 114 _, _ = hasher.Write(content) 115 return h.MustID(hasher.Sum(nil)) 116 } 117 118 var ( 119 Sha1ObjectFormat ObjectFormat = Sha1ObjectFormatImpl{} 120 Sha256ObjectFormat ObjectFormat = Sha256ObjectFormatImpl{} 121 ) 122 123 func ObjectFormatFromName(name string) ObjectFormat { 124 for _, objectFormat := range DefaultFeatures().SupportedObjectFormats { 125 if name == objectFormat.Name() { 126 return objectFormat 127 } 128 } 129 return nil 130 } 131 132 func IsValidObjectFormat(name string) bool { 133 return ObjectFormatFromName(name) != nil 134 }