From 5fc0ee43d44a02fe06bbc2e0e41925dd1ac92445 Mon Sep 17 00:00:00 2001 From: Haleygo Date: Mon, 3 Jul 2023 19:11:49 +0800 Subject: [PATCH] fix parse for invalid partial RFC3339 format (#4539) The validation was needed for covering corner cases when storage is tested with data from 1970. This resulted into unexpected search results, as year was parsed incorrectly from the given timestamp. Co-authored-by: hagen1778 --- docs/CHANGELOG.md | 2 +- lib/promutils/time.go | 10 ++++++++++ lib/promutils/time_test.go | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index e7e9ffdae..314d199c3 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -42,7 +42,7 @@ The following tip changes can be tested by building VictoriaMetrics components f `--search.maxGraphiteTagValues` for limiting the number of tag values returned Graphite `/tags/` API. Remove redundant limit from [Prometheus api/v1/series](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#prometheus-querying-api-usage). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4339). * BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix application routing issues and problems with manual URL changes. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4408). - +* BUGFIX: add validation for invalid [partial RFC3339 timestamp formats](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#timestamp-formats) in query and export APIs. ## [v1.91.3](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.91.3) diff --git a/lib/promutils/time.go b/lib/promutils/time.go index 1f644ef40..5b999c27f 100644 --- a/lib/promutils/time.go +++ b/lib/promutils/time.go @@ -17,6 +17,12 @@ func ParseTime(s string) (float64, error) { return ParseTimeAt(s, currentTimestamp) } +const ( + // time.UnixNano can only store maxInt64, which is 2262 + maxValidYear = 2262 + minValidYear = 1970 +) + // ParseTimeAt parses time s in different formats, assuming the given currentTimestamp. // // See https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#timestamp-formats @@ -67,6 +73,10 @@ func ParseTimeAt(s string, currentTimestamp float64) (float64, error) { if err != nil { return 0, err } + y := t.Year() + if y > maxValidYear || y < minValidYear { + return 0, fmt.Errorf("cannot parse year from %q: year must in range [%d, %d]", s, minValidYear, maxValidYear) + } return tzOffset + float64(t.UnixNano())/1e9, nil } if !strings.Contains(sOrig, "-") { diff --git a/lib/promutils/time_test.go b/lib/promutils/time_test.go index cb311348d..38934eea4 100644 --- a/lib/promutils/time_test.go +++ b/lib/promutils/time_test.go @@ -91,6 +91,7 @@ func TestParseTimeFailure(t *testing.T) { } f("") + f("2263") f("23-45:50") f("1223-fo:ba") f("1223-12:ba")