melib/datetime: isolate unsafe blocks

Isolate unsafe blocks where possible to make code review easier
lazy_fetch
Manos Pitsidianakis 2021-01-05 21:36:22 +02:00
parent bf9143d8e4
commit fe200a3218
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
1 changed files with 97 additions and 100 deletions

View File

@ -273,9 +273,7 @@ where
let s = CString::new(s)?; let s = CString::new(s)?;
let mut new_tm: libc::tm = unsafe { std::mem::zeroed() }; let mut new_tm: libc::tm = unsafe { std::mem::zeroed() };
for fmt in &[RFC822_FMT_WITH_TIME, RFC822_FMT] { for fmt in &[RFC822_FMT_WITH_TIME, RFC822_FMT] {
unsafe { let fmt = unsafe { CStr::from_bytes_with_nul_unchecked(fmt.as_bytes()) };
let fmt = CStr::from_bytes_with_nul_unchecked(fmt.as_bytes());
let ret = { let ret = {
let _with_locale = Locale::new( let _with_locale = Locale::new(
libc::LC_TIME, libc::LC_TIME,
@ -284,18 +282,19 @@ where
) )
.chain_err_summary(|| "Could not set locale for datetime conversion") .chain_err_summary(|| "Could not set locale for datetime conversion")
.chain_err_kind(crate::error::ErrorKind::External)?; .chain_err_kind(crate::error::ErrorKind::External)?;
strptime(s.as_ptr(), fmt.as_ptr(), &mut new_tm as *mut _) unsafe { strptime(s.as_ptr(), fmt.as_ptr(), &mut new_tm as *mut _) }
}; };
if ret.is_null() { if ret.is_null() {
continue; continue;
} }
let rest = CStr::from_ptr(ret); let rest = unsafe { CStr::from_ptr(ret) };
let tm_gmtoff = if rest.to_bytes().len() > 4 let tm_gmtoff = if rest.to_bytes().len() > 4
&& rest.to_bytes().is_ascii() && rest.to_bytes().is_ascii()
&& rest.to_bytes()[1..5].iter().all(u8::is_ascii_digit) && rest.to_bytes()[1..5].iter().all(u8::is_ascii_digit)
{ {
let offset = std::str::from_utf8_unchecked(&rest.to_bytes()[0..5]); // safe since rest.to_bytes().is_ascii()
let offset = unsafe { std::str::from_utf8_unchecked(&rest.to_bytes()[0..5]) };
if let (Ok(mut hr_offset), Ok(mut min_offset)) = if let (Ok(mut hr_offset), Ok(mut min_offset)) =
(offset[1..3].parse::<i64>(), offset[3..5].parse::<i64>()) (offset[1..3].parse::<i64>(), offset[3..5].parse::<i64>())
{ {
@ -325,7 +324,6 @@ where
.map(|res| (res - tm_gmtoff) as u64) .map(|res| (res - tm_gmtoff) as u64)
.unwrap_or(0)); .unwrap_or(0));
} }
}
Ok(0) Ok(0)
} }
@ -336,8 +334,7 @@ where
let s = CString::new(s)?; let s = CString::new(s)?;
let mut new_tm: libc::tm = unsafe { std::mem::zeroed() }; let mut new_tm: libc::tm = unsafe { std::mem::zeroed() };
for fmt in &[RFC3339_FMT_WITH_TIME, RFC3339_FMT] { for fmt in &[RFC3339_FMT_WITH_TIME, RFC3339_FMT] {
unsafe { let fmt = unsafe { CStr::from_bytes_with_nul_unchecked(fmt.as_bytes()) };
let fmt = CStr::from_bytes_with_nul_unchecked(fmt.as_bytes());
let ret = { let ret = {
let _with_locale = Locale::new( let _with_locale = Locale::new(
libc::LC_TIME, libc::LC_TIME,
@ -346,18 +343,19 @@ where
) )
.chain_err_summary(|| "Could not set locale for datetime conversion") .chain_err_summary(|| "Could not set locale for datetime conversion")
.chain_err_kind(crate::error::ErrorKind::External)?; .chain_err_kind(crate::error::ErrorKind::External)?;
strptime(s.as_ptr(), fmt.as_ptr(), &mut new_tm as *mut _) unsafe { strptime(s.as_ptr(), fmt.as_ptr(), &mut new_tm as *mut _) }
}; };
if ret.is_null() { if ret.is_null() {
continue; continue;
} }
let rest = CStr::from_ptr(ret); let rest = unsafe { CStr::from_ptr(ret) };
let tm_gmtoff = if rest.to_bytes().len() > 4 let tm_gmtoff = if rest.to_bytes().len() > 4
&& rest.to_bytes().is_ascii() && rest.to_bytes().is_ascii()
&& rest.to_bytes()[1..3].iter().all(u8::is_ascii_digit) && rest.to_bytes()[1..3].iter().all(u8::is_ascii_digit)
&& rest.to_bytes()[4..6].iter().all(u8::is_ascii_digit) && rest.to_bytes()[4..6].iter().all(u8::is_ascii_digit)
{ {
let offset = std::str::from_utf8_unchecked(&rest.to_bytes()[0..6]); // safe since rest.to_bytes().is_ascii()
let offset = unsafe { std::str::from_utf8_unchecked(&rest.to_bytes()[0..6]) };
if let (Ok(mut hr_offset), Ok(mut min_offset)) = if let (Ok(mut hr_offset), Ok(mut min_offset)) =
(offset[1..3].parse::<i64>(), offset[4..6].parse::<i64>()) (offset[1..3].parse::<i64>(), offset[4..6].parse::<i64>())
{ {
@ -377,7 +375,7 @@ where
}; };
if let Ok(idx) = TIMEZONE_ABBR.binary_search_by(|probe| probe.0.cmp(rest)) { if let Ok(idx) = TIMEZONE_ABBR.binary_search_by(|probe| probe.0.cmp(rest)) {
let (hr_offset, min_offset) = debug!(TIMEZONE_ABBR[idx]).1; let (hr_offset, min_offset) = TIMEZONE_ABBR[idx].1;
(hr_offset as i64) * 60 * 60 + (min_offset as i64) * 60 (hr_offset as i64) * 60 * 60 + (min_offset as i64) * 60
} else { } else {
0 0
@ -387,7 +385,6 @@ where
.map(|res| (res - tm_gmtoff) as u64) .map(|res| (res - tm_gmtoff) as u64)
.unwrap_or(0)); .unwrap_or(0));
} }
}
Ok(0) Ok(0)
} }