From 775e3d9e5599594d6dac35de777274bc90268bc2 Mon Sep 17 00:00:00 2001 From: David Norton Date: Fri, 17 Apr 2015 18:15:55 -0400 Subject: [PATCH] fix #2281: passthru escapes when parsing regex --- CHANGELOG.md | 3 ++- influxql/scanner.go | 24 ++++++++++++++++-------- influxql/scanner_test.go | 26 ++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46a9a79e0d..5706230d8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,13 +5,14 @@ - [#2469](https://github.com/influxdb/influxdb/pull/2469): Reduce default max topic size from 1GB to 50MB. ### Bugfixes -- [#2446] (https://github.com/influxdb/influxdb/pull/2446): Correctly count number of queries executed. Thanks @neonstalwart +- [#2446](https://github.com/influxdb/influxdb/pull/2446): Correctly count number of queries executed. Thanks @neonstalwart - [#2452](https://github.com/influxdb/influxdb/issues/2452): Fix panic with shard stats on multiple clusters - [#2453](https://github.com/influxdb/influxdb/pull/2453): Do not require snapshot on Log.WriteEntriesTo(). - [#2460](https://github.com/influxdb/influxdb/issues/2460): Collectd input should use "value" for fields values. Fixes 2412. Thanks @josh-padnick - [#2465](https://github.com/influxdb/influxdb/pull/2465): HTTP response logging paniced with chunked requests. Thanks @Jackkoz - [#2475](https://github.com/influxdb/influxdb/pull/2475): RLock server when checking if shards groups are required during write. - [#2471](https://github.com/influxdb/influxdb/issues/2471): Function calls normalized to be lower case. Fixes percentile not working when called uppercase. Thanks @neonstalwart +- [#2281](https://github.com/influxdb/influxdb/issues/2281): Fix Bad Escape error when parsing regex ## v0.9.0-rc28 [04-27-2015] diff --git a/influxql/scanner.go b/influxql/scanner.go index 8ec1aa1100..27bcf414fb 100644 --- a/influxql/scanner.go +++ b/influxql/scanner.go @@ -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() @@ -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 @@ -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) } diff --git a/influxql/scanner_test.go b/influxql/scanner_test.go index e3a03a3532..ab0aab2e4f 100644 --- a/influxql/scanner_test.go +++ b/influxql/scanner_test.go @@ -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\.`}, + {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) + } + } +}