mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(relay): avoid overflow when rounding microsecond timeouts
pg_timeout_millis rounded `us` values with `(value + 500) / 1_000`, which overflows for the top 500 representable u128 magnitudes — a debug panic during config load, or in release a wrapped near-zero millisecond value that slips past the range check and hands the original gigantic string to every pool's after_connect. Round without the intermediate, and cover u128::MAX and the first overflowing value in the fallback test. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: Eli Foster <efoster@squareup.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
332ef5ff56
commit
d76acde5fe
@@ -312,7 +312,9 @@ fn parse_bind_addr(raw: &str) -> Result<SocketAddr, ConfigError> {
|
||||
fn pg_timeout_millis(magnitude: &str, unit: &str) -> Option<u128> {
|
||||
let value = magnitude.parse::<u128>().ok()?;
|
||||
match unit {
|
||||
"us" => Some((value + 500) / 1_000),
|
||||
// Round half up without the `value + 500` intermediate, which overflows
|
||||
// for the top 500 representable microsecond values.
|
||||
"us" => Some(value / 1_000 + u128::from(value % 1_000 >= 500)),
|
||||
"" | "ms" => Some(value),
|
||||
"s" => value.checked_mul(1_000),
|
||||
"min" => value.checked_mul(60_000),
|
||||
@@ -1378,6 +1380,11 @@ mod tests {
|
||||
// Wider than any integer type — must fall back, not overflow.
|
||||
"999999999999999999999999999999999999999999d",
|
||||
"99999999999999999999999999999999999999999999999999",
|
||||
// Parses as u128, so unlike the two above it reaches the unit
|
||||
// conversion — where rounding must not overflow on the way to the
|
||||
// range check.
|
||||
&format!("{}us", u128::MAX),
|
||||
&format!("{}us", u128::MAX - 499),
|
||||
] {
|
||||
assert_eq!(
|
||||
pg_timeout_or_default(Some(rejected), "30s"),
|
||||
|
||||
Reference in New Issue
Block a user