Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API to get single commit via SHA and Ref #10915

Merged
merged 12 commits into from
Apr 8, 2020
Prev Previous commit
Next Next commit
add Validation Checks
  • Loading branch information
6543 committed Apr 5, 2020
commit 5b72c19322e810b9dc051e7ad44f28a84742c1c7
4 changes: 4 additions & 0 deletions modules/git/sha1.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package git
import (
"encoding/hex"
"fmt"
"regexp"
"strings"

"github.com/go-git/go-git/v5/plumbing"
Expand All @@ -16,6 +17,9 @@ import (
// EmptySHA defines empty git SHA
const EmptySHA = "0000000000000000000000000000000000000000"

// SHAPattern can be used to determine if a string is an valid sha
var SHAPattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`)

// SHA1 a git commit name
type SHA1 = plumbing.Hash

Expand Down
40 changes: 25 additions & 15 deletions modules/validation/binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,32 @@ const (
)

var (
// GitRefNamePattern is regular expression with unallowed characters in git reference name
// GitRefNamePatternInvalid 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
GitRefNamePattern = regexp.MustCompile(`[\000-\037\177 \\~^:?*[]+`)
GitRefNamePatternInvalid = regexp.MustCompile(`[\000-\037\177 \\~^:?*[]+`)
)

// CheckGitRefAdditionalRulesValid check name is valid on additional rules
func CheckGitRefAdditionalRulesValid(name string) bool {

// Additional rules as described at https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html
if strings.HasPrefix(name, "/") || strings.HasSuffix(name, "/") ||
strings.HasSuffix(name, ".") || strings.Contains(name, "..") ||
strings.Contains(name, "//") || strings.Contains(name, "@{") ||
name == "@" {
return false
}
parts := strings.Split(name, "/")
for _, part := range parts {
if strings.HasSuffix(part, ".lock") || strings.HasPrefix(part, ".") {
return false
}
}

return true
}

// AddBindingRules adds additional binding rules
func AddBindingRules() {
addGitRefNameBindingRule()
Expand All @@ -44,25 +64,15 @@ func addGitRefNameBindingRule() {
IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) {
str := fmt.Sprintf("%v", val)

if GitRefNamePattern.MatchString(str) {
if GitRefNamePatternInvalid.MatchString(str) {
errs.Add([]string{name}, ErrGitRefName, "GitRefName")
return false, errs
}
// Additional rules as described at https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html
if strings.HasPrefix(str, "/") || strings.HasSuffix(str, "/") ||
strings.HasSuffix(str, ".") || strings.Contains(str, "..") ||
strings.Contains(str, "//") || strings.Contains(str, "@{") ||
str == "@" {

if !CheckGitRefAdditionalRulesValid(str) {
errs.Add([]string{name}, ErrGitRefName, "GitRefName")
return false, errs
}
parts := strings.Split(str, "/")
for _, part := range parts {
if strings.HasSuffix(part, ".lock") || strings.HasPrefix(part, ".") {
errs.Add([]string{name}, ErrGitRefName, "GitRefName")
return false, errs
}
}

return true, errs
},
Expand Down
18 changes: 12 additions & 6 deletions routers/api/v1/repo/commits.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package repo

import (
"fmt"
"math"
"net/http"
"strconv"
Expand All @@ -16,6 +17,7 @@ import (
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/validation"
"code.gitea.io/gitea/routers/api/v1/utils"
)

Expand Down Expand Up @@ -45,12 +47,14 @@ func GetSingleCommitBySHA(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/Commit"
// "422":
// "$ref": "#/responses/validationError"
// "404":
// "$ref": "#/responses/notFound"

sha := ctx.Params(":sha")
if len(sha) == 0 {
ctx.Error(http.StatusBadRequest, "ref not given", nil)
if !git.SHAPattern.MatchString(sha) {
ctx.Error(http.StatusUnprocessableEntity, "no valid sha", fmt.Sprintf("no valid sha: %s", sha))
return
}
getCommit(ctx, sha)
Expand Down Expand Up @@ -82,16 +86,18 @@ func GetSingleCommitByRef(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/Commit"
// "400":
// "$ref": "#/responses/error"
// "422":
// "$ref": "#/responses/validationError"
// "404":
// "$ref": "#/responses/notFound"

ref := ctx.Params("ref")
if len(ref) == 0 {
ctx.Error(http.StatusBadRequest, "ref not given", nil)

if validation.GitRefNamePatternInvalid.MatchString(ref) || !validation.CheckGitRefAdditionalRulesValid(ref) {
ctx.Error(http.StatusUnprocessableEntity, "no valid sha", fmt.Sprintf("no valid ref: %s", ref))
return
}

getCommit(ctx, ref)
}

Expand Down
9 changes: 6 additions & 3 deletions templates/swagger/v1_json.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2548,11 +2548,11 @@
"200": {
"$ref": "#/responses/Commit"
},
"400": {
"$ref": "#/responses/error"
},
"404": {
"$ref": "#/responses/notFound"
},
"422": {
"$ref": "#/responses/validationError"
}
}
}
Expand Down Expand Up @@ -3052,6 +3052,9 @@
},
"404": {
"$ref": "#/responses/notFound"
},
"422": {
"$ref": "#/responses/validationError"
}
}
}
Expand Down