Skip to content

Commit

Permalink
Fix some parser bugs around mixing [ and (
Browse files Browse the repository at this point in the history
  • Loading branch information
nelhage committed Dec 27, 2019
1 parent 8a76090 commit 910a1de
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 9 deletions.
22 changes: 15 additions & 7 deletions server/query.go
Expand Up @@ -12,7 +12,7 @@ import (
pb "github.com/livegrep/livegrep/src/proto/go_proto"
)

var pieceRE = regexp.MustCompile(`\(|(?:^([a-zA-Z0-9-_]+):|\\.)| `)
var pieceRE = regexp.MustCompile(`\[|\(|(?:^([a-zA-Z0-9-_]+):|\\.)| `)

var knownTags = map[string]bool{
"file": true,
Expand Down Expand Up @@ -79,16 +79,24 @@ func ParseQuery(query string, globalRegex bool) (pb.Query, error) {
term = ""
inRegex = globalRegex
}
} else if match == "(" {
} else if match == "(" || match == "[" {
if !(inRegex || justGotSpace) {
term += "("
term += match
} else {
// A parenthesis. Nothing is special until the
// end of a balanced set of parenthesis
// A parenthesis or a bracket. Consume
// until the end of a balanced set.
p := 1
i := 0
esc := false
var w bytes.Buffer
var open, close rune
switch match {
case "(":
open, close = '(', ')'
case "[":
open, close = '[', ']'
}

for i < len(q) {
// We decode runes ourselves instead
// of using range because exiting the
Expand All @@ -101,9 +109,9 @@ func ParseQuery(query string, globalRegex bool) (pb.Query, error) {
esc = false
case r == '\\':
esc = true
case r == '(':
case r == open:
p++
case r == ')':
case r == close:
p--
}
w.WriteRune(r)
Expand Down
22 changes: 20 additions & 2 deletions server/query_test.go
@@ -1,6 +1,7 @@
package server

import (
"encoding/json"
"reflect"
"testing"

Expand Down Expand Up @@ -153,6 +154,21 @@ func TestParseQuery(t *testing.T) {
pb.Query{Line: `a\(b`, File: "c", FoldCase: false},
true,
},
{
`[(] file:\.c`,
pb.Query{Line: `[(]`, File: "\\.c", FoldCase: true},
true,
},
{
`[ ] file:\.c`,
pb.Query{Line: `[ ]`, File: "\\.c", FoldCase: true},
true,
},
{
`[ \]] file:\.c`,
pb.Query{Line: `[ \]]`, File: "\\.c", FoldCase: true},
true,
},

// literal parse mode
{
Expand Down Expand Up @@ -200,8 +216,10 @@ func TestParseQuery(t *testing.T) {
for _, tc := range cases {
parsed, err := ParseQuery(tc.in, tc.regex)
if !reflect.DeepEqual(tc.out, parsed) {
t.Errorf("error parsing %q: expected %#v got %#v",
tc.in, tc.out, parsed)
got, _ := json.MarshalIndent(parsed, "", " ")
want, _ := json.MarshalIndent(tc.out, "", " ")
t.Errorf("error parsing %q: expected:\n%s\ngot:\n%s",
tc.in, want, got)
}
if err != nil {
t.Errorf("parse(%v) error=%v", tc.in, err)
Expand Down

0 comments on commit 910a1de

Please sign in to comment.