From<SystemTime> for HttpDate panics on times before 1970 or after year 9999
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
Research direction
Start at src/util/http_date.rs:93, then trace the listed date-header call sites in src/common/. Run the supplied reproducer with cargo run --release and inspect existing tests or documentation for the intended out-of-range behavior. Done means the scoped APIs no longer unexpectedly panic, or their valid range and panic behavior are explicitly documented and covered.
Written by the indexing model from the issue text.
Description
Converting a SystemTime earlier than the Unix epoch, or later than year 9999, panics. The date header APIs listed under Scope all funnel into that conversion, so a pre-1970 file mtime aborts the request handler in an optimized build.
Dependencies: headers = "=0.4.1" and http = "1".
Reproducer
use headers::{Expires, Header, HeaderMapExt, IfModifiedSince, LastModified};
use std::panic::catch_unwind;
use std::time::{Duration, UNIX_EPOCH};
fn main() {
let pre = UNIX_EPOCH - Duration::from_secs(1); // a file mtime from 1969
let far = UNIX_EPOCH + Duration::from_secs(1_000_000_000_000);
let mut m = http::HeaderMap::new();
m.append(
IfModifiedSince::name(),
"Mon, 07 Nov 1994 08:48:37 GMT".parse().unwrap(),
);
let ims: IfModifiedSince = m.typed_get().unwrap();
// Each call panics on its own. catch_unwind keeps the process alive so
// that one run shows all three.
let _ = catch_unwind(|| ims.is_modified(pre));
let _ = catch_unwind(|| LastModified::from(pre));
let _ = catch_unwind(|| Expires::from(far));
}
Observed
cargo run --release:
panicked at 'all times should be after the epoch: SystemTimeError(1s)'
panicked at 'all times should be after the epoch: SystemTimeError(1s)'
panicked at 'date must be before year 9999'
Expected
impl From<SystemTime> for LastModified and IfModifiedSince::is_modified(&self, last_modified: SystemTime) take an unrestricted std::time::SystemTime. Their signatures and docs give no valid range and declare no panic. Either the out-of-range input gets handled or the panic gets documented. LastModified::from(metadata.modified()?) is the canonical static-file-server call, and pre-1970 mtimes show up after tar/zip extraction, on restored backups, and on devices with an unset clock.
Root cause
src/util/http_date.rs:93, which calls httpdate's From<SystemTime> and its .expect("all times should be after the epoch").
Call sites that reach it: src/common/date.rs:37, src/common/last_modified.rs:41, src/common/expires.rs:41, src/common/if_modified_since.rs:41 and :47, src/common/if_unmodified_since.rs:42 and :48, src/common/retry_after.rs:46, src/common/if_range.rs:59.
Scope
Date, LastModified, Expires, IfModifiedSince, IfUnmodifiedSince, RetryAfter::date, IfRange::date, IfModifiedSince::is_modified, and IfUnmodifiedSince::precondition_passes all funnel into the same conversion. A SystemTime below the epoch or past year 9999 passed to any of them triggers the panic. The reproducer above exercises three of these. Debug and release builds both panic.
- Dominant language
- Rust
- Stars
- 200
- Forks
- 107
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from hyperium/headers
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
-
Difficulty 3/5 1-2 days Newbie friendliness 78/100
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
-
Link support Open
Difficulty 4/5 3-5 days Newbie friendliness 38/100
-
easy
Difficulty 2/5 1-3 hours Newbie friendliness 50/100
All issues in hyperium/headers
Similar issues
-
bug github_actions
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
registrystack/registry-stack#1393 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
longbridge/gpui-kit#3223 ·
-
bug engine
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
rocky-data/rocky#2181 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
oasisprotocol/oasis-sdk#2523 ·
-
[indexer] [QA] Add a focused test for the new NonRetryableError / assertSocketAlive() behavior. Openbot:ai-assisted component:indexer QA-roadmap status:untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
midnightntwrk/midnight-indexer#1557 ·