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 <roman@victoriametrics.com>
This commit is contained in:
Haleygo 2023-07-03 19:11:49 +08:00 committed by Aliaksandr Valialkin
parent 7ff0ac1a33
commit b029286298
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
3 changed files with 12 additions and 1 deletions

View file

@ -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/<tag_name>` 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)

View file

@ -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, "-") {

View file

@ -91,6 +91,7 @@ func TestParseTimeFailure(t *testing.T) {
}
f("")
f("2263")
f("23-45:50")
f("1223-fo:ba")
f("1223-12:ba")