From a964fa49b7127c03707128dd82944519bd8adbba Mon Sep 17 00:00:00 2001 From: Johan Lindh Date: Thu, 30 Apr 2026 13:48:28 +0200 Subject: [PATCH] fix(runner): improve timestamp filename errors --- pkg/runner/runner.go | 23 ++++++++++++++++------- pkg/runner/runner_test.go | 17 +++++++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 17cb068..066e9a6 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -2461,21 +2461,30 @@ timerLoop: edm.log.Info("histogramSender: exiting loop") } -func timestampsFromFilename(name string) (time.Time, time.Time, error) { +func timestampsFromFilename(name string) (startTime time.Time, stopTime time.Time, err error) { // expected name format: dns_histogram-2023-11-29T13-50-00Z_2023-11-29T13-51-00Z.parquet trimmedName := strings.TrimSuffix(name, ".parquet") nameParts := strings.SplitN(trimmedName, "-", 2) + if len(nameParts) != 2 { + err = fmt.Errorf("timestampFromFilename: missing '-' separating prefix from timestamps in %q", name) + return + } times := strings.Split(nameParts[1], "_") - startTime, err := time.Parse("2006-01-02T15-04-05Z07:00", times[0]) + if len(times) != 2 { + err = fmt.Errorf("timestampFromFilename: missing '_' separating start and stop timestamps in %q", name) + return + } + startTime, err = time.Parse("2006-01-02T15-04-05Z07:00", times[0]) if err != nil { - return time.Time{}, time.Time{}, fmt.Errorf("timestampFromFilename: unable to parse startTime: %w", err) + err = fmt.Errorf("timestampFromFilename: unable to parse startTime: %w", err) + return } - stopTime, err := time.Parse("2006-01-02T15-04-05Z07:00", times[1]) + stopTime, err = time.Parse("2006-01-02T15-04-05Z07:00", times[1]) if err != nil { - return time.Time{}, time.Time{}, fmt.Errorf("timestampFromFilename: unable to parse stopTime: %w", err) + err = fmt.Errorf("timestampFromFilename: unable to parse stopTime: %w", err) + return } - - return startTime, stopTime, nil + return } func (edm *dnstapMinimiser) newQnamePublisher(wg *sync.WaitGroup) { diff --git a/pkg/runner/runner_test.go b/pkg/runner/runner_test.go index 2bbe84b..cc2dce9 100644 --- a/pkg/runner/runner_test.go +++ b/pkg/runner/runner_test.go @@ -215,6 +215,23 @@ func TestWKD(t *testing.T) { } } +func TestTimestampsFromFilenameRejectsMalformedNames(t *testing.T) { + tests := []string{ + "dns_histogram.parquet", + "dns_histogram-2026-04-30T12-00-00Z.parquet", + "dns_histogram-bad_2026-04-30T12-01-00Z.parquet", + "dns_histogram-2026-04-30T12-00-00Z_bad.parquet", + } + + for _, name := range tests { + t.Run(name, func(t *testing.T) { + if _, _, err := timestampsFromFilename(name); err == nil { + t.Fatal("timestampsFromFilename returned nil error") + } + }) + } +} + func TestIgnoredClientIPsValid(t *testing.T) { discardLogger := slog.NewTextHandler(io.Discard, nil) logger := slog.New(discardLogger)