This bug occurs when the glob.Glob has a matcher which is empty and its length is 0.
In detail, the crash locates in glob/match/raw.go:(self Row) matchAll(s string) bool:
func (self Row) matchAll(s string) bool {
var idx int
for _, m := range self.Matchers {
length := m.Len()
var next, i int
for next = range s[idx:] {
i++
if i == length {
break
}
}
if i < length || !m.Match(s[idx:idx+next+1]) {
return false
}
idx += next + 1
}
return true
}
If length is 0 and s meets the end, the function won't return by the condition i < length and it will crashed at s[idx:idx+next+1]
The PoC is here:
package main
import (
"strings"
"github.com/gobwas/glob"
)
// IndexerGlobFromString parses a comma separated list of patterns and returns a glob.Glob slice suited for repo indexing
func IndexerGlobFromString(globstr string) []glob.Glob {
extarr := make([]glob.Glob, 0, 10)
for _, expr := range strings.Split(strings.ToLower(globstr), ",") {
expr = strings.TrimSpace(expr)
if expr != "" {
if g, err := glob.Compile(expr, '.', '/'); err == nil {
extarr = append(extarr, g)
}
}
}
return extarr
}
func main() {
pocstr := "0{" // this string is designed to make the second matcher of g is empty
g := IndexerGlobFromString(pocstr)[0]
// the second matcher of g is empty, and its length is 0
g.Match("0")
}
It will crash as:
panic: runtime error: slice bounds out of range [:2] with length 1
goroutine 1 [running]:
github.com/gobwas/glob/match.Row.matchAll({{0xc0001b6020, 0x2, 0x2}, 0x1, {0xc0001b0090, 0x1, 0x1}}, {0x4d2ca9, 0x1})
/home/zjx/workspace/gowork/pkg/mod/github.com/gobwas/glob@v0.2.3/match/row.go:34 +0x34f
github.com/gobwas/glob/match.Row.Match({{0xc0001b6020, 0x2, 0x2}, 0x1, {0xc0001b0090, 0x1, 0x1}}, {0x4d2ca9, 0x1})
/home/zjx/workspace/gowork/pkg/mod/github.com/gobwas/glob@v0.2.3/match/row.go:56 +0xe9
main.main()
/home/zjx/workspace/gowork/src/go-fdg-exmaples/gitea/modules/setting/pocTest_newIndexerGlobSettings/main.go:27 +0x7c
This bug occurs when the glob.Glob has a matcher which is empty and its length is 0. In detail, the crash locates in
glob/match/raw.go:(self Row) matchAll(s string) bool
:If
length
is 0 ands
meets the end, the function won't return by the conditioni < length
and it will crashed ats[idx:idx+next+1]
The PoC is here:
It will crash as: