Unverified Commit 0d80212a authored by Russell Cohen's avatar Russell Cohen Committed by GitHub
Browse files

Avoid overflow in exponential backoff computation (#3229)

## Motivation and Context
aws-sdk-rust#960

## Description
Use checked_pow to avoid overflow in backoff computation

## Testing
- unit test

## Checklist
<!--- If a checkbox below is not applicable, then please DELETE it
rather than leaving it unchecked -->
- [x] I have updated `CHANGELOG.next.toml` if I made changes to the
smithy-rs codegen or runtime crates
- [x] I have updated `CHANGELOG.next.toml` if I made changes to the AWS
SDK, generated SDK code, or SDK runtime crates

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent e3a57c88
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -54,3 +54,15 @@ message = "Make certain types for EMR Serverless optional. Previously, they defa
references = ["smithy-rs#3217"]
meta = { "breaking" = true, "tada" = false, "bug" = true }
author = "milesziemer"

[[smithy-rs]]
message = "Prevent multiplication overflow in backoff computation"
references = ["smithy-rs#3229", "aws-sdk-rust#960"]
meta = { "breaking" = false, "tada" = false, "bug" = true, target = "client" }
author = "rcoh"

[[aws-sdk-rust]]
message = "Prevent multiplication overflow in backoff computation"
references = ["smithy-rs#3229", "aws-sdk-rust#960"]
meta = { "breaking" = false, "tada" = false, "bug" = true }
author = "rcoh"
+13 −1
Original line number Diff line number Diff line
@@ -286,7 +286,10 @@ fn check_rate_limiter_for_delay(
}

fn calculate_exponential_backoff(base: f64, initial_backoff: f64, retry_attempts: u32) -> f64 {
    base * initial_backoff * 2_u32.pow(retry_attempts) as f64
    2_u32
        .checked_pow(retry_attempts)
        .map(|backoff| (backoff as f64) * base * initial_backoff)
        .unwrap_or(f64::MAX)
}

fn get_seconds_since_unix_epoch(runtime_components: &RuntimeComponents) -> f64 {
@@ -793,4 +796,13 @@ mod tests {
            assert_eq!(expected_backoff, actual_backoff);
        }
    }

    #[test]
    fn calculate_backoff_overflow() {
        // avoid overflow for a silly large amount of retry attempts
        assert_eq!(
            calculate_exponential_backoff(1_f64, 10_f64, 100000),
            f64::MAX
        );
    }
}