You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

binding.go 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package validation
  5. import (
  6. "fmt"
  7. "regexp"
  8. "strings"
  9. "github.com/go-macaron/binding"
  10. )
  11. const (
  12. // ErrGitRefName is git reference name error
  13. ErrGitRefName = "GitRefNameError"
  14. )
  15. var (
  16. // GitRefNamePattern is regular expression with unallowed characters in git reference name
  17. // They cannot have ASCII control characters (i.e. bytes whose values are lower than \040, or \177 DEL), space, tilde ~, caret ^, or colon : anywhere.
  18. // They cannot have question-mark ?, asterisk *, or open bracket [ anywhere
  19. GitRefNamePattern = regexp.MustCompile(`[\000-\037\177 \\~^:?*[]+`)
  20. )
  21. // AddBindingRules adds additional binding rules
  22. func AddBindingRules() {
  23. addGitRefNameBindingRule()
  24. addValidURLBindingRule()
  25. }
  26. func addGitRefNameBindingRule() {
  27. // Git refname validation rule
  28. binding.AddRule(&binding.Rule{
  29. IsMatch: func(rule string) bool {
  30. return strings.HasPrefix(rule, "GitRefName")
  31. },
  32. IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) {
  33. str := fmt.Sprintf("%v", val)
  34. if GitRefNamePattern.MatchString(str) {
  35. errs.Add([]string{name}, ErrGitRefName, "GitRefName")
  36. return false, errs
  37. }
  38. // Additional rules as described at https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html
  39. if strings.HasPrefix(str, "/") || strings.HasSuffix(str, "/") ||
  40. strings.HasSuffix(str, ".") || strings.Contains(str, "..") ||
  41. strings.Contains(str, "//") || strings.Contains(str, "@{") ||
  42. str == "@" {
  43. errs.Add([]string{name}, ErrGitRefName, "GitRefName")
  44. return false, errs
  45. }
  46. parts := strings.Split(str, "/")
  47. for _, part := range parts {
  48. if strings.HasSuffix(part, ".lock") || strings.HasPrefix(part, ".") {
  49. errs.Add([]string{name}, ErrGitRefName, "GitRefName")
  50. return false, errs
  51. }
  52. }
  53. return true, errs
  54. },
  55. })
  56. }
  57. func addValidURLBindingRule() {
  58. // URL validation rule
  59. binding.AddRule(&binding.Rule{
  60. IsMatch: func(rule string) bool {
  61. return strings.HasPrefix(rule, "ValidUrl")
  62. },
  63. IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) {
  64. str := fmt.Sprintf("%v", val)
  65. if len(str) != 0 && !IsValidURL(str) {
  66. errs.Add([]string{name}, binding.ERR_URL, "Url")
  67. return false, errs
  68. }
  69. return true, errs
  70. },
  71. })
  72. }
  73. func portOnly(hostport string) string {
  74. colon := strings.IndexByte(hostport, ':')
  75. if colon == -1 {
  76. return ""
  77. }
  78. if i := strings.Index(hostport, "]:"); i != -1 {
  79. return hostport[i+len("]:"):]
  80. }
  81. if strings.Contains(hostport, "]") {
  82. return ""
  83. }
  84. return hostport[colon+len(":"):]
  85. }
  86. func validPort(p string) bool {
  87. for _, r := range []byte(p) {
  88. if r < '0' || r > '9' {
  89. return false
  90. }
  91. }
  92. return true
  93. }