Subject
chrono 0.4.44 is a date and time library for Rust. It implements the proleptic Gregorian calendar with timezone-aware (DateTime<Tz>) and timezone-naive (NaiveDate, NaiveTime, NaiveDateTime) types, a signed duration type (TimeDelta), strftime-style formatting and parsing, and local timezone resolution from the host OS. The library supports no_std (with alloc) and targets Unix, Windows, and wasm32.
Methodology
The published crate contents were compared against the upstream Git repository at the commit recorded in .cargo_vcs_info.json using diff -rq. All 41 source files (~34,000 LOC) were surveyed with grep for unsafe, FFI, network, filesystem, process execution, environment variables, and concurrency patterns. Files containing unsafe blocks, the arithmetic/overflow code, the format/parse subsystem, and the local timezone resolution path were read in full. The VCS checkout was inspected for CI configuration, fuzz targets, and integration tests. Tool versions: openvet 0.6.0, diff (macOS), grep (macOS).
Results
The diff between published contents and the VCS tree shows only the expected differences: Cargo.toml (cargo normalisation), Cargo.toml.orig, Cargo.lock, .cargo_vcs_info.json, and VCS-only files (.github/, bench/, fuzz/, ci/). No source files differ, and the package contains no binary artefacts, justifying has-binaries.
There is no build.rs and the library is not a proc macro, so has-build-exec and has-install-exec are false.
The codebase contains 11 unsafe sites concentrated in four areas: NaiveDate::from_yof (one NonZeroI32::new_unchecked guarded by debug_assert! on the ordinal and flags invariants), the Windows timezone FFI path (MaybeUninit::assume_init after Win32 return-code checks, and mem::zeroed for C structs where zero is a valid bit pattern), CStr::from_bytes_with_nul_unchecked after a confirmed null-byte scan, and str::from_utf8_unchecked over a byte slice that the parser has validated to be ASCII. Every site carries a SAFETY comment or an immediately preceding invariant check. uses-unsafe is true; unsafe-documented, unsafe-safe, and unsafe-minimal hold.
Date/time arithmetic uniformly uses checked_add, checked_sub, and checked_mul at every boundary, propagating None on overflow. The Add/Sub/Mul operator impls call the checked variants and panic on overflow with a descriptive message, which matches the documented contract. TimeDelta::checked_mul widens to i128 before comparison against i64 bounds. No unguarded arithmetic was found, justifying algorithm-impl-safe and algorithm-impl-correct.
The strftime-inspired format/parse subsystem reads &str input using bounds-checked slice indexing. Numeric scanning (scan::number) uses checked_mul/checked_add and returns OUT_OF_RANGE on overflow. Parsing returns Result; there are no panics on malformed input in the parse path. RFC 2822 and RFC 3339 input formats are parsed against documented grammar rules with out-of-range values rejected. Justifies impl-parser, parser-impl-safe, parser-impl-tested (fuzz targets fuzz_format and fuzz_reader exist in the VCS fuzz/ directory), and parser-impl-correct. The unsafe blocks have not been run under MIRI or ThreadSanitizer; unsafe-tested is false accordingly.
The historical localtime_r thread-safety issue (RUSTSEC-2020-0159) has been resolved since version 4.20. This version reads /etc/localtime and the system timezone database directly via pure Rust parsing of TZif files (forked from the tz-rs crate). The TZ environment variable is read through Rust's standard library, which holds its own lock. The per-thread thread_local! { static TZ_INFO: RefCell<Option<Cache>> } eliminates cross-thread sharing of the cached timezone, justifying uses-concurrency, concurrency-safe, and concurrency-documented.
Filesystem access is limited to reading well-known OS timezone data paths (/etc/localtime, /usr/share/zoneinfo/<name>, Android/OpenHarmony tzdata archives). The timezone name used to construct a path comes from iana-time-zone::get_timezone() or the TZ environment variable; in neither case is a user-supplied arbitrary string spliced without bounds. Justifies uses-filesystem and filesystem-safe.
Environment access is limited to the TZ variable on Unix, read via std::env::var. A missing or malformed TZ value falls back through iana-time-zone and then to UTC; it does not panic. Justifies uses-environment and environment-safe.
The codebase was reviewed for network calls, process execution, JIT, and cryptographic operations; none were found. uses-network, uses-exec, uses-jit, uses-interpreter, uses-crypto, impl-crypto, impl-protocol, impl-interpreter, impl-jit, and impl-concurrency are all false. No property-based testing framework was found; has-property-tests is false.
The library implements calendar and time-delta algorithms (Gregorian leap-year calculation, ordinal-day lookup tables, week-number computation) justifying impl-algorithm. These algorithms are correct by construction via the packed YearFlags/Mdf table approach and are tested exhaustively in the inline test suite. algorithm-impl-bounds holds: all operations are bounded by the NaiveDate::MIN/MAX range (±262,000 years) and return None on overflow. The library does not implement a standalone data structure; impl-datastructure is false.
The crate ships 332 #[test] functions inlined across the source modules plus three integration test files (tests/dateutils.rs, tests/wasm.rs, tests/win_bindings.rs) and two fuzz targets (fuzz_format, fuzz_reader) in the VCS tree. Justifies has-unit-tests, has-integration-tests, and has-fuzz-tests.
The code contains no obfuscated payloads, base64 blobs, telemetry, or network sinks, justifying is-benign.
The unsafe impl<Tz: TimeZone> Send for Date<Tz> where <Tz as TimeZone>::Offset: Send in date.rs is the correct structural bound; Date<Tz> holds only a NaiveDate and a Tz::Offset, so the bound is sound. algorithm-impl-tested is justified by the extensive inline test suite and fuzz targets.
Conclusion
The audit found no findings. The 11 unsafe sites are all narrow and correctly bounded, with safety invariants documented inline. Arithmetic overflow is handled systematically via checked_* methods throughout. The historical localtime_r thread-safety issue is resolved. The format/parse subsystem returns errors on all out-of-range inputs. The surface area includes filesystem reads (timezone data) and environment variable access (TZ), both limited to expected OS-level data sources.