From 41ae8bdae7bada362a02afff8b17fce67bbf3851 Mon Sep 17 00:00:00 2001 From: Jason Wilder Date: Mon, 29 Jun 2015 15:15:50 -0600 Subject: [PATCH] Handle escaped commas in measurement name Fixes #3183 --- CHANGELOG.md | 1 + tsdb/points.go | 19 ++++++++++++++++++- tsdb/points_test.go | 16 +++++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4a1bb35a7..f61bef0e23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ - [#2678](https://github.com/influxdb/influxdb/issues/2678): Server allows tags with an empty string for the key and/or value - [#3061](https://github.com/influxdb/influxdb/issues/3061): syntactically incorrect line protocol insert panics the database - [#2608](https://github.com/influxdb/influxdb/issues/2608): drop measurement while writing points to that measurement has race condition that can panic +- [#3183](https://github.com/influxdb/influxdb/issues/3183): using line protocol measurement names cannot contain commas ## v0.9.0 [2015-06-11] diff --git a/tsdb/points.go b/tsdb/points.go index b987cd09f4..d95a1f83eb 100644 --- a/tsdb/points.go +++ b/tsdb/points.go @@ -266,6 +266,10 @@ func scanKey(buf []byte, i int) (int, []byte, error) { // reached end of the block? (next block would be fields) if buf[i] == ' ' { + // check for "cpu,tag value=1" + if equals == 0 && commas > 0 { + return i, buf[start:i], fmt.Errorf("missing tag value") + } if equals > 0 && commas-1 != equals-1 { return i, buf[start:i], fmt.Errorf("missing tag value") } @@ -620,6 +624,10 @@ func skipWhitespace(buf []byte, i int) int { return i } + if buf[i] == '\\' { + i += 2 + continue + } if buf[i] == ' ' || buf[i] == '\t' { i += 1 continue @@ -631,7 +639,7 @@ func skipWhitespace(buf []byte, i int) int { // scanTo returns the end position in buf and the next consecutive block // of bytes, starting from i and ending with stop byte. If there are leading -// spaces, they are skipped. +// spaces or escaped chars, they are skipped. func scanTo(buf []byte, i int, stop byte) (int, []byte) { start := i for { @@ -640,6 +648,11 @@ func scanTo(buf []byte, i int, stop byte) (int, []byte) { break } + if buf[i] == '\\' { + i += 2 + continue + } + // reached end of block? if buf[i] == stop { break @@ -661,6 +674,10 @@ func scanToSpaceOr(buf []byte, i int, stop byte) (int, []byte) { break } + if buf[i] == '\\' { + i += 2 + continue + } // reached end of block? if buf[i] == stop || buf[i] == ' ' { break diff --git a/tsdb/points_test.go b/tsdb/points_test.go index 308e57a66b..402aadecdc 100644 --- a/tsdb/points_test.go +++ b/tsdb/points_test.go @@ -198,7 +198,12 @@ func TestParsePointMissingTagName(t *testing.T) { } func TestParsePointMissingTagValue(t *testing.T) { - _, err := ParsePointsString(`cpu,host=serverA,region value=1`) + _, err := ParsePointsString(`cpu,host value=1`) + if err == nil { + t.Errorf(`ParsePoints("%s") mismatch. got nil, exp error`, `cpu,host value=1`) + } + + _, err = ParsePointsString(`cpu,host=serverA,region value=1`) if err == nil { t.Errorf(`ParsePoints("%s") mismatch. got nil, exp error`, `cpu,host=serverA,region value=1`) } @@ -423,6 +428,15 @@ func TestParsePointBooleanInvalid(t *testing.T) { } func TestParsePointUnescape(t *testing.T) { + test(t, `foo\,bar value=1`, + NewPoint( + "foo,bar", // comma in the name + Tags{}, + Fields{ + "value": 1, + }, + time.Unix(0, 0))) + // commas in measuremnt name test(t, `cpu\,main,regions=east\,west value=1.0`, NewPoint(