Repository: tokio-rs/prost (language: rust)

Issue:
Malformed `Timestamp` leads to Debug Assert Crash  'attempt to negate with overflow' in `impl TryFrom<Timestamp> for std::time::SystemTime`
Hi. Thank you for a very useful library.

I believe this is a bug: as of 25ab1cc77cba01568d7a72b01f7725f13b8cc095, if you instantiate the proptest `check_timestamp_roundtrip_via_system_time` in `prost-types/lib.rs` with out of range-values, you can get `SystemTime::try_from(timestamp.clone())` to crash with arithemetic overflow checks. Even if the input is invalid, I believe TryFrom should return an error value instead of crashing on the spot. Especially b/c this Timestamp struct is public including the internal fields.


Replication (tested on x86 64 bit ubuntu 20.04 and M1 Mac ): Paste the following into `prost-types/lib.rs` at[ this location](https://github.com/tokio-rs/prost/blob/25ab1cc77cba01568d7a72b01f7725f13b8cc095/prost-types/src/lib.rs#L404)
```rust
    #[test]
    fn check_timestamp_roundtrip_via_system_time_oveflow() {
        use std::time::SystemTime;
        let seconds : i64 = -9223372036854775808;
        let nanos : i32 = 999997508;

        let mut timestamp = Timestamp { seconds, nanos };
        timestamp.normalize();
        if let Ok(system_time) = SystemTime::try_from(timestamp.clone()) {
            assert_eq!(Timestamp::from(system_time), timestamp);
        }
    }
```
`cargo test --package prost-types --lib -- tests::check_timestamp_roundtrip_via_system_time_oveflow --exact`  yields
```
thread 'tests::check_timestamp_roundtrip_via_system_time_oveflow' panicked at 'attempt to negate with overflow', prost-types/src/lib.rs:372:56
```


Discussion / hints:
Thanks for opening this! I will take a deeper look soon but https://github.com/tokio-rs/prost/commit/25ab1cc77cba01568d7a72b01f7725f13b8cc095 doesn't change any actual code just upgrades github CI so I don't see how that one affects it. That said, there was a recent change to timestamp that might be the culprit https://github.com/tokio-rs/prost/commit/1674ef925ef4ad0daa09b8144742ecd1a545d72f.

cc @danburkert 

Fix patch:
diff --git a/prost-types/src/lib.rs b/prost-types/src/lib.rs
index 086cdbb51..223bd1aa9 100644
--- a/prost-types/src/lib.rs
+++ b/prost-types/src/lib.rs
@@ -368,8 +368,13 @@ impl TryFrom<Timestamp> for std::time::SystemTime {
         let system_time = if timestamp.seconds >= 0 {
             std::time::UNIX_EPOCH.checked_add(time::Duration::from_secs(timestamp.seconds as u64))
         } else {
-            std::time::UNIX_EPOCH
-                .checked_sub(time::Duration::from_secs((-timestamp.seconds) as u64))
+            std::time::UNIX_EPOCH.checked_sub(time::Duration::from_secs(
+                timestamp
+                    .seconds
+                    .checked_neg()
+                    .ok_or(TimestampError::OutOfSystemRange(timestamp.clone()))?
+                    as u64,
+            ))
         };
 
         let system_time = system_time.and_then(|system_time| {


Test patch: