From 35069910f532b9078236177052425ae9605880c8 Mon Sep 17 00:00:00 2001 From: Marco Pracucci Date: Sat, 1 Jul 2023 14:29:59 +0200 Subject: [PATCH] Fix infinite loop in index Writer when a series contains duplicated label names Signed-off-by: Marco Pracucci --- tsdb/index/index.go | 5 ++++- tsdb/index/index_test.go | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/tsdb/index/index.go b/tsdb/index/index.go index 50a701d3a..ef2d167dc 100644 --- a/tsdb/index/index.go +++ b/tsdb/index/index.go @@ -864,7 +864,10 @@ func (w *Writer) writePostingsToTmpFiles() error { // using more memory than a single label name can. for len(names) > 0 { if w.labelNames[names[0]]+c > maxPostings { - break + if c > 0 { + break + } + return fmt.Errorf("corruption detected when writing postings to index: label %q has %d uses, but maxPostings is %d", names[0], w.labelNames[names[0]], maxPostings) } batchNames = append(batchNames, names[0]) c += w.labelNames[names[0]] diff --git a/tsdb/index/index_test.go b/tsdb/index/index_test.go index e4cee4a55..a978ba186 100644 --- a/tsdb/index/index_test.go +++ b/tsdb/index/index_test.go @@ -471,6 +471,21 @@ func TestPersistence_index_e2e(t *testing.T) { require.NoError(t, ir.Close()) } +func TestWriter_ShouldReturnErrorOnSeriesWithDuplicatedLabelNames(t *testing.T) { + w, err := NewWriter(context.Background(), filepath.Join(t.TempDir(), "index")) + require.NoError(t, err) + + require.NoError(t, w.AddSymbol("__name__")) + require.NoError(t, w.AddSymbol("metric_1")) + require.NoError(t, w.AddSymbol("metric_2")) + + require.NoError(t, w.AddSeries(0, labels.FromStrings("__name__", "metric_1", "__name__", "metric_2"))) + + err = w.Close() + require.Error(t, err) + require.ErrorContains(t, err, "corruption detected when writing postings to index") +} + func TestDecbufUvarintWithInvalidBuffer(t *testing.T) { b := realByteSlice([]byte{0x81, 0x81, 0x81, 0x81, 0x81, 0x81})