aboutsummaryrefslogtreecommitdiffstats
path: root/modules/validation/binding.go
diff options
context:
space:
mode:
authorLauris BH <lauris@nix.lv>2017-04-19 06:02:20 +0300
committerBo-Yi Wu <appleboy.tw@gmail.com>2017-04-19 11:02:20 +0800
commitf42ec6120e8a2830407027020b65391ebf8e7f59 (patch)
treeaee67e8f44d105ef957b27fe3777e38aa034baa6 /modules/validation/binding.go
parent941281ae12f0df84ffc73c279dc9e55f058e4703 (diff)
downloadgitea-f42ec6120e8a2830407027020b65391ebf8e7f59.tar.gz
gitea-f42ec6120e8a2830407027020b65391ebf8e7f59.zip
Better URL validation (#1507)
* Add correct git branch name validation * Change git refname validation error constant name * Implement URL validation based on GoLang url.Parse method * Backward compatibility with older Go compiler * Add git reference name validation unit tests * Remove unused variable in unit test * Implement URL validation based on GoLang url.Parse method * Backward compatibility with older Go compiler * Add url validation unit tests
Diffstat (limited to 'modules/validation/binding.go')
-rw-r--r--modules/validation/binding.go102
1 files changed, 102 insertions, 0 deletions
diff --git a/modules/validation/binding.go b/modules/validation/binding.go
new file mode 100644
index 0000000000..783499e69a
--- /dev/null
+++ b/modules/validation/binding.go
@@ -0,0 +1,102 @@
+// 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"
+ "net/url"
+ "regexp"
+ "strings"
+
+ "github.com/go-macaron/binding"
+)
+
+const (
+ // ErrGitRefName is git reference name error
+ ErrGitRefName = "GitRefNameError"
+)
+
+var (
+ // GitRefNamePattern is regular expression wirh unallowed characters in git reference name
+ GitRefNamePattern = regexp.MustCompile("[^\\d\\w-_\\./]")
+)
+
+// AddBindingRules adds additional binding rules
+func AddBindingRules() {
+ addGitRefNameBindingRule()
+ addValidURLBindingRule()
+}
+
+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)
+
+ if GitRefNamePattern.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.HasPrefix(str, ".") || strings.HasSuffix(str, ".") ||
+ strings.HasSuffix(str, ".lock") ||
+ strings.Contains(str, "..") || strings.Contains(str, "//") {
+ 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 {
+ if u, err := url.ParseRequestURI(str); err != nil ||
+ (u.Scheme != "http" && u.Scheme != "https") ||
+ !validPort(portOnly(u.Host)) {
+ errs.Add([]string{name}, binding.ERR_URL, "Url")
+ return false, errs
+ }
+ }
+
+ return true, errs
+ },
+ })
+}
+
+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
+}