From 5081481ca852c6bb9af66da1a922183b48e79796 Mon Sep 17 00:00:00 2001 From: Jason Wilder Date: Fri, 26 Jun 2015 12:02:46 -0600 Subject: [PATCH] Return error when parsing fields with no name Fixes #3061 --- tsdb/points.go | 28 +++++++++++++++++++++++----- tsdb/points_test.go | 28 +++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/tsdb/points.go b/tsdb/points.go index ea3a3c1bf4..d900a7c68d 100644 --- a/tsdb/points.go +++ b/tsdb/points.go @@ -328,8 +328,11 @@ func scanFields(buf []byte, i int) (int, []byte, error) { i = start quoted := false - // tracks whether we've see at least one '=' - hasSeparator := false + // tracks how many '=' we've seen + equals := 0 + + // tracks how many commas we've seen + commas := 0 for { // reached the end of buf? @@ -350,9 +353,19 @@ func scanFields(buf []byte, i int) (int, []byte, error) { continue } - // If we see an =, ensure that there is at least on char after it + // If we see an =, ensure that there is at least on char before and after it if buf[i] == '=' && !quoted { - hasSeparator = true + equals += 1 + + // check for "... =123" but allow "a\ =123" + if buf[i-1] == ' ' && buf[i-2] != '\\' { + return i, buf[start:i], fmt.Errorf("missing field name") + } + + // check for "...a=123,=456" but allow "a=123,a\,=456" + if buf[i-1] == ',' && buf[i-2] != '\\' { + return i, buf[start:i], fmt.Errorf("missing field name") + } // check for "... value=" if i+1 >= len(buf) { @@ -384,6 +397,10 @@ func scanFields(buf []byte, i int) (int, []byte, error) { } } + if buf[i] == ',' && !quoted { + commas += 1 + } + // reached end of block? if buf[i] == ' ' && !quoted { break @@ -395,7 +412,8 @@ func scanFields(buf []byte, i int) (int, []byte, error) { return i, buf[start:i], fmt.Errorf("unbalanced quotes") } - if !hasSeparator { + // check that all field sections had key and values (e.g. prevent "a=1,b" + if equals == 0 || commas != equals-1 { return i, buf[start:i], fmt.Errorf("invalid field format") } diff --git a/tsdb/points_test.go b/tsdb/points_test.go index 83147772f1..a4c6e886ed 100644 --- a/tsdb/points_test.go +++ b/tsdb/points_test.go @@ -166,6 +166,28 @@ func TestParsePointMissingTagValue(t *testing.T) { } } +func TestParsePointMissingFieldName(t *testing.T) { + _, err := ParsePointsString(`cpu,host=serverA,region=us-west =`) + if err == nil { + t.Errorf(`ParsePoints("%s") mismatch. got nil, exp error`, `cpu,host=serverA,region=us-west =`) + } + + _, err = ParsePointsString(`cpu,host=serverA,region=us-west =123`) + if err == nil { + t.Errorf(`ParsePoints("%s") mismatch. got nil, exp error`, `cpu,host=serverA,region=us-west =123`) + } + + _, err = ParsePointsString(`cpu,host=serverA,region=us-west a\ =123`) + if err != nil { + t.Errorf(`ParsePoints("%s") mismatch. got nil, exp error`, `cpu,host=serverA,region=us-west a\ =123`) + } + _, err = ParsePointsString(`cpu,host=serverA,region=us-west value=123,=456`) + if err == nil { + t.Errorf(`ParsePoints("%s") mismatch. got nil, exp error`, `cpu,host=serverA,region=us-west value=123,=456`) + } + +} + func TestParsePointMissingFieldValue(t *testing.T) { _, err := ParsePointsString(`cpu,host=serverA,region=us-west value=`) if err == nil { @@ -187,6 +209,10 @@ func TestParsePointMissingFieldValue(t *testing.T) { t.Errorf(`ParsePoints("%s") mismatch. got nil, exp error`, `cpu,host=server01,region=us-west 1434055562000000000`) } + _, err = ParsePointsString(`cpu,host=server01,region=us-west value=1,b`) + if err == nil { + t.Errorf(`ParsePoints("%s") mismatch. got nil, exp error`, `cpu,host=server01,region=us-west value=1,b`) + } } func TestParsePointBadNumber(t *testing.T) { @@ -594,7 +620,7 @@ func TestParsePointEscapedStringsAndCommas(t *testing.T) { } func TestParsePointWithStringWithEquals(t *testing.T) { - test(t, `cpu,host=serverA,region=us-east str="foo=bar",value=1.0, 1000000000`, + test(t, `cpu,host=serverA,region=us-east str="foo=bar",value=1.0 1000000000`, NewPoint( "cpu", Tags{