Skip to content
This repository was archived by the owner on Apr 13, 2021. It is now read-only.

Use std::time API instead of u64s for timestamp and expiry time #8

Merged
merged 4 commits into from
Nov 27, 2018

Conversation

sgeisler
Copy link
Contributor

@sgeisler sgeisler commented Nov 3, 2018

Using dedicated time structs should make the API less error prone and easier to use right. Since we don't want to pull in unnecessary Dependencies I didn't use chrono.

But std::time unfortunately misses a way to do time calculations (like SystemTime + Duration) in a non-panicking way (see rust-lang/rust#55527). So I had to make some wild guesses about our potential target platforms and their internal representations of time which can't be statically asserted yet unfortunately. That means we end up with some really ugly heuristics that try to keep people from using the library in ways that would expose them to DoS attacks by overflowing the time calculations.

// TODO: fix before 2037 (see rust PR #55527)
/// Defines the maximum UNIX timestamp that can be represented as `SystemTime`. This is checked by
/// one of the unit tests, please run them.
const SYSTEM_TIME_MAX_UNIX_TIMESTAMP: u64 = std::i32::MAX as u64;

/// Allow the expiry time to be up to one year. Since this reduces the range of possible timestamps
/// it should be rather low as long as we still have to support 32bit time representations
const MAX_EXPIRY_TIME: u64 = 60 * 60 * 24 * 356;

/// This function is used as a static assert for the size of `SystemTime`. If the crate fails to
/// compile due to it this indicates that your system uses unexpected bounds for `SystemTime`. You
/// can remove this functions and run the test `test_system_time_bounds_assumptions`. In any case,
/// please open an issue. If all tests pass you should be able to use this library safely by just
/// removing this function till we patch it accordingly.
fn __system_time_size_check() {
	/// Use 2 * sizeof(u64) as expected size since the expected underlying implementation is storing
	/// a `Duration` since `SystemTime::UNIX_EPOCH`.
	unsafe { std::mem::transmute::<SystemTime, [u8; 16]>(UNIX_EPOCH); }
}

I nonetheless think that it's the right thing to improve the API in that way. With some luck my rust-lang PR will end up in the debian stable rust release in the next decade 😭 but it's ok as long as that will happen before 2037 😄

Since @TheBlueMatt is the only user of this library I know of: what do you think about that change. I think that was the last short-term API-breaking change, so I'd really like to publish a 0.1.0 soon.

@sgeisler sgeisler requested a review from TheBlueMatt November 3, 2018 00:39
@sgeisler sgeisler self-assigned this Nov 3, 2018
@sgeisler sgeisler added enhancement New feature or request design decision API design discussion labels Nov 3, 2018
@sgeisler sgeisler added this to the v0.1.0 milestone Nov 3, 2018
@sgeisler sgeisler mentioned this pull request Nov 3, 2018
@sgeisler sgeisler force-pushed the master branch 10 times, most recently from a70f7c9 to 47ade71 Compare November 3, 2018 09:18
Copy link
Member

@TheBlueMatt TheBlueMatt left a comment

Choose a reason for hiding this comment

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

At a high level I think its nice to use the std::time API just for convenience though I don't think it really helps safety given that we have to restrict the timestamp + expiry delta to make sure they dont overflow anyway (and much better to do it during deserialize than hope the user remembers to avoid the unwrap() either way).

@sgeisler
Copy link
Contributor Author

I don't think it really helps safety given that we have to restrict the timestamp + expiry delta to make sure they dont overflow anyway

I'd argue that it removes possible logic errors where you accidentally pass a completely unrelated integer into a function expecting an expiry time etc. It makes you think twice if the integer you have is actually a duration (and if so with which unit) and should be converted accordingly.

@sgeisler
Copy link
Contributor Author

I guess I'll just merge now, I think I addressed all of your comments. And btw thx for making me implement fuzz tests (not PR ready yet), they already found a round trip/serialization bug in this PR 😃 (fixed by now)

@sgeisler sgeisler merged commit 84cfec7 into master Nov 27, 2018
@sgeisler sgeisler deleted the std-time branch November 27, 2018 23:44
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
design decision API design discussion enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants