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.
pull/5158/head
Jonathan A. Sternberg 2015-12-17 15:38:27 -05:00
parent 3264ab02b4
commit 4813d82285
3 changed files with 32 additions and 12 deletions

View File

@ -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]

View File

@ -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

View File

@ -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")
}
}