summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2022-10-17 18:05:46 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2022-10-17 18:06:58 +0300
commit3697b7d960cc9dbe602fa84f861cea854b600b73 (patch)
treed63a3de350aedbb2e7acd6b2a1e646195a5693aa
parentdd0baa82e9789da23c8f9b06925776c7f80e2568 (diff)
downloadmeli-3697b7d960cc9dbe602fa84f861cea854b600b73.zip
melib/datetime: don't use LC_ category in place of LC_ masks in libc calls
LC_ masks are bit masks, whereas category values are not. Concerns #159 [imap] all mail timestamps are zero/epoch #159 https://git.meli.delivery/meli/meli/issues/159
-rw-r--r--melib/src/datetime.rs56
1 files changed, 45 insertions, 11 deletions
diff --git a/melib/src/datetime.rs b/melib/src/datetime.rs
index e944eeb4..8a9dbdb7 100644
--- a/melib/src/datetime.rs
+++ b/melib/src/datetime.rs
@@ -41,6 +41,7 @@ use crate::error::{Result, ResultIntoMeliError};
use std::borrow::Cow;
use std::convert::TryInto;
use std::ffi::{CStr, CString};
+use std::os::raw::c_int;
pub type UnixTimestamp = u64;
pub const RFC3339_FMT_WITH_TIME: &str = "%Y-%m-%dT%H:%M:%S\0";
@@ -74,14 +75,36 @@ extern "C" {
fn gettimeofday(tv: *mut libc::timeval, tz: *mut libc::timezone) -> i32;
}
+#[repr(i32)]
+#[derive(Copy, Clone)]
+#[allow(dead_code)]
+enum LocaleCategoryMask {
+ Time = libc::LC_TIME_MASK,
+ All = libc::LC_ALL_MASK,
+}
+
+#[repr(i32)]
+#[derive(Copy, Clone)]
+#[allow(dead_code)]
+enum LocaleCategory {
+ Time = libc::LC_TIME,
+ All = libc::LC_ALL,
+}
+
#[cfg(not(target_os = "netbsd"))]
+#[allow(dead_code)]
struct Locale {
+ mask: LocaleCategoryMask,
+ category: LocaleCategory,
new_locale: libc::locale_t,
old_locale: libc::locale_t,
}
+
#[cfg(target_os = "netbsd")]
+#[allow(dead_code)]
struct Locale {
- mask: std::os::raw::c_int,
+ mask: LocaleCategoryMask,
+ category: LocaleCategory,
old_locale: *const std::os::raw::c_char,
}
@@ -94,7 +117,7 @@ impl Drop for Locale {
}
#[cfg(target_os = "netbsd")]
unsafe {
- let _ = libc::setlocale(self.mask, self.old_locale);
+ let _ = libc::setlocale(self.category as c_int, self.old_locale);
}
}
}
@@ -103,11 +126,12 @@ impl Drop for Locale {
impl Locale {
#[cfg(not(target_os = "netbsd"))]
fn new(
- mask: std::os::raw::c_int,
+ mask: LocaleCategoryMask,
+ category: LocaleCategory,
locale: *const std::os::raw::c_char,
base: libc::locale_t,
) -> Result<Self> {
- let new_locale = unsafe { libc::newlocale(mask, locale, base) };
+ let new_locale = unsafe { libc::newlocale(mask as c_int, locale, base) };
if new_locale.is_null() {
return Err(nix::Error::last().into());
}
@@ -117,25 +141,32 @@ impl Locale {
return Err(nix::Error::last().into());
}
Ok(Locale {
+ mask,
+ category,
new_locale,
old_locale,
})
}
#[cfg(target_os = "netbsd")]
fn new(
- mask: std::os::raw::c_int,
+ mask: LocaleCategoryMask,
+ category: LocaleCategory,
locale: *const std::os::raw::c_char,
_base: libc::locale_t,
) -> Result<Self> {
- let old_locale = unsafe { libc::setlocale(mask, std::ptr::null_mut()) };
+ let old_locale = unsafe { libc::setlocale(category as c_int, std::ptr::null_mut()) };
if old_locale.is_null() {
return Err(nix::Error::last().into());
}
- let new_locale = unsafe { libc::setlocale(mask, locale) };
+ let new_locale = unsafe { libc::setlocale(category as c_int, locale) };
if new_locale.is_null() {
return Err(nix::Error::last().into());
}
- Ok(Locale { mask, old_locale })
+ Ok(Locale {
+ mask,
+ category,
+ old_locale,
+ })
}
}
@@ -166,7 +197,8 @@ pub fn timestamp_to_string(timestamp: UnixTimestamp, fmt: Option<&str>, posix: b
let _with_locale: Option<Result<Locale>> = if posix {
Some(
Locale::new(
- libc::LC_TIME,
+ LocaleCategoryMask::Time,
+ LocaleCategory::Time,
b"C\0".as_ptr() as *const std::os::raw::c_char,
std::ptr::null_mut(),
)
@@ -304,7 +336,8 @@ where
let fmt = unsafe { CStr::from_bytes_with_nul_unchecked(fmt.as_bytes()) };
let ret = {
let _with_locale = Locale::new(
- libc::LC_TIME,
+ LocaleCategoryMask::Time,
+ LocaleCategory::Time,
b"C\0".as_ptr() as *const std::os::raw::c_char,
std::ptr::null_mut(),
)
@@ -365,7 +398,8 @@ where
let fmt = unsafe { CStr::from_bytes_with_nul_unchecked(fmt.as_bytes()) };
let ret = {
let _with_locale = Locale::new(
- libc::LC_TIME,
+ LocaleCategoryMask::Time,
+ LocaleCategory::Time,
b"C\0".as_ptr() as *const std::os::raw::c_char,
std::ptr::null_mut(),
)