glob: Parse() missed a number of bad pattern that would later
panic in MatchInitialSegment().  Fixed.

Change-Id: I9098a311c87707e86f3480e5ca86a023606baa3f
diff --git a/lib/glob/glob.go b/lib/glob/glob.go
index 1faf8b3..6f0ac86 100644
--- a/lib/glob/glob.go
+++ b/lib/glob/glob.go
@@ -33,6 +33,33 @@
 	restricted bool
 }
 
+func parseElem(pattern string) error {
+	if len(pattern) == 0 {
+		return filepath.ErrBadPattern
+	}
+	escape := false
+	inrange := false
+	for _, c := range pattern {
+		if escape {
+			escape = false
+			continue
+		}
+		switch c {
+		case '\\':
+			escape = true
+		case '[':
+			inrange = true
+		case ']':
+			inrange = false
+		}
+	}
+	// If we are in the middle of an escape or character range, the expression is incomplete.
+	if escape || inrange {
+		return filepath.ErrBadPattern
+	}
+	return nil
+}
+
 // Parse returns a new Glob.
 func Parse(pattern string) (*Glob, error) {
 	if len(pattern) > 0 && pattern[0] == '/' {
@@ -59,7 +86,7 @@
 	// I'll just check every part to make sure it's error free.
 	// Note: Match never returns an error when matching against an empty string.
 	for _, elem := range g.elems {
-		if _, err := filepath.Match(elem, "test"); err != nil {
+		if err := parseElem(elem); err != nil {
 			return nil, err
 		}
 	}
@@ -112,7 +139,7 @@
 	}
 
 	if matches, err := filepath.Match(g.elems[0], segment); err != nil {
-		panic("Error in glob pattern found.")
+		return false, false, nil
 	} else if matches {
 		_, fixed := isFixed(g.elems[0])
 		return true, fixed, g.Split(1)
diff --git a/lib/glob/glob_test.go b/lib/glob/glob_test.go
index 194af7e..2b8aea3 100644
--- a/lib/glob/glob_test.go
+++ b/lib/glob/glob_test.go
@@ -109,7 +109,7 @@
 }
 
 func TestBadPattern(t *testing.T) {
-	tests := []string{"[", "[foo", "[^foo", "\\"}
+	tests := []string{"[", "[foo", "[^foo", "\\", "a\\", "abc[foo", "a//b"}
 	for _, test := range tests {
 		if _, err := Parse(test); err == nil {
 			t.Errorf("Unexpected success for %q", test)