mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-13 08:05:19 +09:00
fix(observability-proxy): accept bare seconds only as plain digits
Bare seconds were parsed with ParseFloat, which also takes signs, exponents, Inf and NaN. Such a start fell through to the relative duration form and silently moved the window, so 1.7937864e9 meant 1970 rather than an error, and NaN converted differently per CPU architecture. Only digits with an optional fraction are taken now; everything else is a 400. Assisted-by: LLM Signed-off-by: ZverGuy <maximbel2003@gmail.com>
This commit is contained in:
1 parent
8eef2fa5d2
commit
4e8071aa2b
2 files changed
+14
-3
No files matched your search
@@ -264,9 +264,12 @@ var durationUnits = map[string]time.Duration{
|
||||
// parseDuration accepts the LogsQL duration forms (1h30m, 1d, 2w) and bare
|
||||
// seconds; Go's parser knows neither d nor w.
|
||||
func parseDuration(s string) (time.Duration, error) {
|
||||
if f, err := strconv.ParseFloat(s, 64); err == nil {
|
||||
if f < 0 {
|
||||
return 0, fmt.Errorf("negative duration %q", s)
|
||||
// Bare seconds only as digits with an optional fraction: ParseFloat
|
||||
// would also take signs, exponents, Inf and NaN.
|
||||
if whole, frac, ok := strings.Cut(s, "."); isDigits(whole) && (!ok || isDigits(frac)) {
|
||||
f, err := strconv.ParseFloat(s, 64)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid duration %q", s)
|
||||
}
|
||||
return time.Duration(f * float64(time.Second)), nil
|
||||
}
|
||||
|
||||
@@ -128,6 +128,14 @@ func TestBuildLogsParamsRejects(t *testing.T) {
|
||||
{"bad start", "query", url.Values{"start": {"yesterday"}}, http.StatusBadRequest},
|
||||
{"millisecond timestamp", "query", url.Values{"start": {"1793786400000"}}, http.StatusBadRequest},
|
||||
{"year-like number", "query", url.Values{"start": {"2026"}}, http.StatusBadRequest},
|
||||
{"exponent time", "query", url.Values{"start": {"1.7937864e9"}}, http.StatusBadRequest},
|
||||
{"signed time", "query", url.Values{"start": {"+1793786400"}}, http.StatusBadRequest},
|
||||
{"exponent duration", "query", url.Values{"start": {"3e2"}}, http.StatusBadRequest},
|
||||
{"trailing dot", "query", url.Values{"start": {"300."}}, http.StatusBadRequest},
|
||||
{"infinite time", "query", url.Values{"end": {"Inf"}}, http.StatusBadRequest},
|
||||
{"NaN time", "query", url.Values{"start": {"NaN"}}, http.StatusBadRequest},
|
||||
{"NaN step", "hits", url.Values{"step": {"NaN"}}, http.StatusBadRequest},
|
||||
{"NaN start_offset", "tail", url.Values{"start_offset": {"NaN"}}, http.StatusBadRequest},
|
||||
{"bad limit", "query", url.Values{"limit": {"-1"}}, http.StatusBadRequest},
|
||||
{"zero limit", "query", url.Values{"limit": {"0"}}, http.StatusBadRequest},
|
||||
{"bad step", "hits", url.Values{"step": {"0s"}}, http.StatusBadRequest},
|
||||
|
||||
Reference in new issue
Block a user