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

binding.go 4.4 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. "gitea.com/macaron/binding"
  10. "github.com/gobwas/glob"
  11. )
  12. const (
  13. // ErrGitRefName is git reference name error
  14. ErrGitRefName = "GitRefNameError"
  15. // ErrGlobPattern is returned when glob pattern is invalid
  16. ErrGlobPattern = "GlobPattern"
  17. ErrAlphaDashDotChinese = "AlphaDashDotChineseError"
  18. )
  19. var (
  20. // GitRefNamePatternInvalid is regular expression with unallowed characters in git reference name
  21. // They cannot have ASCII control characters (i.e. bytes whose values are lower than \040, or \177 DEL), space, tilde ~, caret ^, or colon : anywhere.
  22. // They cannot have question-mark ?, asterisk *, or open bracket [ anywhere
  23. GitRefNamePatternInvalid = regexp.MustCompile(`[\000-\037\177 \\~^:?*[]+`)
  24. AlphaDashDotChinese = regexp.MustCompile("^[\u4e00-\u9fa5\\.\\-_A-Za-z0-9]+$")
  25. )
  26. // CheckGitRefAdditionalRulesValid check name is valid on additional rules
  27. func CheckGitRefAdditionalRulesValid(name string) bool {
  28. // Additional rules as described at https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html
  29. if strings.HasPrefix(name, "/") || strings.HasSuffix(name, "/") ||
  30. strings.HasSuffix(name, ".") || strings.Contains(name, "..") ||
  31. strings.Contains(name, "//") || strings.Contains(name, "@{") ||
  32. name == "@" {
  33. return false
  34. }
  35. parts := strings.Split(name, "/")
  36. for _, part := range parts {
  37. if strings.HasSuffix(part, ".lock") || strings.HasPrefix(part, ".") {
  38. return false
  39. }
  40. }
  41. return true
  42. }
  43. // AddBindingRules adds additional binding rules
  44. func AddBindingRules() {
  45. addGitRefNameBindingRule()
  46. addValidURLBindingRule()
  47. addGlobPatternRule()
  48. addAlphaDashDotChineseRule()
  49. }
  50. func addGitRefNameBindingRule() {
  51. // Git refname validation rule
  52. binding.AddRule(&binding.Rule{
  53. IsMatch: func(rule string) bool {
  54. return strings.HasPrefix(rule, "GitRefName")
  55. },
  56. IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) {
  57. str := fmt.Sprintf("%v", val)
  58. if GitRefNamePatternInvalid.MatchString(str) {
  59. errs.Add([]string{name}, ErrGitRefName, "GitRefName")
  60. return false, errs
  61. }
  62. if !CheckGitRefAdditionalRulesValid(str) {
  63. errs.Add([]string{name}, ErrGitRefName, "GitRefName")
  64. return false, errs
  65. }
  66. return true, errs
  67. },
  68. })
  69. }
  70. func addValidURLBindingRule() {
  71. // URL validation rule
  72. binding.AddRule(&binding.Rule{
  73. IsMatch: func(rule string) bool {
  74. return strings.HasPrefix(rule, "ValidUrl")
  75. },
  76. IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) {
  77. str := fmt.Sprintf("%v", val)
  78. if len(str) != 0 && !IsValidURL(str) {
  79. errs.Add([]string{name}, binding.ERR_URL, "Url")
  80. return false, errs
  81. }
  82. return true, errs
  83. },
  84. })
  85. }
  86. func addGlobPatternRule() {
  87. binding.AddRule(&binding.Rule{
  88. IsMatch: func(rule string) bool {
  89. return rule == "GlobPattern"
  90. },
  91. IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) {
  92. str := fmt.Sprintf("%v", val)
  93. if len(str) != 0 {
  94. if _, err := glob.Compile(str); err != nil {
  95. errs.Add([]string{name}, ErrGlobPattern, err.Error())
  96. return false, errs
  97. }
  98. }
  99. return true, errs
  100. },
  101. })
  102. }
  103. func addAlphaDashDotChineseRule() {
  104. binding.AddRule(&binding.Rule{
  105. IsMatch: func(rule string) bool {
  106. return strings.HasPrefix(rule, "AlphaDashDotChinese")
  107. },
  108. IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) {
  109. if val == "" {
  110. return true, errs
  111. }
  112. if !ValidAlphaDashDotChinese(fmt.Sprintf("%v", val)) {
  113. errs.Add([]string{name}, ErrAlphaDashDotChinese, "ErrAlphaDashDotChinese")
  114. return false, errs
  115. }
  116. return true, errs
  117. },
  118. })
  119. }
  120. func portOnly(hostport string) string {
  121. colon := strings.IndexByte(hostport, ':')
  122. if colon == -1 {
  123. return ""
  124. }
  125. if i := strings.Index(hostport, "]:"); i != -1 {
  126. return hostport[i+len("]:"):]
  127. }
  128. if strings.Contains(hostport, "]") {
  129. return ""
  130. }
  131. return hostport[colon+len(":"):]
  132. }
  133. func validPort(p string) bool {
  134. for _, r := range []byte(p) {
  135. if r < '0' || r > '9' {
  136. return false
  137. }
  138. }
  139. return true
  140. }
  141. func ValidAlphaDashDotChinese(value string) bool {
  142. return AlphaDashDotChinese.MatchString(value)
  143. }