From e6b3be460840f1f982d5358198466e7d6f509d21 Mon Sep 17 00:00:00 2001 From: zeripath Date: Sun, 4 Sep 2022 11:47:56 +0100 Subject: Add more checks in migration code (#21011) When migrating add several more important sanity checks: * SHAs must be SHAs * Refs must be valid Refs * URLs must be reasonable Signed-off-by: Andrew Thornton Signed-off-by: Andrew Thornton Co-authored-by: techknowlogick --- modules/git/ref.go | 28 +++++++++++++++++++++++++++- modules/git/repo_commit_nogogit.go | 2 +- modules/git/sha1.go | 7 ++++++- 3 files changed, 34 insertions(+), 3 deletions(-) (limited to 'modules/git') diff --git a/modules/git/ref.go b/modules/git/ref.go index 9fd071ce58..2f459148a2 100644 --- a/modules/git/ref.go +++ b/modules/git/ref.go @@ -4,7 +4,10 @@ package git -import "strings" +import ( + "regexp" + "strings" +) const ( // RemotePrefix is the base directory of the remotes information of git. @@ -15,6 +18,29 @@ const ( pullLen = len(PullPrefix) ) +// refNamePatternInvalid is regular expression with unallowed characters in git reference name +// They cannot have ASCII control characters (i.e. bytes whose values are lower than \040, or \177 DEL), space, tilde ~, caret ^, or colon : anywhere. +// They cannot have question-mark ?, asterisk *, or open bracket [ anywhere +var refNamePatternInvalid = regexp.MustCompile( + `[\000-\037\177 \\~^:?*[]|` + // No absolutely invalid characters + `(?:^[/.])|` + // Not HasPrefix("/") or "." + `(?:/\.)|` + // no "/." + `(?:\.lock$)|(?:\.lock/)|` + // No ".lock/"" or ".lock" at the end + `(?:\.\.)|` + // no ".." anywhere + `(?://)|` + // no "//" anywhere + `(?:@{)|` + // no "@{" + `(?:[/.]$)|` + // no terminal '/' or '.' + `(?:^@$)`) // Not "@" + +// IsValidRefPattern ensures that the provided string could be a valid reference +func IsValidRefPattern(name string) bool { + return !refNamePatternInvalid.MatchString(name) +} + +func SanitizeRefPattern(name string) string { + return refNamePatternInvalid.ReplaceAllString(name, "_") +} + // Reference represents a Git ref. type Reference struct { Name string diff --git a/modules/git/repo_commit_nogogit.go b/modules/git/repo_commit_nogogit.go index e528af0ffb..efea307b37 100644 --- a/modules/git/repo_commit_nogogit.go +++ b/modules/git/repo_commit_nogogit.go @@ -138,7 +138,7 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id SHA1) (*Co // ConvertToSHA1 returns a Hash object from a potential ID string func (repo *Repository) ConvertToSHA1(commitID string) (SHA1, error) { - if len(commitID) == 40 && SHAPattern.MatchString(commitID) { + if len(commitID) == 40 && IsValidSHAPattern(commitID) { sha1, err := NewIDFromString(commitID) if err == nil { return sha1, nil diff --git a/modules/git/sha1.go b/modules/git/sha1.go index 2da74733df..15f282c6e4 100644 --- a/modules/git/sha1.go +++ b/modules/git/sha1.go @@ -19,7 +19,12 @@ const EmptySHA = "0000000000000000000000000000000000000000" const EmptyTreeSHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904" // SHAPattern can be used to determine if a string is an valid sha -var SHAPattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`) +var shaPattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`) + +// IsValidSHAPattern will check if the provided string matches the SHA Pattern +func IsValidSHAPattern(sha string) bool { + return shaPattern.MatchString(sha) +} // MustID always creates a new SHA1 from a [20]byte array with no validation of input. func MustID(b []byte) SHA1 { -- cgit v1.2.3