Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToon Claes <toon@gitlab.com>2022-07-12 18:31:16 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2022-07-18 12:04:56 +0300
commitb3d0d5c58218b5ec9b7dac6fd1accbce42839779 (patch)
treeb6cd22691f493006f0c3f6eea42a2b8521487db5
parente2ea91705833e60c11600651a60be497e751c806 (diff)
git: Add package that handles sha256 hashes
SHA256 hashes are 64 hexadecimal characters, compared to the 40 chars for SHA1. This change adds validators for this longer object format.
-rw-r--r--internal/git/sha256/id.go36
-rw-r--r--internal/git/sha256/id_test.go106
2 files changed, 142 insertions, 0 deletions
diff --git a/internal/git/sha256/id.go b/internal/git/sha256/id.go
new file mode 100644
index 000000000..42a4a7c5f
--- /dev/null
+++ b/internal/git/sha256/id.go
@@ -0,0 +1,36 @@
+package sha256
+
+import (
+ "fmt"
+ "regexp"
+
+ "gitlab.com/gitlab-org/gitaly/v15/internal/git"
+)
+
+const (
+ // EmptyTreeOID is the Git tree object sha256 hash that corresponds to an empty tree (directory)
+ EmptyTreeOID = git.ObjectID("6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321")
+)
+
+var objectIDRegex = regexp.MustCompile(`\A[0-9a-f]{64}\z`)
+
+// NewObjectIDFromHex constructs a new ObjectID from the given hex
+// representation of the object ID. Returns ErrInvalidObjectID if the given
+// OID is not valid.
+func NewObjectIDFromHex(hex string) (git.ObjectID, error) {
+ if err := ValidateObjectID(hex); err != nil {
+ return "", err
+ }
+ return git.ObjectID(hex), nil
+}
+
+// ValidateObjectID checks if id is a syntactically correct object ID. Abbreviated
+// object IDs are not deemed to be valid. Returns an ErrInvalidObjectID if the
+// id is not valid.
+func ValidateObjectID(id string) error {
+ if objectIDRegex.MatchString(id) {
+ return nil
+ }
+
+ return fmt.Errorf("%w: %q", git.ErrInvalidObjectID, id)
+}
diff --git a/internal/git/sha256/id_test.go b/internal/git/sha256/id_test.go
new file mode 100644
index 000000000..1be75e98f
--- /dev/null
+++ b/internal/git/sha256/id_test.go
@@ -0,0 +1,106 @@
+package sha256
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestValidateObjectID(t *testing.T) {
+ for _, tc := range []struct {
+ desc string
+ oid string
+ valid bool
+ }{
+ {
+ desc: "valid object ID",
+ oid: "cff96308c1b0c36602ca031013b563074edddb203efa61c4f01be1bd2482d92e",
+ valid: true,
+ },
+ {
+ desc: "object ID with non-hex characters fails",
+ oid: "xff96308c1b0c36602ca031013b563074edddb203efa61c4f01be1bd2482d92e",
+ valid: false,
+ },
+ {
+ desc: "object ID with upper-case letters fails",
+ oid: "CFF96308C1B0C36602CA031013B563074EDDDB203EFA61C4F01BE1BD2482D92E",
+ valid: false,
+ },
+ {
+ desc: "too short object ID fails",
+ oid: "cff96308c1b0c36602ca031013b563074edddb203efa61c4f01be1bd2482d92",
+ valid: false,
+ },
+ {
+ desc: "too long object ID fails",
+ oid: "cff96308c1b0c36602ca031013b563074edddb203efa61c4f01be1bd2482d92eb",
+ valid: false,
+ },
+ {
+ desc: "empty string fails",
+ oid: "",
+ valid: false,
+ },
+ } {
+ t.Run(tc.desc, func(t *testing.T) {
+ err := ValidateObjectID(tc.oid)
+ if tc.valid {
+ require.NoError(t, err)
+ } else {
+ require.Error(t, err)
+ require.EqualError(t, err, fmt.Sprintf("invalid object ID: %q", tc.oid))
+ }
+ })
+ }
+}
+
+func TestNewObjectIDFromHex(t *testing.T) {
+ for _, tc := range []struct {
+ desc string
+ oid string
+ valid bool
+ }{
+ {
+ desc: "valid object ID",
+ oid: "cff96308c1b0c36602ca031013b563074edddb203efa61c4f01be1bd2482d92e",
+ valid: true,
+ },
+ {
+ desc: "object ID with non-hex characters fails",
+ oid: "xff96308c1b0c36602ca031013b563074edddb203efa61c4f01be1bd2482d92e",
+ valid: false,
+ },
+ {
+ desc: "object ID with upper-case letters fails",
+ oid: "CFF96308C1B0C36602CA031013B563074EDDDB203EFA61C4F01BE1BD2482D92E",
+ valid: false,
+ },
+ {
+ desc: "too short object ID fails",
+ oid: "cff96308c1b0c36602ca031013b563074edddb203efa61c4f01be1bd2482d92",
+ valid: false,
+ },
+ {
+ desc: "too long object ID fails",
+ oid: "cff96308c1b0c36602ca031013b563074edddb203efa61c4f01be1bd2482d92eb",
+ valid: false,
+ },
+ {
+ desc: "empty string fails",
+ oid: "",
+ valid: false,
+ },
+ } {
+ t.Run(tc.desc, func(t *testing.T) {
+ oid, err := NewObjectIDFromHex(tc.oid)
+ if tc.valid {
+ require.NoError(t, err)
+ require.Equal(t, tc.oid, oid.String())
+ } else {
+ require.Error(t, err)
+ }
+ })
+ }
+}