From 5072db40c25e979839920e6833a967fee40b1bec Mon Sep 17 00:00:00 2001 From: "Jonathan A. Sternberg" Date: Wed, 8 Mar 2017 13:54:18 -0600 Subject: [PATCH] Forbid wildcards in binary expressions When rewriting fields, wildcards within binary expressions were skipped. This now throws an error whenever it finds a wildcard within a binary expression in order to prevent the panic that occurs. --- CHANGELOG.md | 1 + influxql/ast.go | 20 ++++++++++++++++++ influxql/ast_test.go | 50 ++++++++++++++++++++++++++++++++++++++------ 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a28a8dc414..8a30a459994 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ ### Bugfixes - [#8091](https://github.com/influxdata/influxdb/issues/8091): Do not increment the continuous query statistic if no query is run. +- [#8064](https://github.com/influxdata/influxdb/issues/8064): Forbid wildcards in binary expressions. ## v1.2.2 [2017-03-14] diff --git a/influxql/ast.go b/influxql/ast.go index 8a86b343d7e..d1e3ee15849 100644 --- a/influxql/ast.go +++ b/influxql/ast.go @@ -1273,6 +1273,26 @@ func (s *SelectStatement) RewriteFields(m FieldMapper) (*SelectStatement, error) Alias: fmt.Sprintf("%s_%s", f.Name(), ref.Val), }) } + case *BinaryExpr: + // Search for regexes or wildcards within the binary + // expression. If we find any, throw an error indicating that + // it's illegal. + var regex, wildcard bool + WalkFunc(expr, func(n Node) { + switch n.(type) { + case *RegexLiteral: + regex = true + case *Wildcard: + wildcard = true + } + }) + + if wildcard { + return nil, fmt.Errorf("unsupported expression with wildcard: %s", f.Expr) + } else if regex { + return nil, fmt.Errorf("unsupported expression with regex field: %s", f.Expr) + } + rwFields = append(rwFields, f) default: rwFields = append(rwFields, f) } diff --git a/influxql/ast_test.go b/influxql/ast_test.go index 74e6779c8a4..646f73a9242 100644 --- a/influxql/ast_test.go +++ b/influxql/ast_test.go @@ -326,6 +326,7 @@ func TestSelectStatement_RewriteFields(t *testing.T) { var tests = []struct { stmt string rewrite string + err string }{ // No wildcards { @@ -462,6 +463,35 @@ func TestSelectStatement_RewriteFields(t *testing.T) { stmt: `SELECT * FROM (SELECT mean(value1) FROM cpu GROUP BY host) GROUP BY *`, rewrite: `SELECT mean::float FROM (SELECT mean(value1::float) FROM cpu GROUP BY host) GROUP BY host`, }, + + // Invalid queries that can't be rewritten should return an error (to + // avoid a panic in the query engine) + { + stmt: `SELECT count(*) / 2 FROM cpu`, + err: `unsupported expression with wildcard: count(*) / 2`, + }, + + { + stmt: `SELECT * / 2 FROM (SELECT count(*) FROM cpu)`, + err: `unsupported expression with wildcard: * / 2`, + }, + + { + stmt: `SELECT count(/value/) / 2 FROM cpu`, + err: `unsupported expression with regex field: count(/value/) / 2`, + }, + + // This one should be possible though since there's no wildcard in the + // binary expression. + { + stmt: `SELECT value1 + value2, * FROM cpu`, + rewrite: `SELECT value1::float + value2::integer, host::tag, region::tag, value1::float, value2::integer FROM cpu`, + }, + + { + stmt: `SELECT value1 + value2, /value/ FROM cpu`, + rewrite: `SELECT value1::float + value2::integer, value1::float, value2::integer FROM cpu`, + }, } for i, tt := range tests { @@ -496,12 +526,20 @@ func TestSelectStatement_RewriteFields(t *testing.T) { // Rewrite statement. rw, err := stmt.(*influxql.SelectStatement).RewriteFields(&ic) - if err != nil { - t.Errorf("%d. %q: error: %s", i, tt.stmt, err) - } else if rw == nil { - t.Errorf("%d. %q: unexpected nil statement", i, tt.stmt) - } else if rw := rw.String(); tt.rewrite != rw { - t.Errorf("%d. %q: unexpected rewrite:\n\nexp=%s\n\ngot=%s\n\n", i, tt.stmt, tt.rewrite, rw) + if tt.err != "" { + if err != nil && err.Error() != tt.err { + t.Errorf("%d. %q: unexpected error: %s != %s", i, tt.stmt, err.Error(), tt.err) + } else if err == nil { + t.Errorf("%d. %q: expected error", i, tt.stmt) + } + } else { + if err != nil { + t.Errorf("%d. %q: error: %s", i, tt.stmt, err) + } else if rw == nil && tt.err == "" { + t.Errorf("%d. %q: unexpected nil statement", i, tt.stmt) + } else if rw := rw.String(); tt.rewrite != rw { + t.Errorf("%d. %q: unexpected rewrite:\n\nexp=%s\n\ngot=%s\n\n", i, tt.stmt, tt.rewrite, rw) + } } } }