Skip to content

Commit

Permalink
CIRC-9980: Remove quote handling from metric name parser (#100)
Browse files Browse the repository at this point in the history
* CIRC-9980: Remove quote handling from metric name parser

* CIRC-9980: Update changelog
  • Loading branch information
dhaifley committed Mar 10, 2023
1 parent d0d5164 commit 9aa7b6a
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 164 deletions.
6 changes: 6 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ to [Semantic Versioning](http://semver.org/) rules.

## [Next Release]

## [v1.13.3] - 2023-03-10

* fix: Removes quote handling from the metric name parser. This handling is
correct for tag queries, but not for canonical name parsing.

## [v1.13.2] - 2023-03-09

* add: Adds a configuration item, DenyHosts, to allow a list of hosts to
Expand Down Expand Up @@ -465,6 +470,7 @@ writing to histogram endpoints.
any delay, once started. Created: 2019-03-12. Fixed: 2019-03-13.

[Next Release]: https://github.com/circonus-labs/gosnowth
[v1.13.3]: https://github.com/circonus-labs/gosnowth/releases/tag/v1.13.3
[v1.13.2]: https://github.com/circonus-labs/gosnowth/releases/tag/v1.13.2
[v1.13.1]: https://github.com/circonus-labs/gosnowth/releases/tag/v1.13.1
[v1.13.0]: https://github.com/circonus-labs/gosnowth/releases/tag/v1.13.0
Expand Down
168 changes: 7 additions & 161 deletions metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,95 +205,17 @@ func (ms *metricScanner) scanTagName() (scanToken, string, string, error) {

var can bytes.Buffer

quoted := false

loop:
for {
ch := ms.read()
switch ch {
case '"':
quoted = !quoted

if _, err := buf.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name buffer: %w", err)
}

if _, err := can.WriteRune(ch); err != nil {
case ':':
if err := ms.unread(); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name canonical buffer: %w", err)
}
case '\\':
if quoted { //nolint:nestif
ch2 := ms.read()
if ch2 == '"' || ch2 == '\\' {
if _, err := buf.WriteRune(ch2); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name buffer: %w", err)
}

if _, err := can.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name canonical buffer: %w", err)
}

if _, err := can.WriteRune(ch2); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name canonical buffer: %w", err)
}
} else {
if err := ms.unread(); err != nil {
if _, err := buf.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to unread rune from tag name: %w", err)
}

if _, err := can.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name canonical buffer: %w", err)
}
}

if _, err := buf.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name buffer: %w", err)
}

if _, err := can.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name canonical buffer: %w", err)
}
}
} else {
if _, err := buf.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name buffer: %w", err)
}

if _, err := can.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name canonical buffer: %w", err)
}
"unable to unread to scan buffer: %w", err)
}
case ':':
if !quoted {
if err := ms.unread(); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to unread to scan buffer: %w", err)
}

break loop
} else {
if _, err := buf.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name buffer: %w", err)
}

if _, err := can.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name canonical buffer: %w", err)
}
}
break loop
case rune(0): // EOF
break loop
default:
Expand All @@ -313,84 +235,18 @@ loop:
}

// scanTagValue attempts to read a tag value token from the scan buffer.
func (ms *metricScanner) scanTagValue( //nolint:gocyclo
func (ms *metricScanner) scanTagValue(
tt tagType,
) (scanToken, string, string, error) {
var buf, can bytes.Buffer

quoted := false

loop:
for {
ch := ms.read()
switch ch {
case '"':
quoted = !quoted

if _, err := buf.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name buffer: %w", err)
}

if _, err := can.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to canonical tag name buffer: %w", err)
}
case '\\':
if quoted { //nolint:nestif
ch2 := ms.read()
if ch2 == '"' || ch2 == '\\' {
if _, err := buf.WriteRune(ch2); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name buffer: %w", err)
}

if _, err := can.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to canonical tag name buffer: %w", err)
}

if _, err := can.WriteRune(ch2); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to canonical tag name buffer: %w", err)
}
} else {
if err := ms.unread(); err != nil {
if _, err := buf.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to unread rune from tag name: %w", err)
}

if _, err := can.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to canonical tag name buffer: %w", err)
}
}

if _, err := buf.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name buffer: %w", err)
}

if _, err := can.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to canonical tag name buffer: %w", err)
}
}
} else {
if _, err := buf.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to tag name buffer: %w", err)
}

if _, err := can.WriteRune(ch); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to write to canonical tag name buffer: %w", err)
}
}
case ',', ']', '}':
if !quoted && (ch == ',' || (ch == ']' && tt == tagStreamTag) ||
(ch == '}' && tt == tagMeasurementTag)) {
if ch == ',' || (ch == ']' && tt == tagStreamTag) ||
(ch == '}' && tt == tagMeasurementTag) {
if err := ms.unread(); err != nil {
return tokenIllegal, "", "", fmt.Errorf(
"unable to unread to scan buffer: %w", err)
Expand Down Expand Up @@ -489,11 +345,6 @@ func (mp *MetricParser) parseTagSet(tt tagType) (string, []Tag, error) {
tag.Category = string(b)
}

if strings.HasPrefix(tag.Category, `"`) &&
strings.HasSuffix(tag.Category, `"`) {
tag.Category = strings.Trim(tag.Category, `"`)
}

canonical.WriteString(can)

if tok, lit = mp.s.scan(); tok != tokenColon {
Expand Down Expand Up @@ -529,11 +380,6 @@ func (mp *MetricParser) parseTagSet(tt tagType) (string, []Tag, error) {
tag.Value = string(b)
}

if strings.HasPrefix(tag.Value, `"`) &&
strings.HasSuffix(tag.Value, `"`) {
tag.Value = strings.Trim(tag.Value, `"`)
}

canonical.WriteString(can)

tags = append(tags, tag)
Expand Down
6 changes: 3 additions & 3 deletions metric_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,19 +235,19 @@ func TestMetricParser(t *testing.T) {
lit: "testing",
},
{
input: `testing|ST["blah:|ST[]":blah]|MT{blah:",}:|MTblah"}`,
input: `testing|ST["blah":blah]|MT{blah:"MTblah"}`,
numST: 1,
numMT: 1,
lit: "testing",
},
{
input: `testing|ST["blah:|ST[]":blah]|MT{blah:",}:|MTblah"}`,
input: `testing|ST["blah":blah]|MT{blah:"|MTblah"}`,
numST: 1,
numMT: 1,
lit: "testing",
},
{
input: `testing|ST["b:|ST[]":b]|MT{b:",}:|MTb"}|ST[a:b]|MT{c:d}`,
input: `testing|ST["b":"b"]|MT{b:"MTb"}|ST[a:b]|MT{c:d}`,
numST: 2,
numMT: 2,
lit: "testing",
Expand Down

0 comments on commit 9aa7b6a

Please sign in to comment.