Files
Atay-Makhzan/modules/validation/binding.go
T

204 lines
5.2 KiB
Go
Raw Normal View History

2017-04-19 06:02:20 +03:00
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package validation
import (
"fmt"
"regexp"
"strings"
2021-01-26 23:36:53 +08:00
"gitea.com/go-chi/binding"
2019-09-09 08:48:21 +03:00
"github.com/gobwas/glob"
2017-04-19 06:02:20 +03:00
)
const (
// ErrGitRefName is git reference name error
ErrGitRefName = "GitRefNameError"
2019-09-09 08:48:21 +03:00
// ErrGlobPattern is returned when glob pattern is invalid
ErrGlobPattern = "GlobPattern"
2021-06-25 16:28:55 +02:00
// ErrRegexPattern is returned when a regex pattern is invalid
ErrRegexPattern = "RegexPattern"
2017-04-19 06:02:20 +03:00
)
var (
2020-04-08 04:54:46 +02:00
// GitRefNamePatternInvalid is regular expression with unallowed characters in git reference name
2019-03-26 15:59:48 -04:00
// 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
2020-04-08 04:54:46 +02:00
GitRefNamePatternInvalid = regexp.MustCompile(`[\000-\037\177 \\~^:?*[]+`)
2017-04-19 06:02:20 +03:00
)
2020-04-08 04:54:46 +02:00
// 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
}
2017-04-19 06:02:20 +03:00
// AddBindingRules adds additional binding rules
func AddBindingRules() {
addGitRefNameBindingRule()
addValidURLBindingRule()
2021-06-26 00:38:27 +02:00
addValidSiteURLBindingRule()
2019-09-09 08:48:21 +03:00
addGlobPatternRule()
2021-06-25 16:28:55 +02:00
addRegexPatternRule()
addGlobOrRegexPatternRule()
2017-04-19 06:02:20 +03:00
}
func addGitRefNameBindingRule() {
// Git refname validation rule
binding.AddRule(&binding.Rule{
IsMatch: func(rule string) bool {
return strings.HasPrefix(rule, "GitRefName")
},
IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) {
str := fmt.Sprintf("%v", val)
2020-04-08 04:54:46 +02:00
if GitRefNamePatternInvalid.MatchString(str) {
2017-04-19 06:02:20 +03:00
errs.Add([]string{name}, ErrGitRefName, "GitRefName")
return false, errs
}
2020-04-08 04:54:46 +02:00
if !CheckGitRefAdditionalRulesValid(str) {
2017-04-19 06:02:20 +03:00
errs.Add([]string{name}, ErrGitRefName, "GitRefName")
return false, errs
}
return true, errs
},
})
}
func addValidURLBindingRule() {
// URL validation rule
binding.AddRule(&binding.Rule{
IsMatch: func(rule string) bool {
return strings.HasPrefix(rule, "ValidUrl")
},
IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) {
str := fmt.Sprintf("%v", val)
if len(str) != 0 && !IsValidURL(str) {
errs.Add([]string{name}, binding.ERR_URL, "Url")
return false, errs
2017-04-19 06:02:20 +03:00
}
return true, errs
},
})
}
2021-06-26 00:38:27 +02:00
func addValidSiteURLBindingRule() {
// URL validation rule
binding.AddRule(&binding.Rule{
IsMatch: func(rule string) bool {
return strings.HasPrefix(rule, "ValidSiteUrl")
},
IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) {
str := fmt.Sprintf("%v", val)
if len(str) != 0 && !IsValidSiteURL(str) {
errs.Add([]string{name}, binding.ERR_URL, "Url")
return false, errs
}
return true, errs
},
})
}
2019-09-09 08:48:21 +03:00
func addGlobPatternRule() {
binding.AddRule(&binding.Rule{
IsMatch: func(rule string) bool {
return rule == "GlobPattern"
},
2021-06-25 16:28:55 +02:00
IsValid: globPatternValidator,
})
}
func globPatternValidator(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) {
str := fmt.Sprintf("%v", val)
if len(str) != 0 {
if _, err := glob.Compile(str); err != nil {
errs.Add([]string{name}, ErrGlobPattern, err.Error())
return false, errs
}
}
return true, errs
}
func addRegexPatternRule() {
binding.AddRule(&binding.Rule{
IsMatch: func(rule string) bool {
return rule == "RegexPattern"
},
IsValid: regexPatternValidator,
})
}
func regexPatternValidator(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) {
str := fmt.Sprintf("%v", val)
if _, err := regexp.Compile(str); err != nil {
errs.Add([]string{name}, ErrRegexPattern, err.Error())
return false, errs
}
return true, errs
}
func addGlobOrRegexPatternRule() {
binding.AddRule(&binding.Rule{
IsMatch: func(rule string) bool {
return rule == "GlobOrRegexPattern"
},
2019-09-09 08:48:21 +03:00
IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) {
2021-06-25 16:28:55 +02:00
str := strings.TrimSpace(fmt.Sprintf("%v", val))
2019-09-09 08:48:21 +03:00
2021-06-25 16:28:55 +02:00
if len(str) >= 2 && strings.HasPrefix(str, "/") && strings.HasSuffix(str, "/") {
return regexPatternValidator(errs, name, str[1:len(str)-1])
2019-09-09 08:48:21 +03:00
}
2021-06-25 16:28:55 +02:00
return globPatternValidator(errs, name, val)
2019-09-09 08:48:21 +03:00
},
})
}
2017-04-19 06:02:20 +03:00
func portOnly(hostport string) string {
colon := strings.IndexByte(hostport, ':')
if colon == -1 {
return ""
}
if i := strings.Index(hostport, "]:"); i != -1 {
return hostport[i+len("]:"):]
}
if strings.Contains(hostport, "]") {
return ""
}
return hostport[colon+len(":"):]
}
func validPort(p string) bool {
for _, r := range []byte(p) {
if r < '0' || r > '9' {
return false
}
}
return true
}