From 4813d822857434778065eeb740e9024a93beafd7 Mon Sep 17 00:00:00 2001 From: "Jonathan A. Sternberg" Date: Thu, 17 Dec 2015 15:38:27 -0500 Subject: [PATCH] Fix the line protocol scanner to read field keys with quotes correctly Quotes are not supposed to be significant in field keys, but are significant in field values. The code as it currently was would consider quotes in a key to be significant, but the later parser that would unmarshal the fields from the byte string did not consider those quotes to be significant. This meant that the following string: "a=1 The line protocol parser would see a mismatched quote instead of a valid input to the line protocol. But more nefariously, the following string: "a=1"=2 The line protocol parser would ignore the first equals since it is located in the quotation marks and think this was a valid input. It would then pass it on to the field parser who would panic and die when it tried to parse `1"=2` as a number. Fixes #4076. --- CHANGELOG.md | 3 ++- models/points.go | 16 +++++----------- models/points_test.go | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a88a5e14fa..7cbbe0fb8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,8 @@ With this release InfluxDB is moving to Go 1.5. - [#5079](https://github.com/influxdb/influxdb/pull/5079): Ensure tsm WAL encoding buffer can handle large batches. - [#4303](https://github.com/influxdb/influxdb/issues/4303): Don't drop measurements or series from multiple databases. - [#5078](https://github.com/influxdb/influxdb/issues/5078): influx non-interactive mode - INSERT must be handled. Thanks @grange74 -- [[#5178](https://github.com/influxdb/influxdb/pull/5178): SHOW FIELD shouln't consider VALUES to be valid. Thanks @pires +- [#5178](https://github.com/influxdb/influxdb/pull/5178): SHOW FIELD shouldn't consider VALUES to be valid. Thanks @pires +- [#5158](https://github.com/influxdb/influxdb/pull/5158): Fix panic when writing invalid input to the line protocol. ## v0.9.6 [2015-12-09] diff --git a/models/points.go b/models/points.go index b7669a1b54..ca3945f3c7 100644 --- a/models/points.go +++ b/models/points.go @@ -534,20 +534,14 @@ func scanFields(buf []byte, i int) (int, []byte, error) { // escaped characters? if buf[i] == '\\' && i+1 < len(buf) { - - // Is this an escape char within a string field? Only " and \ are allowed. - if quoted && (buf[i+1] == '"' || buf[i+1] == '\\') { - i += 2 - continue - // Non-string field escaped chars - } else if !quoted && isFieldEscapeChar(buf[i+1]) { - i += 2 - continue - } + i += 2 + continue } // If the value is quoted, scan until we get to the end quote - if buf[i] == '"' { + // Only quote values in the field value since quotes are not significant + // in the field key + if buf[i] == '"' && equals > commas { quoted = !quoted i++ continue diff --git a/models/points_test.go b/models/points_test.go index 36f2986d81..05f0d895e9 100644 --- a/models/points_test.go +++ b/models/points_test.go @@ -1658,3 +1658,28 @@ func TestParsePointsStringWithExtraBuffer(t *testing.T) { t.Fatalf("expected both keys are same but got %s and %s", key, pointKey) } } + +func TestParsePointsQuotesInFieldKey(t *testing.T) { + buf := `cpu "a=1` + points, err := models.ParsePointsString(buf) + if err != nil { + t.Fatalf("failed to write points: %s", err.Error()) + } + + pointFields := points[0].Fields() + value, ok := pointFields["\"a"] + if !ok { + t.Fatalf("expected to parse field '\"a'") + } + + if value != float64(1) { + t.Fatalf("expected field value to be 1, got %v", value) + } + + // The following input should not parse + buf = `cpu "\, '= "\ v=1.0` + _, err = models.ParsePointsString(buf) + if err == nil { + t.Fatalf("expected parsing failure but got no error") + } +}