1
1
mirror of https://github.com/go-gitea/gitea synced 2025-09-15 05:08:13 +00:00

Replace gobwas/glob package (#35478)

https://github.com/gobwas/glob is unmaintained and has bugs.
This commit is contained in:
wxiaoguang
2025-09-14 02:01:00 +08:00
committed by GitHub
parent 688abac5ca
commit 4fe1066a17
29 changed files with 418 additions and 45 deletions

View File

@@ -579,11 +579,6 @@
"path": "github.com/go-webauthn/x/revoke/LICENSE", "path": "github.com/go-webauthn/x/revoke/LICENSE",
"licenseText": "Copyright (c) 2014 CloudFlare Inc.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\nRedistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n\nRedistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" "licenseText": "Copyright (c) 2014 CloudFlare Inc.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\nRedistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n\nRedistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
}, },
{
"name": "github.com/gobwas/glob",
"path": "github.com/gobwas/glob/LICENSE",
"licenseText": "The MIT License (MIT)\n\nCopyright (c) 2016 Sergey Kamardin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
},
{ {
"name": "github.com/goccy/go-json", "name": "github.com/goccy/go-json",
"path": "github.com/goccy/go-json/LICENSE", "path": "github.com/goccy/go-json/LICENSE",

View File

@@ -12,6 +12,7 @@ import (
"strings" "strings"
"code.gitea.io/gitea/modules/assetfs" "code.gitea.io/gitea/modules/assetfs"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/options" "code.gitea.io/gitea/modules/options"
"code.gitea.io/gitea/modules/public" "code.gitea.io/gitea/modules/public"
@@ -19,7 +20,6 @@ import (
"code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"github.com/gobwas/glob"
"github.com/urfave/cli/v3" "github.com/urfave/cli/v3"
) )

1
go.mod
View File

@@ -61,7 +61,6 @@ require (
github.com/go-redsync/redsync/v4 v4.13.0 github.com/go-redsync/redsync/v4 v4.13.0
github.com/go-sql-driver/mysql v1.9.3 github.com/go-sql-driver/mysql v1.9.3
github.com/go-webauthn/webauthn v0.13.4 github.com/go-webauthn/webauthn v0.13.4
github.com/gobwas/glob v0.2.3
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
github.com/golang-jwt/jwt/v5 v5.3.0 github.com/golang-jwt/jwt/v5 v5.3.0

2
go.sum
View File

@@ -364,8 +364,6 @@ github.com/go-webauthn/webauthn v0.13.4 h1:q68qusWPcqHbg9STSxBLBHnsKaLxNO0RnVKaA
github.com/go-webauthn/webauthn v0.13.4/go.mod h1:MglN6OH9ECxvhDqoq1wMoF6P6JRYDiQpC9nc5OomQmI= github.com/go-webauthn/webauthn v0.13.4/go.mod h1:MglN6OH9ECxvhDqoq1wMoF6P6JRYDiQpC9nc5OomQmI=
github.com/go-webauthn/x v0.1.24 h1:6LaWf2zzWqbyKT8IyQkhje1/1KCGhlEkMz4V1tDnt/A= github.com/go-webauthn/x v0.1.24 h1:6LaWf2zzWqbyKT8IyQkhje1/1KCGhlEkMz4V1tDnt/A=
github.com/go-webauthn/x v0.1.24/go.mod h1:2o5XKJ+X1AKqYKGgHdKflGnoQFQZ6flJ2IFCBKSbSOw= github.com/go-webauthn/x v0.1.24/go.mod h1:2o5XKJ+X1AKqYKGgHdKflGnoQFQZ6flJ2IFCBKSbSOw=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=

View File

@@ -17,12 +17,11 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"github.com/gobwas/glob"
"github.com/gobwas/glob/syntax"
"xorm.io/builder" "xorm.io/builder"
) )
@@ -77,7 +76,7 @@ func init() {
// IsRuleNameSpecial return true if it contains special character // IsRuleNameSpecial return true if it contains special character
func IsRuleNameSpecial(ruleName string) bool { func IsRuleNameSpecial(ruleName string) bool {
for i := 0; i < len(ruleName); i++ { for i := 0; i < len(ruleName); i++ {
if syntax.Special(ruleName[i]) { if glob.IsSpecialByte(ruleName[i]) {
return true return true
} }
} }

View File

@@ -8,9 +8,8 @@ import (
"sort" "sort"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/optional"
"github.com/gobwas/glob"
) )
type ProtectedBranchRules []*ProtectedBranch type ProtectedBranchRules []*ProtectedBranch

View File

@@ -11,9 +11,8 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"github.com/gobwas/glob"
) )
// ProtectedTag struct // ProtectedTag struct

View File

@@ -10,11 +10,11 @@ import (
"strings" "strings"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook" webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/gobwas/glob"
"github.com/nektos/act/pkg/jobparser" "github.com/nektos/act/pkg/jobparser"
"github.com/nektos/act/pkg/model" "github.com/nektos/act/pkg/model"
"github.com/nektos/act/pkg/workflowpattern" "github.com/nektos/act/pkg/workflowpattern"

184
modules/glob/glob.go Normal file
View File

@@ -0,0 +1,184 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package glob
import (
"errors"
"fmt"
"regexp"
"code.gitea.io/gitea/modules/util"
)
// Reference: https://github.com/gobwas/glob/blob/master/glob.go
type Glob interface {
Match(string) bool
}
type globCompiler struct {
nonSeparatorChars string
globPattern []rune
regexpPattern string
regexp *regexp.Regexp
pos int
}
// compileChars compiles character class patterns like [abc] or [!abc]
func (g *globCompiler) compileChars() (string, error) {
result := ""
if g.pos < len(g.globPattern) && g.globPattern[g.pos] == '!' {
g.pos++
result += "^"
}
for g.pos < len(g.globPattern) {
c := g.globPattern[g.pos]
g.pos++
if c == ']' {
return "[" + result + "]", nil
}
if c == '\\' {
if g.pos >= len(g.globPattern) {
return "", errors.New("unterminated character class escape")
}
result += "\\" + string(g.globPattern[g.pos])
g.pos++
} else {
result += string(c)
}
}
return "", errors.New("unterminated character class")
}
// compile compiles the glob pattern into a regular expression
func (g *globCompiler) compile(subPattern bool) (string, error) {
result := ""
for g.pos < len(g.globPattern) {
c := g.globPattern[g.pos]
g.pos++
if subPattern && c == '}' {
return "(" + result + ")", nil
}
switch c {
case '*':
if g.pos < len(g.globPattern) && g.globPattern[g.pos] == '*' {
g.pos++
result += ".*" // match any sequence of characters
} else {
result += g.nonSeparatorChars + "*" // match any sequence of non-separator characters
}
case '?':
result += g.nonSeparatorChars // match any single non-separator character
case '[':
chars, err := g.compileChars()
if err != nil {
return "", err
}
result += chars
case '{':
subResult, err := g.compile(true)
if err != nil {
return "", err
}
result += subResult
case ',':
if subPattern {
result += "|"
} else {
result += ","
}
case '\\':
if g.pos >= len(g.globPattern) {
return "", errors.New("no character to escape")
}
result += "\\" + string(g.globPattern[g.pos])
g.pos++
case '.', '+', '^', '$', '(', ')', '|':
result += "\\" + string(c) // escape regexp special characters
default:
result += string(c)
}
}
return result, nil
}
func newGlobCompiler(pattern string, separators ...rune) (Glob, error) {
g := &globCompiler{globPattern: []rune(pattern)}
// Escape separators for use in character class
escapedSeparators := regexp.QuoteMeta(string(separators))
if escapedSeparators != "" {
g.nonSeparatorChars = "[^" + escapedSeparators + "]"
} else {
g.nonSeparatorChars = "."
}
compiled, err := g.compile(false)
if err != nil {
return nil, err
}
g.regexpPattern = "^" + compiled + "$"
regex, err := regexp.Compile(g.regexpPattern)
if err != nil {
return nil, fmt.Errorf("failed to compile regexp: %w", err)
}
g.regexp = regex
return g, nil
}
func (g *globCompiler) Match(s string) bool {
return g.regexp.MatchString(s)
}
func Compile(pattern string, separators ...rune) (Glob, error) {
return newGlobCompiler(pattern, separators...)
}
func MustCompile(pattern string, separators ...rune) Glob {
g, err := Compile(pattern, separators...)
if err != nil {
panic(err)
}
return g
}
func IsSpecialByte(c byte) bool {
return c == '*' || c == '?' || c == '\\' || c == '[' || c == ']' || c == '{' || c == '}'
}
// QuoteMeta returns a string that quotes all glob pattern meta characters
// inside the argument text; For example, QuoteMeta(`{foo*}`) returns `\[foo\*\]`.
// Reference: https://github.com/gobwas/glob/blob/master/glob.go
func QuoteMeta(s string) string {
pos := 0
for pos < len(s) && !IsSpecialByte(s[pos]) {
pos++
}
if pos == len(s) {
return s
}
b := make([]byte, pos+2*(len(s)-pos))
copy(b, s[0:pos])
to := pos
for ; pos < len(s); pos++ {
if IsSpecialByte(s[pos]) {
b[to] = '\\'
to++
}
b[to] = s[pos]
to++
}
return util.UnsafeBytesToString(b[0:to])
}

208
modules/glob/glob_test.go Normal file
View File

@@ -0,0 +1,208 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// Copyright (c) 2016 Sergey Kamardin
// SPDX-License-Identifier: MIT
//
//nolint:revive // the code is from gobwas/glob
package glob
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// Reference: https://github.com/gobwas/glob/blob/master/glob_test.go
const (
pattern_all = "[a-z][!a-x]*cat*[h][!b]*eyes*"
regexp_all = `^[a-z][^a-x].*cat.*[h][^b].*eyes.*$`
fixture_all_match = "my cat has very bright eyes"
fixture_all_mismatch = "my dog has very bright eyes"
pattern_plain = "google.com"
regexp_plain = `^google\.com$`
fixture_plain_match = "google.com"
fixture_plain_mismatch = "gobwas.com"
pattern_multiple = "https://*.google.*"
regexp_multiple = `^https:\/\/.*\.google\..*$`
fixture_multiple_match = "https://account.google.com"
fixture_multiple_mismatch = "https://google.com"
pattern_alternatives = "{https://*.google.*,*yandex.*,*yahoo.*,*mail.ru}"
regexp_alternatives = `^(https:\/\/.*\.google\..*|.*yandex\..*|.*yahoo\..*|.*mail\.ru)$`
fixture_alternatives_match = "http://yahoo.com"
fixture_alternatives_mismatch = "http://google.com"
pattern_alternatives_suffix = "{https://*gobwas.com,http://exclude.gobwas.com}"
regexp_alternatives_suffix = `^(https:\/\/.*gobwas\.com|http://exclude.gobwas.com)$`
fixture_alternatives_suffix_first_match = "https://safe.gobwas.com"
fixture_alternatives_suffix_first_mismatch = "http://safe.gobwas.com"
fixture_alternatives_suffix_second = "http://exclude.gobwas.com"
pattern_prefix = "abc*"
regexp_prefix = `^abc.*$`
pattern_suffix = "*def"
regexp_suffix = `^.*def$`
pattern_prefix_suffix = "ab*ef"
regexp_prefix_suffix = `^ab.*ef$`
fixture_prefix_suffix_match = "abcdef"
fixture_prefix_suffix_mismatch = "af"
pattern_alternatives_combine_lite = "{abc*def,abc?def,abc[zte]def}"
regexp_alternatives_combine_lite = `^(abc.*def|abc.def|abc[zte]def)$`
fixture_alternatives_combine_lite = "abczdef"
pattern_alternatives_combine_hard = "{abc*[a-c]def,abc?[d-g]def,abc[zte]?def}"
regexp_alternatives_combine_hard = `^(abc.*[a-c]def|abc.[d-g]def|abc[zte].def)$`
fixture_alternatives_combine_hard = "abczqdef"
)
type test struct {
pattern, match string
should bool
delimiters []rune
}
func glob(s bool, p, m string, d ...rune) test {
return test{p, m, s, d}
}
func TestGlob(t *testing.T) {
for _, test := range []test{
glob(true, "* ?at * eyes", "my cat has very bright eyes"),
glob(true, "", ""),
glob(false, "", "b"),
glob(true, "*ä", "åä"),
glob(true, "abc", "abc"),
glob(true, "a*c", "abc"),
glob(true, "a*c", "a12345c"),
glob(true, "a?c", "a1c"),
glob(true, "a.b", "a.b", '.'),
glob(true, "a.*", "a.b", '.'),
glob(true, "a.**", "a.b.c", '.'),
glob(true, "a.?.c", "a.b.c", '.'),
glob(true, "a.?.?", "a.b.c", '.'),
glob(true, "?at", "cat"),
glob(true, "?at", "fat"),
glob(true, "*", "abc"),
glob(true, `\*`, "*"),
glob(true, "**", "a.b.c", '.'),
glob(false, "?at", "at"),
glob(false, "?at", "fat", 'f'),
glob(false, "a.*", "a.b.c", '.'),
glob(false, "a.?.c", "a.bb.c", '.'),
glob(false, "*", "a.b.c", '.'),
glob(true, "*test", "this is a test"),
glob(true, "this*", "this is a test"),
glob(true, "*is *", "this is a test"),
glob(true, "*is*a*", "this is a test"),
glob(true, "**test**", "this is a test"),
glob(true, "**is**a***test*", "this is a test"),
glob(false, "*is", "this is a test"),
glob(false, "*no*", "this is a test"),
glob(true, "[!a]*", "this is a test3"),
glob(true, "*abc", "abcabc"),
glob(true, "**abc", "abcabc"),
glob(true, "???", "abc"),
glob(true, "?*?", "abc"),
glob(true, "?*?", "ac"),
glob(false, "sta", "stagnation"),
glob(true, "sta*", "stagnation"),
glob(false, "sta?", "stagnation"),
glob(false, "sta?n", "stagnation"),
glob(true, "{abc,def}ghi", "defghi"),
glob(true, "{abc,abcd}a", "abcda"),
glob(true, "{a,ab}{bc,f}", "abc"),
glob(true, "{*,**}{a,b}", "ab"),
glob(false, "{*,**}{a,b}", "ac"),
glob(true, "/{rate,[a-z][a-z][a-z]}*", "/rate"),
glob(true, "/{rate,[0-9][0-9][0-9]}*", "/rate"),
glob(true, "/{rate,[a-z][a-z][a-z]}*", "/usd"),
glob(true, "{*.google.*,*.yandex.*}", "www.google.com", '.'),
glob(true, "{*.google.*,*.yandex.*}", "www.yandex.com", '.'),
glob(false, "{*.google.*,*.yandex.*}", "yandex.com", '.'),
glob(false, "{*.google.*,*.yandex.*}", "google.com", '.'),
glob(true, "{*.google.*,yandex.*}", "www.google.com", '.'),
glob(true, "{*.google.*,yandex.*}", "yandex.com", '.'),
glob(false, "{*.google.*,yandex.*}", "www.yandex.com", '.'),
glob(false, "{*.google.*,yandex.*}", "google.com", '.'),
glob(true, "*//{,*.}example.com", "https://www.example.com"),
glob(true, "*//{,*.}example.com", "http://example.com"),
glob(false, "*//{,*.}example.com", "http://example.com.net"),
glob(true, pattern_all, fixture_all_match),
glob(false, pattern_all, fixture_all_mismatch),
glob(true, pattern_plain, fixture_plain_match),
glob(false, pattern_plain, fixture_plain_mismatch),
glob(true, pattern_multiple, fixture_multiple_match),
glob(false, pattern_multiple, fixture_multiple_mismatch),
glob(true, pattern_alternatives, fixture_alternatives_match),
glob(false, pattern_alternatives, fixture_alternatives_mismatch),
glob(true, pattern_alternatives_suffix, fixture_alternatives_suffix_first_match),
glob(false, pattern_alternatives_suffix, fixture_alternatives_suffix_first_mismatch),
glob(true, pattern_alternatives_suffix, fixture_alternatives_suffix_second),
glob(true, pattern_alternatives_combine_hard, fixture_alternatives_combine_hard),
glob(true, pattern_alternatives_combine_lite, fixture_alternatives_combine_lite),
glob(true, pattern_prefix, fixture_prefix_suffix_match),
glob(false, pattern_prefix, fixture_prefix_suffix_mismatch),
glob(true, pattern_suffix, fixture_prefix_suffix_match),
glob(false, pattern_suffix, fixture_prefix_suffix_mismatch),
glob(true, pattern_prefix_suffix, fixture_prefix_suffix_match),
glob(false, pattern_prefix_suffix, fixture_prefix_suffix_mismatch),
} {
g, err := Compile(test.pattern, test.delimiters...)
require.NoError(t, err)
result := g.Match(test.match)
assert.Equal(t, test.should, result, "pattern %q matching %q should be %v but got %v, compiled=%s", test.pattern, test.match, test.should, result, g.(*globCompiler).regexpPattern)
}
}
func TestQuoteMeta(t *testing.T) {
for id, test := range []struct {
in, out string
}{
{
in: `[foo*]`,
out: `\[foo\*\]`,
},
{
in: `{foo*}`,
out: `\{foo\*\}`,
},
{
in: `*?\[]{}`,
out: `\*\?\\\[\]\{\}`,
},
{
in: `some text and *?\[]{}`,
out: `some text and \*\?\\\[\]\{\}`,
},
} {
act := QuoteMeta(test.in)
assert.Equal(t, test.out, act, "QuoteMeta(%q)", test.in)
_, err := Compile(act)
assert.NoError(t, err, "#%d _, err := Compile(QuoteMeta(%q) = %q); err = %q", id, test.in, act, err)
}
}

View File

@@ -10,10 +10,9 @@ import (
"strings" "strings"
"sync" "sync"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/gobwas/glob"
) )
var ( var (

View File

@@ -3,7 +3,7 @@
package setting package setting
import "github.com/gobwas/glob" import "code.gitea.io/gitea/modules/glob"
type GlobMatcher struct { type GlobMatcher struct {
compiledGlob glob.Glob compiledGlob glob.Glob

View File

@@ -9,10 +9,9 @@ import (
"strings" "strings"
"time" "time"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
"github.com/gobwas/glob"
) )
// enumerates all the types of captchas // enumerates all the types of captchas

View File

@@ -6,10 +6,10 @@ package setting
import ( import (
"testing" "testing"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/test"
"github.com/gobwas/glob"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View File

@@ -10,10 +10,10 @@ import (
"code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"gitea.com/go-chi/binding" "gitea.com/go-chi/binding"
"github.com/gobwas/glob"
) )
const ( const (

View File

@@ -6,8 +6,9 @@ package validation
import ( import (
"testing" "testing"
"code.gitea.io/gitea/modules/glob"
"gitea.com/go-chi/binding" "gitea.com/go-chi/binding"
"github.com/gobwas/glob"
) )
func getGlobPatternErrorString(pattern string) string { func getGlobPatternErrorString(pattern string) string {

View File

@@ -11,9 +11,8 @@ import (
"strings" "strings"
"sync" "sync"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/gobwas/glob"
) )
type globalVarsStruct struct { type globalVarsStruct struct {

View File

@@ -27,6 +27,7 @@ import (
"code.gitea.io/gitea/modules/fileicon" "code.gitea.io/gitea/modules/fileicon"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
issue_template "code.gitea.io/gitea/modules/issue/template" issue_template "code.gitea.io/gitea/modules/issue/template"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@@ -46,8 +47,6 @@ import (
pull_service "code.gitea.io/gitea/services/pull" pull_service "code.gitea.io/gitea/services/pull"
repo_service "code.gitea.io/gitea/services/repository" repo_service "code.gitea.io/gitea/services/repository"
user_service "code.gitea.io/gitea/services/user" user_service "code.gitea.io/gitea/services/user"
"github.com/gobwas/glob"
) )
const ( const (

View File

@@ -19,6 +19,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/web/repo" "code.gitea.io/gitea/routers/web/repo"
@@ -26,8 +27,6 @@ import (
"code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/forms"
pull_service "code.gitea.io/gitea/services/pull" pull_service "code.gitea.io/gitea/services/pull"
"code.gitea.io/gitea/services/repository" "code.gitea.io/gitea/services/repository"
"github.com/gobwas/glob"
) )
const ( const (

View File

@@ -6,10 +6,10 @@ package forms
import ( import (
"testing" "testing"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/test"
"github.com/gobwas/glob"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View File

@@ -12,9 +12,9 @@ import (
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/modules/commitstatus" "code.gitea.io/gitea/modules/commitstatus"
"code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"github.com/gobwas/glob"
"github.com/pkg/errors" "github.com/pkg/errors"
) )

View File

@@ -19,13 +19,12 @@ import (
"code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"github.com/gobwas/glob"
) )
// DownloadDiffOrPatch will write the patch for the pr to the writer // DownloadDiffOrPatch will write the patch for the pr to the writer

View File

@@ -17,6 +17,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/optional"
@@ -24,8 +25,6 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
notify_service "code.gitea.io/gitea/services/notify" notify_service "code.gitea.io/gitea/services/notify"
"github.com/gobwas/glob"
) )
func deleteFailedAdoptRepository(repoID int64) error { func deleteFailedAdoptRepository(repoID int64) error {

View File

@@ -19,12 +19,12 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository" repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"github.com/gobwas/glob"
"github.com/huandu/xstrings" "github.com/huandu/xstrings"
) )

View File

@@ -9,9 +9,9 @@ import (
organization_model "code.gitea.io/gitea/models/organization" organization_model "code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/gobwas/glob"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View File

@@ -21,6 +21,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
webhook_model "code.gitea.io/gitea/models/webhook" webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/hostmatcher" "code.gitea.io/gitea/modules/hostmatcher"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@@ -30,8 +31,6 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
webhook_module "code.gitea.io/gitea/modules/webhook" webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/gobwas/glob"
) )
func newDefaultRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (req *http.Request, body []byte, err error) { func newDefaultRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (req *http.Request, body []byte, err error) {

View File

@@ -15,6 +15,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
webhook_model "code.gitea.io/gitea/models/webhook" webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/optional"
@@ -23,8 +24,6 @@ import (
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook" webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/gobwas/glob"
) )
type Requester func(context.Context, *webhook_model.Webhook, *webhook_model.HookTask) (req *http.Request, body []byte, err error) type Requester func(context.Context, *webhook_model.Webhook, *webhook_model.HookTask) (req *http.Request, body []byte, err error)

View File

@@ -13,12 +13,12 @@ import (
auth_model "code.gitea.io/gitea/models/auth" auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/tests" "code.gitea.io/gitea/tests"
"github.com/gobwas/glob"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View File

@@ -16,7 +16,7 @@ async function loadGlobTestData(): Promise<{caseNames: string[], caseDataMap: Re
const key = parts[0].trim(); const key = parts[0].trim();
let value = parts[1].trim(); let value = parts[1].trim();
value = value.substring(1, value.length - 1); // remove quotes value = value.substring(1, value.length - 1); // remove quotes
value = value.replace(/\\\\/g, '\\').replaceAll(/\\\//g, '/'); value = value.replace(/\\\//g, '/').replace(/\\\\/g, '\\');
caseDataMap[key] = value; caseDataMap[key] = value;
if (key.startsWith('pattern_')) caseNameMap[key.substring('pattern_'.length)] = true; if (key.startsWith('pattern_')) caseNameMap[key.substring('pattern_'.length)] = true;
} }