-
Notifications
You must be signed in to change notification settings - Fork 527
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(prost-types): Converting DateTime to Timestamp is fallible #1095
Conversation
@mumbleskates bilrost solved this problem differently. Do you agree with this solution as well? |
5a6f62f
to
a409c74
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems sensible to me. i'm tempted to recommend an error type for the TryFrom
that can distinguish between denormalized inputs and out-of-range inputs, but i don't really think it's actually worth making that distinction.
the fix i wrote in bilrost is enough to avoid the crash in year_to_seconds
, but it isn't actually correct yet for denormalized datetimes either (i haven't put it through a fuzzer yet, and i've found that at minimum it's possible to crash in month_to_seconds
with an out-of-range month).
prost-types/src/datetime.rs
Outdated
year: 2020, | ||
month: 2, | ||
day: 29, | ||
hour: 1, | ||
minute: 2, | ||
second: 3, | ||
nanos: 0, | ||
}), | ||
}) | ||
.unwrap(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can remove .unwrap()
on both sides of this assert
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah maybe we can't, since these have different error types. would it be sensible to use TimestampError
for the TryFrom
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is a bit lame that it can only return the one enum variant, but I agree that it is sensible. And it is an internal conversion, so we can change it if that makes sense at a later time.
i took a little time today to hook up a fuzzer to the timestamp <--> string machinery and i'm finding all kinds of problems. so far: |
|
The converstion from the private type DateTime to public type Timestamp is fallible when the DateTime is invalid. All code paths that used `DateTime::into::<Timestamp>()` first check whether the DateTime is valid and then do the conversion, therefore this problem was not visible. tokio-rs#893 points out that some conversions panic, however all these DateTime are invalid. Solution: Replace `impl From<DateTime> for Timestamp` with `TryFrom` and remove the manual `is_valid` checks before the conversion. I added the test cases from the issue and roundtrip test between DateTime and Timestamp.
a409c74
to
76970fd
Compare
I have been playing with the idea of improving compatibility with |
possibly. one of the original reasons for having it, though, was that indeed, perhaps it is more sensible to support from-string conversion only via pivoting through i can contribute that, with the 3 fixes i include or mention in #1096, fuzz testing in |
Ok, let's work towards a fuzz tested implementation. Could you review and approve this PR? Then I will look at yours. What I find interesting is that the protobuf comments on the Timestamp type specifically mention year 0001 through 9999. So you could argue that the chrono implementation is good enough. But I agree we should not settle for good enough and make it infallible. |
fuzz testing for some pretty reasonable bounds is available in |
The converstion from the private type DateTime to public type Timestamp is fallible when the DateTime is invalid. All code paths that used
DateTime::into::<Timestamp>()
first check whether the DateTime is valid and then do the conversion, therefore this problem was not visible. #893 points out that some conversions panic, however all these DateTime are invalid.Solution: Replace
impl From<DateTime> for Timestamp
withTryFrom
and remove the manualis_valid
checks before the conversion.I added the test cases from the issue and roundtrip test between DateTime and Timestamp.