gobwas / glob

Go glob
MIT License
948 stars 63 forks source link

[BUG]: slice bounds out of range on glob/match #56

Open secsys-go opened 2 years ago

secsys-go commented 2 years ago

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