Skip to content

Commit

Permalink
fix #2281: passthru escapes when parsing regex
Browse files Browse the repository at this point in the history
Make the InfluxQL parser check for '\/' escape and pass all other
escapes through to the Go regexp parser unmodified.
  • Loading branch information
dgnorton committed May 4, 2015
1 parent 5bd53e5 commit 78f458b
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 8 deletions.
24 changes: 16 additions & 8 deletions influxql/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func (s *Scanner) ScanRegex() (tok Token, pos Pos, lit string) {
// Valid escape chars.
escapes := map[rune]rune{'/': '/'}

b, err := ScanDelimited(s.r, start, end, escapes)
b, err := ScanDelimited(s.r, start, end, escapes, true)

if err == errBadEscape {
_, pos = s.r.curr()
Expand Down Expand Up @@ -443,7 +443,7 @@ func (r *reader) curr() (ch rune, pos Pos) {
// eof is a marker code point to signify that the reader can't read any more.
const eof = rune(0)

func ScanDelimited(r io.RuneScanner, start, end rune, escapes map[rune]rune) ([]byte, error) {
func ScanDelimited(r io.RuneScanner, start, end rune, escapes map[rune]rune, escapesPassThru bool) ([]byte, error) {
// Scan start delimiter.
if ch, _, err := r.ReadRune(); err != nil {
return nil, err
Expand All @@ -468,15 +468,23 @@ func ScanDelimited(r io.RuneScanner, start, end rune, escapes map[rune]rune) ([]
return nil, err
}

r, ok := escapes[ch1]
c, ok := escapes[ch1]
if !ok {
buf.Reset()
_, _ = buf.WriteRune(ch0)
_, _ = buf.WriteRune(ch1)
return buf.Bytes(), errBadEscape
if escapesPassThru {
// Unread ch1 (char after the \)
_ = r.UnreadRune()
// Write ch0 (\) to the output buffer.
_, _ = buf.WriteRune(ch0)
continue
} else {
buf.Reset()
_, _ = buf.WriteRune(ch0)
_, _ = buf.WriteRune(ch1)
return buf.Bytes(), errBadEscape
}
}

_, _ = buf.WriteRune(r)
_, _ = buf.WriteRune(c)
} else {
_, _ = buf.WriteRune(ch0)
}
Expand Down
26 changes: 26 additions & 0 deletions influxql/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,29 @@ func TestScanString(t *testing.T) {
}
}
}

// Test scanning regex
func TestScanRegex(t *testing.T) {
var tests = []struct {
in string
tok influxql.Token
lit string
err string
}{
{in: `/^payments\./`, tok: influxql.REGEX, lit: `^payments\.`},

This comment has been minimized.

Copy link
@marcosnils

marcosnils May 4, 2015

Contributor

@dgnorton If you're escaping the .(dot) here, Shouldn't the literal string be ^payments.?. Why are you returning the backslash as it's only the escape character?

{in: `/foo\/bar/`, tok: influxql.REGEX, lit: `foo/bar`},
{in: `/foo\\/bar/`, tok: influxql.REGEX, lit: `foo\/bar`},
{in: `/foo\\bar/`, tok: influxql.REGEX, lit: `foo\\bar`},
}

for i, tt := range tests {
s := influxql.NewScanner(strings.NewReader(tt.in))
tok, _, lit := s.ScanRegex()
if tok != tt.tok {
t.Errorf("%d. %s: error:\n\texp=%s\n\tgot=%s\n", i, tt.in, tt.tok.String(), tok.String())
}
if lit != tt.lit {
t.Errorf("%d. %s: error:\n\texp=%s\n\tgot=%s\n", i, tt.in, tt.lit, lit)
}
}
}

0 comments on commit 78f458b

Please sign in to comment.