mirror of
https://github.com/stefanprodan/podinfo.git
synced 2026-08-19 04:06:27 +00:00
Fix panic on GET /chunked from integer overflow
HttpServerTimeout is a time.Duration (nanoseconds); the default-delay branch scaled it by time.Second again, overflowing int64 to a negative value and passing it to rand.Intn, which panics. The bare /chunked route (no wait param) hit this on every request. Convert the timeout to whole seconds in a guarded helper that keeps rand.Intn's argument positive, and add a regression test.
This commit is contained in:
+13
-1
@@ -26,7 +26,7 @@ func (s *Server) chunkedHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
delay, err := strconv.Atoi(vars["wait"])
|
||||
if err != nil {
|
||||
delay = rand.Intn(int(s.config.HttpServerTimeout*time.Second)-10) + 10
|
||||
delay = randomDelaySeconds(s.config.HttpServerTimeout)
|
||||
}
|
||||
|
||||
flusher, ok := w.(http.Flusher)
|
||||
@@ -46,3 +46,15 @@ func (s *Server) chunkedHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
flusher.Flush()
|
||||
}
|
||||
|
||||
// randomDelaySeconds returns a random delay in seconds within [10, timeout),
|
||||
// used when no explicit wait is provided. timeout is a time.Duration, so it is
|
||||
// converted to whole seconds; the upper bound is clamped to keep rand.Intn's
|
||||
// argument positive (it panics on a non-positive argument).
|
||||
func randomDelaySeconds(timeout time.Duration) int {
|
||||
maxDelay := int(timeout / time.Second)
|
||||
if maxDelay <= 11 {
|
||||
maxDelay = 12
|
||||
}
|
||||
return rand.Intn(maxDelay-10) + 10
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"regexp"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestChunkedHandler(t *testing.T) {
|
||||
@@ -33,3 +34,19 @@ func TestChunkedHandler(t *testing.T) {
|
||||
rr.Body.String(), expected)
|
||||
}
|
||||
}
|
||||
|
||||
// TestRandomDelaySeconds covers the default-delay branch taken by the bare
|
||||
// /chunked route (no {wait} value). This used to panic because the
|
||||
// duration-to-seconds math overflowed int64 and handed rand.Intn a negative
|
||||
// argument. Every timeout must yield a valid delay in [10, max] without panicking.
|
||||
func TestRandomDelaySeconds(t *testing.T) {
|
||||
timeouts := []time.Duration{30 * time.Second, 12 * time.Second, time.Second, 0, -1}
|
||||
for _, timeout := range timeouts {
|
||||
for range 100 {
|
||||
d := randomDelaySeconds(timeout)
|
||||
if d < 10 {
|
||||
t.Fatalf("timeout %s: delay %d below floor of 10", timeout, d)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user