diff --git a/Cargo.toml b/Cargo.toml index 7365844a7d..fbe1d13c6a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ exclude = ["tests", "dlmalloc-rs"] [workspace.lints.clippy] borrow_as_ptr = "warn" # TODO review occurrences cast_lossless = "warn" # TODO review occurrences -cast_ptr_alignment = "warn" # TODO review occurrences +cast_ptr_alignment = "allow" # TODO review occurrences missing_safety_doc = "allow" # TODO review occurrences mut_from_ref = "warn" # TODO review occurrences precedence = "deny" diff --git a/src/header/time/constants.rs b/src/header/time/constants.rs index d26988955f..2b3d3ba645 100644 --- a/src/header/time/constants.rs +++ b/src/header/time/constants.rs @@ -10,7 +10,7 @@ pub mod sys; pub use self::sys::*; -pub(crate) const UTC: *const c_char = b"UTC\0".as_ptr().cast(); +pub(crate) const UTC: *const c_char = c"UTC".as_ptr().cast(); pub(crate) const DAY_NAMES: [&str; 7] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; pub(crate) const MON_NAMES: [&str; 12] = [ diff --git a/src/header/time/mod.rs b/src/header/time/mod.rs index fea11a453f..59ce7d1423 100644 --- a/src/header/time/mod.rs +++ b/src/header/time/mod.rs @@ -138,7 +138,7 @@ pub struct itimerspec { #[deprecated] #[unsafe(no_mangle)] pub unsafe extern "C" fn asctime(timeptr: *const tm) -> *mut c_char { - unsafe { asctime_r(timeptr, &raw mut ASCTIME as *mut _) } + unsafe { asctime_r(timeptr, (&raw mut ASCTIME).cast()) } } /// See . @@ -187,17 +187,16 @@ pub unsafe extern "C" fn asctime_r(tm: *const tm, buf: *mut c_char) -> *mut c_ch * message for all fields. */ const OUT_OF_RANGE_MESSAGE: &str = "tm member out of range"; - assert!(0 <= tm_sec && tm_sec <= 99, "{}", OUT_OF_RANGE_MESSAGE); - assert!(0 <= tm_min && tm_min <= 99, "{}", OUT_OF_RANGE_MESSAGE); - assert!(0 <= tm_hour && tm_hour <= 99, "{}", OUT_OF_RANGE_MESSAGE); - assert!(-99 <= tm_mday && tm_mday <= 999, "{}", OUT_OF_RANGE_MESSAGE); - assert!(0 <= tm_mon && tm_mon <= 11, "{}", OUT_OF_RANGE_MESSAGE); + assert!((0..=99).contains(&tm_sec), "{OUT_OF_RANGE_MESSAGE}"); + assert!((0..=99).contains(&tm_min), "{OUT_OF_RANGE_MESSAGE}"); + assert!((0..=99).contains(&tm_hour), "{OUT_OF_RANGE_MESSAGE}"); + assert!((-99..=999).contains(&tm_mday), "{OUT_OF_RANGE_MESSAGE}"); + assert!((0..=11).contains(&tm_mon), "{OUT_OF_RANGE_MESSAGE}"); assert!( - -999 - 1900 <= tm_year && tm_year <= 9999 - 1900, - "{}", - OUT_OF_RANGE_MESSAGE + (-999 - 1900..=9999 - 1900).contains(&tm_year), + "{OUT_OF_RANGE_MESSAGE}" ); - assert!(0 <= tm_wday && tm_wday <= 6, "{}", OUT_OF_RANGE_MESSAGE); + assert!((0..=6).contains(&tm_wday), "{OUT_OF_RANGE_MESSAGE}"); // At this point, we can safely use the values as given. let write_result = core::fmt::write( @@ -236,10 +235,7 @@ pub extern "C" fn clock() -> clock_t { let clocks = ts.tv_sec * CLOCKS_PER_SEC as i64 + (ts.tv_nsec / (1_000_000_000 / CLOCKS_PER_SEC)) as i64; - match clock_t::try_from(clocks) { - Ok(ok) => ok, - Err(_err) => -1, - } + clock_t::try_from(clocks).unwrap_or(-1) } /// See . @@ -304,8 +300,8 @@ pub unsafe extern "C" fn ctime(clock: *const time_t) -> *mut c_char { pub unsafe extern "C" fn ctime_r(clock: *const time_t, buf: *mut c_char) -> *mut c_char { // Using MaybeUninit seems to cause a panic during the build process let mut tm1 = blank_tm(); - unsafe { localtime_r(clock, &mut tm1) }; - unsafe { asctime_r(&tm1, buf) } + unsafe { localtime_r(clock, &raw mut tm1) }; + unsafe { asctime_r(&raw const tm1, buf) } } /// See . @@ -422,7 +418,7 @@ pub unsafe extern "C" fn strftime( ) -> size_t { let ret = unsafe { strftime::strftime( - &mut platform::StringWriter(s as *mut u8, maxsize), + &mut platform::StringWriter(s.cast::(), maxsize), format, timeptr, ) @@ -441,7 +437,7 @@ pub unsafe extern "C" fn strftime( #[unsafe(no_mangle)] pub unsafe extern "C" fn time(tloc: *mut time_t) -> time_t { let mut ts = timespec::default(); - if let Ok(_) = Sys::clock_gettime(CLOCK_REALTIME, Out::from_mut(&mut ts)) {}; // TODO what to do if Err? + if Sys::clock_gettime(CLOCK_REALTIME, Out::from_mut(&mut ts)).is_ok() {}; // TODO what to do if Err? if !tloc.is_null() { unsafe { *tloc = ts.tv_sec } }; @@ -462,7 +458,7 @@ pub unsafe extern "C" fn timegm(tm: *mut tm) -> time_t { (*tm).tm_yday = dt.ordinal0() as _; // day of year starting at 0 (*tm).tm_isdst = 0; // UTC does not use DST (*tm).tm_gmtoff = 0; // UTC offset is zero - (*tm).tm_zone = UTC_STR.as_ptr() as *const c_char; + (*tm).tm_zone = UTC_STR.as_ptr().cast::(); } dt.timestamp() @@ -502,7 +498,7 @@ pub unsafe extern "C" fn timer_create( return Err(Errno(EFAULT)).or_minus_one_errno(); } let (evp, timerid) = unsafe { (&*evp, Out::nonnull(timerid)) }; - Sys::timer_create(clock_id, &evp, timerid) + Sys::timer_create(clock_id, evp, timerid) .map(|()| 0) .or_minus_one_errno() } @@ -645,10 +641,10 @@ fn get_system_time_zone<'a>() -> Option<&'a str> { let path = unsafe { CStr::from_ptr(buffer.as_mut_ptr().cast()) }; - if let Ok(tz_name) = path.to_str() { - if let Some(stripped) = tz_name.strip_prefix(prefix) { - return Some(stripped); - } + if let Ok(tz_name) = path.to_str() + && let Some(stripped) = tz_name.strip_prefix(prefix) + { + return Some(stripped); } None @@ -656,11 +652,11 @@ fn get_system_time_zone<'a>() -> Option<&'a str> { fn get_current_time_zone<'a>() -> &'a str { // Check the `TZ` environment variable - let tz_env = unsafe { getenv(c"TZ".as_ptr() as _) }; - if !tz_env.is_null() { - if let Ok(tz) = unsafe { CStr::from_ptr(tz_env) }.to_str() { - return tz; - } + let tz_env = unsafe { getenv(c"TZ".as_ptr().cast()) }; + if !tz_env.is_null() + && let Ok(tz) = unsafe { CStr::from_ptr(tz_env) }.to_str() + { + return tz; } // Fallback to the system's default time zone @@ -680,7 +676,7 @@ fn time_zone() -> Tz { #[inline(always)] fn now() -> NaiveDateTime { let mut now = timespec::default(); - if let Ok(_) = Sys::clock_gettime(CLOCK_REALTIME, Out::from_mut(&mut now)) {}; // TODO what to do if Err? + if Sys::clock_gettime(CLOCK_REALTIME, Out::from_mut(&mut now)).is_ok() {}; // TODO what to do if Err? NaiveDateTime::from_timestamp(now.tv_sec, now.tv_nsec as _) } @@ -702,7 +698,7 @@ fn get_localtime(clock: time_t, t: *mut tm) -> (Option>, Option) -> tm { let tz = local_time.timezone().name(); - let tz = tz.strip_prefix("Etc/").or(Some(tz)).unwrap(); + let tz = tz.strip_prefix("Etc/").unwrap_or(tz); let mut t = blank_tm(); // Populate the `tm` structure @@ -792,9 +788,9 @@ const fn blank_tm() -> tm { pub(crate) fn timespec_realtime_to_monotonic(abstime: timespec) -> Result { let mut realtime = timespec::default(); - unsafe { clock_gettime(CLOCK_REALTIME, &mut realtime) }; + unsafe { clock_gettime(CLOCK_REALTIME, &raw mut realtime) }; let mut monotonic = timespec::default(); - unsafe { clock_gettime(CLOCK_MONOTONIC, &mut monotonic) }; + unsafe { clock_gettime(CLOCK_MONOTONIC, &raw mut monotonic) }; let Some(delta) = timespec::subtract(abstime, realtime) else { return Err(Errno(ETIMEDOUT)); }; diff --git a/src/header/time/strftime.rs b/src/header/time/strftime.rs index 944f4cb12b..49ab8e48fc 100644 --- a/src/header/time/strftime.rs +++ b/src/header/time/strftime.rs @@ -35,10 +35,7 @@ unsafe fn langinfo_to_str(item: nl_item) -> &'static str { if ptr.is_null() { return ""; } - match unsafe { CStr::from_ptr(ptr) }.to_str() { - Ok(s) => s, - Err(_) => "", - } + unsafe { CStr::from_ptr(ptr) }.to_str().unwrap_or_default() } /// See . @@ -116,26 +113,26 @@ pub unsafe fn strftime(w: &mut W, format: *const c_char, t: *const // Abbreviated weekday name: %a b'a' => { // `ABDAY_1 + tm_wday` is the correct langinfo ID for abbreviated weekdays - let s = unsafe { langinfo_to_str(ABDAY_1 + (*t).tm_wday as i32) }; + let s = unsafe { langinfo_to_str(ABDAY_1 + (*t).tm_wday) }; w!(s); } // Full weekday name: %A b'A' => { // `DAY_1 + tm_wday` is the correct langinfo ID for full weekdays - let s = unsafe { langinfo_to_str(DAY_1 + (*t).tm_wday as i32) }; + let s = unsafe { langinfo_to_str(DAY_1 + (*t).tm_wday) }; w!(s); } // Abbreviated month name: %b or %h b'b' | b'h' => { - let s = unsafe { langinfo_to_str(ABMON_1 + (*t).tm_mon as i32) }; + let s = unsafe { langinfo_to_str(ABMON_1 + (*t).tm_mon) }; w!(s); } // Full month name: %B b'B' => { - let s = unsafe { langinfo_to_str(MON_1 + (*t).tm_mon as i32) }; + let s = unsafe { langinfo_to_str(MON_1 + (*t).tm_mon) }; w!(s); } @@ -204,7 +201,7 @@ pub unsafe fn strftime(w: &mut W, format: *const c_char, t: *const b'R' => w!(recurse "%H:%M"), // Seconds since the Epoch: %s => calls mktime() to convert tm to time_t - b's' => w!("{}", unsafe { super::mktime(t as *mut tm) }), + b's' => w!("{}", unsafe { super::mktime(t.cast_mut()) }), // Seconds (00-60): %S (unchanged) b'S' => w!("{:02}", unsafe { (*t).tm_sec }), @@ -285,7 +282,7 @@ pub unsafe fn strftime(w: &mut W, format: *const c_char, t: *const /// ## Source /// https://en.wikipedia.org/wiki/ISO_week_date fn weeks_per_year(year: c_int) -> c_int { - let year = year as f64; + let year = f64::from(year); let p_y = (year + (year / 4.) - (year / 100.) + (year / 400.)) as c_int % 7; if p_y == 4 { 53 } else { 52 } } diff --git a/src/header/time/strptime.rs b/src/header/time/strptime.rs index f6828d799c..f49c5b54b6 100644 --- a/src/header/time/strptime.rs +++ b/src/header/time/strptime.rs @@ -48,13 +48,13 @@ pub unsafe extern "C" fn strptime( tm: *mut tm, ) -> *mut c_char { // Validate inputs - let buf_ptr = if let Some(ptr) = NonNull::new(buf as *const c_void as *mut c_void) { + let buf_ptr = if let Some(ptr) = NonNull::new(buf.cast::().cast_mut()) { ptr } else { return ptr::null_mut(); }; // - let fmt_ptr = if let Some(ptr) = NonNull::new(format as *const c_void as *mut c_void) { + let fmt_ptr = if let Some(ptr) = NonNull::new(format.cast::().cast_mut()) { ptr } else { return ptr::null_mut(); @@ -230,7 +230,7 @@ pub unsafe extern "C" fn strptime( Some(v) => v, None => return ptr::null_mut(), }; - if val < 1 || val > 12 { + if !(1..=12).contains(&val) { return ptr::null_mut(); } unsafe { @@ -364,7 +364,7 @@ pub unsafe extern "C" fn strptime( Some(v) => v, None => return ptr::null_mut(), }; - if val < 1 || val > 366 { + if !(1..=366).contains(&val) { return ptr::null_mut(); } // store in tm_yday @@ -432,7 +432,7 @@ pub unsafe extern "C" fn strptime( // If we got here, parsing was successful. Return pointer to the // next unparsed character in `buf`. let ret_ptr = unsafe { buf.add(index_in_input) }; - ret_ptr as *mut c_char + ret_ptr.cast_mut() } // Helper / Parsing Logic @@ -444,16 +444,18 @@ pub unsafe extern "C" fn strptime( /// (e.g., `%Y` can have more than 4 digits, but also might parse "2023" or "12345"). fn parse_int(input: &str, width: usize, allow_variable: bool) -> Option<(i32, usize)> { let mut val = 0i32; - let mut chars = input.chars(); + let chars = input.chars(); let mut count = 0; - while let Some(c) = chars.next() { + for c in chars { if !c.is_ascii_digit() { break; } // Check for integer overflow - val = val.checked_mul(10)?.checked_add((c as u8 - b'0') as i32)?; + val = val + .checked_mul(10)? + .checked_add(i32::from(c as u8 - b'0'))?; count += 1; if count == width && !allow_variable { @@ -484,13 +486,14 @@ fn parse_am_pm(s: &str) -> Option<(bool, usize)> { /// Parse a weekday name from `s`. /// - if `abbrev == true`, match short forms: "Mont".."Sun" /// - otherwise, match "Monday".."Sunday" +/// /// Return (weekday_index, length_consumed). fn parse_weekday(s: &str, abbrev: bool) -> Option<(usize, usize)> { let list = if abbrev { &SHORT_DAYS } else { &LONG_DAYS }; for (i, name) in list.iter().enumerate() { if s.len() >= name.len() && s.get(0..name.len()) - .map_or(false, |sub| sub.eq_ignore_ascii_case(name)) + .is_some_and(|sub| sub.eq_ignore_ascii_case(name)) { return Some((i, name.len())); } @@ -501,13 +504,14 @@ fn parse_weekday(s: &str, abbrev: bool) -> Option<(usize, usize)> { /// Parse a month name from `s`. /// - If `abbrev == true`, match short forms: "Jan".."Dec" /// - Otherwise, match "January".."December" +/// /// Return (month_index, length_consumed). fn parse_month(s: &str, abbrev: bool) -> Option<(usize, usize)> { let list = if abbrev { &SHORT_MONTHS } else { &LONG_MONTHS }; for (i, name) in list.iter().enumerate() { if s.len() >= name.len() && s.get(0..name.len()) - .map_or(false, |sub| sub.eq_ignore_ascii_case(name)) + .is_some_and(|sub| sub.eq_ignore_ascii_case(name)) { return Some((i, name.len())); } @@ -536,8 +540,8 @@ unsafe fn apply_subformat(input: &str, subfmt: &str, tm: *mut tm) -> Option(), + tmpfmt.as_ptr().cast::(), tm, ) };