Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ceil with zero duration #323

Merged
merged 7 commits into from
Jul 28, 2024

Conversation

cardigan1008
Copy link
Contributor

Fix 14. Arithmetic overflow bug in #244

In #244 , ceil() is called with a duration of 0, which can lead to an arithmetic overflow. While returning 0 is one way to address this, another approach is to report an error to the user.

I'm not very familiar with operations involving time, so apologies for any misunderstandings.

In issue nyx-space#244, ceil() is called with 0 duration. It seems return 0
is an alternative way to fix this. But it seems that we can also
report user with error?
@cardigan1008 cardigan1008 marked this pull request as draft July 28, 2024 05:48
Copy link

codecov bot commented Jul 28, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 83.75%. Comparing base (0cde737) to head (c58ca0b).
Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #323   +/-   ##
=======================================
  Coverage   83.75%   83.75%           
=======================================
  Files          22       22           
  Lines        3688     3688           
=======================================
  Hits         3089     3089           
  Misses        599      599           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ChristopherRabotin
Copy link
Member

Thanks! Can you add a regression test?

@cardigan1008
Copy link
Contributor Author

Thanks! Can you add a regression test?

Sure! But I'm wondering if this change is logically correct. In this example, with this change, the final output is 1900-01-01T00:00:00 UTC:

fn main() {
    let _local0 =
        if let Ok(x) = hifitime::prelude::Epoch::maybe_from_gregorian_utc(1792, 1, 1, 0, 0, 0, 0) {
            x
        } else {
            use std::process;
            process::exit(0);
        };
    let _local5 = hifitime::prelude::Epoch::duration_in_year(&(_local0));
    let _ = hifitime::prelude::Epoch::to_utc_seconds(&(_local0));
    let _ = hifitime::prelude::Duration::decompose(&(_local5));
    let a = hifitime::prelude::Epoch::ceil(&(_local0), _local5);
    println!("{:?}", a);
}

@cardigan1008 cardigan1008 marked this pull request as ready for review July 28, 2024 10:27
Copy link
Member

@ChristopherRabotin ChristopherRabotin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution. Could you implement a few changes to the test and then I think it's ready to merge.

tests/duration.rs Outdated Show resolved Hide resolved
tests/duration.rs Outdated Show resolved Hide resolved
@cardigan1008
Copy link
Contributor Author

Thanks for your contribution. Could you implement a few changes to the test and then I think it's ready to merge.

Thank you for your guidance! I have implemented the changes you suggested. As I'm not very familiar with adding regression tests in Rust, your advice was extremely helpful.

@ChristopherRabotin
Copy link
Member

My apologies, I didn't take enough time to look at the test. I think that you're making the test too complicated for what should be tested because the Epoch::ceil directly calls Duration::ceil, so only that last function needs testing. Hence, I recommend the following:

#[test]
fn regression_test_gh_244() {
    let zero = Duration::ZERO;
    // Test that the ceil of a zero duration is still zero.
    assert_eq!(zero.ceil(zero), zero);
    let non_zero = Duration::from_parts(1, 23456);
    // Test that the ceil of a non-zero duration by zero is still that original duration.
    assert_eq!(non_zero.ceil(zero), non_zero);
    // Test that the ceil of a zero duration by a non-zero is still zero.
    assert_eq!(zero.ceil(non_zero), zero);
}

@cardigan1008
Copy link
Contributor Author

My apologies, I didn't take enough time to look at the test. I think that you're making the test too complicated for what should be tested because the Epoch::ceil directly calls Duration::ceil, so only that last function needs testing. Hence, I recommend the following:

#[test]
fn regression_test_gh_244() {
    let zero = Duration::ZERO;
    // Test that the ceil of a zero duration is still zero.
    assert_eq!(zero.ceil(zero), zero);
    let non_zero = Duration::from_parts(1, 23456);
    // Test that the ceil of a non-zero duration by zero is still that original duration.
    assert_eq!(non_zero.ceil(zero), non_zero);
    // Test that the ceil of a zero duration by a non-zero is still zero.
    assert_eq!(zero.ceil(non_zero), zero);
}

I just found the second assertion failed. With this change, the ceil of a non-zero duration by zero is still zero. So here comes the logical issue. What do you think of this?

@ChristopherRabotin
Copy link
Member

the ceil of a non-zero duration by zero is still zero
That actually looks like the correct behavior, and that test recommendation is wrong! The whole point of the change is to avoid a modulo operation by zero, so indeed, the ceil of a non-zero duration by zero should be zero.

Could you make that test change and then we're good!

@cardigan1008
Copy link
Contributor Author

Could you make that test change and then we're good!

Sure, thanks for your prompt response! I have just made the changes to the test.

I learned a lot from our discussion. Initially, I simply copied the code snippet from the issue without considering the coverage and simplicity of the regression test case. Your guidance was very helpful. Thank you!

@ChristopherRabotin ChristopherRabotin merged commit 754a86e into nyx-space:master Jul 28, 2024
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants