From 7b529ba9177146a51964a6950234dddc9b9b4199 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 13 Sep 2025 12:27:39 +0800 Subject: [PATCH 1/2] fix --- assets/go-licenses.json | 5 - cmd/embedded.go | 2 +- go.mod | 1 - go.sum | 2 - models/git/protected_branch.go | 5 +- models/git/protected_branch_list.go | 3 +- models/git/protected_tag.go | 3 +- modules/actions/workflows.go | 2 +- modules/glob/glob.go | 184 ++++++++++++++++ modules/glob/glob_test.go | 208 +++++++++++++++++++ modules/proxy/proxy.go | 3 +- modules/setting/glob.go | 2 +- modules/setting/service.go | 3 +- modules/setting/service_test.go | 2 +- modules/validation/binding.go | 2 +- modules/validation/glob_pattern_test.go | 3 +- modules/validation/helpers.go | 3 +- routers/web/repo/pull.go | 3 +- routers/web/repo/setting/protected_branch.go | 3 +- services/forms/user_form_test.go | 2 +- services/pull/commit_status.go | 2 +- services/pull/patch.go | 3 +- services/repository/adopt.go | 3 +- services/repository/generate.go | 2 +- services/user/email_test.go | 2 +- services/webhook/deliver.go | 3 +- services/webhook/webhook.go | 3 +- tests/integration/api_admin_test.go | 2 +- 28 files changed, 417 insertions(+), 44 deletions(-) create mode 100644 modules/glob/glob.go create mode 100644 modules/glob/glob_test.go diff --git a/assets/go-licenses.json b/assets/go-licenses.json index d645009d90fe6..9c19080e24618 100644 --- a/assets/go-licenses.json +++ b/assets/go-licenses.json @@ -579,11 +579,6 @@ "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" }, - { - "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", "path": "github.com/goccy/go-json/LICENSE", diff --git a/cmd/embedded.go b/cmd/embedded.go index 1908352453ff8..9180407fd18a1 100644 --- a/cmd/embedded.go +++ b/cmd/embedded.go @@ -12,6 +12,7 @@ import ( "strings" "code.gitea.io/gitea/modules/assetfs" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/options" "code.gitea.io/gitea/modules/public" @@ -19,7 +20,6 @@ import ( "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/util" - "github.com/gobwas/glob" "github.com/urfave/cli/v3" ) diff --git a/go.mod b/go.mod index eb871e24ae1c1..f32c3e08ef436 100644 --- a/go.mod +++ b/go.mod @@ -61,7 +61,6 @@ require ( github.com/go-redsync/redsync/v4 v4.13.0 github.com/go-sql-driver/mysql v1.9.3 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/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 github.com/golang-jwt/jwt/v5 v5.3.0 diff --git a/go.sum b/go.sum index b69b380cfe2ab..1853693e90dcf 100644 --- a/go.sum +++ b/go.sum @@ -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/x v0.1.24 h1:6LaWf2zzWqbyKT8IyQkhje1/1KCGhlEkMz4V1tDnt/A= 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/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= diff --git a/models/git/protected_branch.go b/models/git/protected_branch.go index 55bbe6938cdc4..511f7563cf52d 100644 --- a/models/git/protected_branch.go +++ b/models/git/protected_branch.go @@ -17,12 +17,11 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" 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/timeutil" "code.gitea.io/gitea/modules/util" - "github.com/gobwas/glob" - "github.com/gobwas/glob/syntax" "xorm.io/builder" ) @@ -77,7 +76,7 @@ func init() { // IsRuleNameSpecial return true if it contains special character func IsRuleNameSpecial(ruleName string) bool { for i := 0; i < len(ruleName); i++ { - if syntax.Special(ruleName[i]) { + if glob.IsSpecialByte(ruleName[i]) { return true } } diff --git a/models/git/protected_branch_list.go b/models/git/protected_branch_list.go index 16f85006723b1..6b282835a4687 100644 --- a/models/git/protected_branch_list.go +++ b/models/git/protected_branch_list.go @@ -8,9 +8,8 @@ import ( "sort" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/optional" - - "github.com/gobwas/glob" ) type ProtectedBranchRules []*ProtectedBranch diff --git a/models/git/protected_tag.go b/models/git/protected_tag.go index 9a6646c742c72..95642df59323c 100644 --- a/models/git/protected_tag.go +++ b/models/git/protected_tag.go @@ -11,9 +11,8 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/timeutil" - - "github.com/gobwas/glob" ) // ProtectedTag struct diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 27bcafa6497b9..5fc530b63e53b 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -10,11 +10,11 @@ import ( "strings" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" webhook_module "code.gitea.io/gitea/modules/webhook" - "github.com/gobwas/glob" "github.com/nektos/act/pkg/jobparser" "github.com/nektos/act/pkg/model" "github.com/nektos/act/pkg/workflowpattern" diff --git a/modules/glob/glob.go b/modules/glob/glob.go new file mode 100644 index 0000000000000..d4ca77e2ee173 --- /dev/null +++ b/modules/glob/glob.go @@ -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]) +} diff --git a/modules/glob/glob_test.go b/modules/glob/glob_test.go new file mode 100644 index 0000000000000..846789525243a --- /dev/null +++ b/modules/glob/glob_test.go @@ -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) + } +} diff --git a/modules/proxy/proxy.go b/modules/proxy/proxy.go index 1a6bdad7fb5d8..f8843316aa9c0 100644 --- a/modules/proxy/proxy.go +++ b/modules/proxy/proxy.go @@ -10,10 +10,9 @@ import ( "strings" "sync" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - - "github.com/gobwas/glob" ) var ( diff --git a/modules/setting/glob.go b/modules/setting/glob.go index 8f1d24dea4cfb..cc76a02077116 100644 --- a/modules/setting/glob.go +++ b/modules/setting/glob.go @@ -3,7 +3,7 @@ package setting -import "github.com/gobwas/glob" +import "code.gitea.io/gitea/modules/glob" type GlobMatcher struct { compiledGlob glob.Glob diff --git a/modules/setting/service.go b/modules/setting/service.go index b1b9fedd62afb..e652c13c9c9e3 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -9,10 +9,9 @@ import ( "strings" "time" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/structs" - - "github.com/gobwas/glob" ) // enumerates all the types of captchas diff --git a/modules/setting/service_test.go b/modules/setting/service_test.go index 73736b793a8db..fad15427415cd 100644 --- a/modules/setting/service_test.go +++ b/modules/setting/service_test.go @@ -6,10 +6,10 @@ package setting import ( "testing" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/test" - "github.com/gobwas/glob" "github.com/stretchr/testify/assert" ) diff --git a/modules/validation/binding.go b/modules/validation/binding.go index 75190e31e185b..335f248ead102 100644 --- a/modules/validation/binding.go +++ b/modules/validation/binding.go @@ -10,10 +10,10 @@ import ( "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/util" "gitea.com/go-chi/binding" - "github.com/gobwas/glob" ) const ( diff --git a/modules/validation/glob_pattern_test.go b/modules/validation/glob_pattern_test.go index 7f3e609acfabc..80cf035ca6923 100644 --- a/modules/validation/glob_pattern_test.go +++ b/modules/validation/glob_pattern_test.go @@ -6,8 +6,9 @@ package validation import ( "testing" + "code.gitea.io/gitea/modules/glob" + "gitea.com/go-chi/binding" - "github.com/gobwas/glob" ) func getGlobPatternErrorString(pattern string) string { diff --git a/modules/validation/helpers.go b/modules/validation/helpers.go index ba383ba195db1..051330e439723 100644 --- a/modules/validation/helpers.go +++ b/modules/validation/helpers.go @@ -11,9 +11,8 @@ import ( "strings" "sync" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/setting" - - "github.com/gobwas/glob" ) type globalVarsStruct struct { diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 83aaf75363fbd..889219b256e53 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -27,6 +27,7 @@ import ( "code.gitea.io/gitea/modules/fileicon" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/graceful" issue_template "code.gitea.io/gitea/modules/issue/template" "code.gitea.io/gitea/modules/log" @@ -46,8 +47,6 @@ import ( pull_service "code.gitea.io/gitea/services/pull" repo_service "code.gitea.io/gitea/services/repository" user_service "code.gitea.io/gitea/services/user" - - "github.com/gobwas/glob" ) const ( diff --git a/routers/web/repo/setting/protected_branch.go b/routers/web/repo/setting/protected_branch.go index 0eea5e3f34062..152f67550cc6c 100644 --- a/routers/web/repo/setting/protected_branch.go +++ b/routers/web/repo/setting/protected_branch.go @@ -19,6 +19,7 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/web/repo" @@ -26,8 +27,6 @@ import ( "code.gitea.io/gitea/services/forms" pull_service "code.gitea.io/gitea/services/pull" "code.gitea.io/gitea/services/repository" - - "github.com/gobwas/glob" ) const ( diff --git a/services/forms/user_form_test.go b/services/forms/user_form_test.go index 09e9ec0f65c35..4246f955b3e63 100644 --- a/services/forms/user_form_test.go +++ b/services/forms/user_form_test.go @@ -6,10 +6,10 @@ package forms import ( "testing" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/test" - "github.com/gobwas/glob" "github.com/stretchr/testify/assert" ) diff --git a/services/pull/commit_status.go b/services/pull/commit_status.go index d15d318149734..e7c14a5e7aabf 100644 --- a/services/pull/commit_status.go +++ b/services/pull/commit_status.go @@ -12,9 +12,9 @@ import ( issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/commitstatus" "code.gitea.io/gitea/modules/gitrepo" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/log" - "github.com/gobwas/glob" "github.com/pkg/errors" ) diff --git a/services/pull/patch.go b/services/pull/patch.go index 9d9b8d0d076eb..e5f8f678bc9c9 100644 --- a/services/pull/patch.go +++ b/services/pull/patch.go @@ -19,13 +19,12 @@ import ( "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" - - "github.com/gobwas/glob" ) // DownloadDiffOrPatch will write the patch for the pr to the writer diff --git a/services/repository/adopt.go b/services/repository/adopt.go index a17111dfafbbe..8d8e59b0531af 100644 --- a/services/repository/adopt.go +++ b/services/repository/adopt.go @@ -17,6 +17,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/gitrepo" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" @@ -24,8 +25,6 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" notify_service "code.gitea.io/gitea/services/notify" - - "github.com/gobwas/glob" ) func deleteFailedAdoptRepository(repoID int64) error { diff --git a/services/repository/generate.go b/services/repository/generate.go index 867b5d78554ff..b92d148d2183a 100644 --- a/services/repository/generate.go +++ b/services/repository/generate.go @@ -19,12 +19,12 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" - "github.com/gobwas/glob" "github.com/huandu/xstrings" ) diff --git a/services/user/email_test.go b/services/user/email_test.go index 78770633d2045..76770a92301ba 100644 --- a/services/user/email_test.go +++ b/services/user/email_test.go @@ -9,9 +9,9 @@ import ( organization_model "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/setting" - "github.com/gobwas/glob" "github.com/stretchr/testify/assert" ) diff --git a/services/webhook/deliver.go b/services/webhook/deliver.go index e8e6ed19c1488..b6611a3576df5 100644 --- a/services/webhook/deliver.go +++ b/services/webhook/deliver.go @@ -21,6 +21,7 @@ import ( user_model "code.gitea.io/gitea/models/user" 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/hostmatcher" "code.gitea.io/gitea/modules/log" @@ -30,8 +31,6 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" 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) { diff --git a/services/webhook/webhook.go b/services/webhook/webhook.go index 182078b39d4d3..2b276207a1396 100644 --- a/services/webhook/webhook.go +++ b/services/webhook/webhook.go @@ -15,6 +15,7 @@ import ( user_model "code.gitea.io/gitea/models/user" webhook_model "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" @@ -23,8 +24,6 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" 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) diff --git a/tests/integration/api_admin_test.go b/tests/integration/api_admin_test.go index d28a103e596f8..dbd62c4078b26 100644 --- a/tests/integration/api_admin_test.go +++ b/tests/integration/api_admin_test.go @@ -13,12 +13,12 @@ import ( auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/unittest" 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/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/tests" - "github.com/gobwas/glob" "github.com/stretchr/testify/assert" ) From fd02f8b570e40e7c42fc2236cb8e1635ffc30db2 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 13 Sep 2025 21:37:16 +0800 Subject: [PATCH 2/2] fix js test --- web_src/js/utils/glob.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_src/js/utils/glob.test.ts b/web_src/js/utils/glob.test.ts index 5dbaece9d2841..db05b282d2619 100644 --- a/web_src/js/utils/glob.test.ts +++ b/web_src/js/utils/glob.test.ts @@ -16,7 +16,7 @@ async function loadGlobTestData(): Promise<{caseNames: string[], caseDataMap: Re const key = parts[0].trim(); let value = parts[1].trim(); value = value.substring(1, value.length - 1); // remove quotes - value = value.replace(/\\\\/g, '\\').replaceAll(/\\\//g, '/'); + value = value.replace(/\\\//g, '/').replace(/\\\\/g, '\\'); caseDataMap[key] = value; if (key.startsWith('pattern_')) caseNameMap[key.substring('pattern_'.length)] = true; }