mirror of
https://github.com/coredns/coredns.git
synced 2026-04-05 03:35:33 -04:00
fix(kubernetes): sanitize non-UTF-8 host in metrics (#7998)
This commit is contained in:
@@ -3,7 +3,9 @@ package kubernetes
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/coredns/coredns/plugin"
|
||||
|
||||
@@ -64,7 +66,7 @@ type latencyAdapter struct {
|
||||
}
|
||||
|
||||
func (l *latencyAdapter) Observe(_ context.Context, verb string, u url.URL, latency time.Duration) {
|
||||
l.m.WithLabelValues(verb, u.Host).Observe(latency.Seconds())
|
||||
l.m.WithLabelValues(verb, sanitizeLabelValue(u.Host)).Observe(latency.Seconds())
|
||||
}
|
||||
|
||||
type resultAdapter struct {
|
||||
@@ -72,5 +74,14 @@ type resultAdapter struct {
|
||||
}
|
||||
|
||||
func (r *resultAdapter) Increment(_ context.Context, code, method, host string) {
|
||||
r.m.WithLabelValues(code, method, host).Inc()
|
||||
r.m.WithLabelValues(code, method, sanitizeLabelValue(host)).Inc()
|
||||
}
|
||||
|
||||
// sanitizeLabelValue ensures the string is valid UTF-8, which is required by
|
||||
// Prometheus for label values. Invalid bytes are replaced with U+FFFD.
|
||||
func sanitizeLabelValue(s string) string {
|
||||
if utf8.ValidString(s) {
|
||||
return s
|
||||
}
|
||||
return strings.ToValidUTF8(s, "\uFFFD")
|
||||
}
|
||||
|
||||
27
plugin/kubernetes/metrics_test.go
Normal file
27
plugin/kubernetes/metrics_test.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package kubernetes
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestSanitizeLabelValue(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{"valid ASCII", "example.com", "example.com"},
|
||||
{"valid UTF-8", "例え.jp", "例え.jp"},
|
||||
{"empty string", "", ""},
|
||||
{"invalid single byte", "host\xff:443", "host\uFFFD:443"},
|
||||
{"consecutive invalid bytes", "\xff\xfe\xfd", "\uFFFD"},
|
||||
{"mixed valid and invalid", "ok\xffok\xfeok", "ok\uFFFDok\uFFFDok"},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := sanitizeLabelValue(tc.input)
|
||||
if got != tc.expected {
|
||||
t.Errorf("sanitizeLabelValue(%q) = %q, want %q", tc.input, got, tc.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user