From b02928629851a8445447fd2c4a7adbbb91d88e83 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 06518619d..5cad4bcd3 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -46,7 +46,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")