Skip to content

Commit c513d30

Browse files
committed
pack: escape characters before using them in glob patterns
When we open a pack file, we use a glob pattern to find the pack files that are in our pack directory and then attempt to open them. This works fine if our directory contains no characters that are special to the shell, but works poorly when we handle characters that are special in glob patterns, most notably the left square bracket. In such a case, our pattern doesn't actually match anything, so we don't open any pack files. Git LFS then complains about a missing object. Escape all the characters which are special to the shell so that we can handle these paths properly. Use character classes instead of backslashes because backslash escaping is not available on Windows. For the same reason, punt on handling backslashes on Unix systems because there isn't a great way to handle them portably.
1 parent 8efea4e commit c513d30

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

pack/set.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"path/filepath"
77
"regexp"
88
"sort"
9+
"strings"
910

1011
"github.com/git-lfs/gitobj/errors"
1112
)
@@ -40,7 +41,7 @@ var (
4041
func NewSet(db string) (*Set, error) {
4142
pd := filepath.Join(db, "pack")
4243

43-
paths, err := filepath.Glob(filepath.Join(pd, "*.pack"))
44+
paths, err := filepath.Glob(filepath.Join(escapeGlobPattern(pd), "*.pack"))
4445
if err != nil {
4546
return nil, err
4647
}
@@ -91,6 +92,21 @@ func NewSet(db string) (*Set, error) {
9192
return NewSetPacks(packs...), nil
9293
}
9394

95+
// globEscapes uses these escapes because filepath.Glob does not understand
96+
// backslash escapes on Windows.
97+
var globEscapes = map[string]string{
98+
"*": "[*]",
99+
"?": "[?]",
100+
"[": "[[]",
101+
}
102+
103+
func escapeGlobPattern(s string) string {
104+
for char, escape := range globEscapes {
105+
s = strings.Replace(s, char, escape, -1)
106+
}
107+
return s
108+
}
109+
94110
// NewSetPacks creates a new *Set from the given packfiles.
95111
func NewSetPacks(packs ...*Packfile) *Set {
96112
m := make(map[byte][]*Packfile)

0 commit comments

Comments
 (0)