mirror of
https://github.com/lahfir/agent-desktop.git
synced 2026-08-09 00:17:27 +00:00
fix: clamp auto-wait budget to prevent Instant overflow panic
An unbounded --timeout-ms flowed into Instant::now() + Duration::from_millis(ms) and panicked on overflow; with no catch_unwind on the CLI path this was a raw crash on trivial input (e.g. --timeout-ms 99999999999999999999). Clamp the budget to a 24h ceiling before deadline construction, with a regression test. Also add APP_UNRESPONSIVE to the error-code as_str/serde consistency test, which was silently non-exhaustive after the 16th variant landed.
This commit is contained in:
parent
f329d5840f
commit
39cf1f0ad3
3 changed files with 17 additions and 1 deletions
|
|
@ -316,6 +316,7 @@ mod tests {
|
|||
(ErrorCode::NotificationNotFound, "NOTIFICATION_NOT_FOUND"),
|
||||
(ErrorCode::SnapshotNotFound, "SNAPSHOT_NOT_FOUND"),
|
||||
(ErrorCode::PolicyDenied, "POLICY_DENIED"),
|
||||
(ErrorCode::AppUnresponsive, "APP_UNRESPONSIVE"),
|
||||
(ErrorCode::Internal, "INTERNAL"),
|
||||
];
|
||||
for (code, expected) in cases {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,11 @@ fn trace_resolve_error(context: &CommandContext, ref_id: &str, err: &AdapterErro
|
|||
|
||||
pub(crate) const POLL_INTERVAL: Duration = Duration::from_millis(100);
|
||||
pub(crate) const RESOLVE_ATTEMPT: Duration = Duration::from_millis(750);
|
||||
const MAX_BUDGET_MS: u64 = 24 * 60 * 60 * 1000;
|
||||
|
||||
pub(crate) fn budget_from_ms(ms: u64) -> Duration {
|
||||
Duration::from_millis(ms.min(MAX_BUDGET_MS))
|
||||
}
|
||||
|
||||
pub(crate) fn execute_with_auto_wait(
|
||||
adapter: &dyn PlatformAdapter,
|
||||
|
|
@ -62,7 +67,7 @@ pub(crate) fn execute_with_auto_wait(
|
|||
ref_id,
|
||||
context,
|
||||
request,
|
||||
Duration::from_millis(budget_ms),
|
||||
budget_from_ms(budget_ms),
|
||||
dispatch,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,16 @@ use crate::{
|
|||
use std::sync::atomic::{AtomicU32, Ordering};
|
||||
use std::time::Duration;
|
||||
|
||||
#[test]
|
||||
fn oversized_timeout_budget_is_clamped_and_never_overflows() {
|
||||
assert_eq!(budget_from_ms(100), Duration::from_millis(100));
|
||||
let clamped = budget_from_ms(u64::MAX);
|
||||
assert!(
|
||||
std::time::Instant::now().checked_add(clamped).is_some(),
|
||||
"deadline construction must not overflow for an oversized --timeout-ms"
|
||||
);
|
||||
}
|
||||
|
||||
struct RetryAdapter {
|
||||
resolve_calls: AtomicU32,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue