Skip to content

Commit 64653d5

Browse files
authored
Add localtime_r safe rule (#266)
1 parent 3eaeae0 commit 64653d5

4 files changed

Lines changed: 130 additions & 4 deletions

File tree

‎rules/time/tgt_refcount.rs‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,28 @@ fn f4(a0: Ptr<::libc::time_t>, a1: Ptr<Tm>) -> Ptr<Tm> {
6363
}
6464
}
6565

66+
fn f5(a0: Ptr<::libc::time_t>, a1: Ptr<Tm>) -> Ptr<Tm> {
67+
let __res = a1.clone();
68+
match jiff::Timestamp::from_second(a0.read()) {
69+
Ok(__ts) => {
70+
let __dt = __ts.to_zoned(jiff::tz::TimeZone::system());
71+
let __info = __dt.time_zone().to_offset_info(__ts);
72+
let __zone: Vec<u8> = __info.abbreviation().bytes().chain([0]).collect();
73+
let __isdst = if __info.dst().is_dst() { 1 } else { 0 };
74+
__res.with_mut(|__tm| {
75+
*__tm = Tm::from_zoned(&__dt);
76+
*__tm.tm_isdst.borrow_mut() = __isdst;
77+
*__tm.tm_zone.borrow_mut() = Ptr::alloc_array(__zone.into_boxed_slice());
78+
});
79+
__res
80+
}
81+
Err(_) => {
82+
libcc2rs::cpp2rust_errno().write(::libc::EOVERFLOW);
83+
Ptr::null()
84+
}
85+
}
86+
}
87+
6688
fn f6(a0: Ptr<u8>, a1: usize, a2: Ptr<u8>, a3: Ptr<Tm>) -> usize {
6789
let __dt = a3.with(|__tm| __tm.to_civil());
6890
let __text = match __dt {

‎tests/unit/out/refcount/sys_time.rs‎

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,57 @@ pub fn test_gmtime_r_2() {
9292
({ print_tm_1(1721126096_i64) });
9393
({ print_tm_1(4102444800_i64) });
9494
}
95-
pub fn test_strftime_3() {
95+
pub fn print_local_tm_3(t: i64) {
96+
let t: Value<i64> = Rc::new(RefCell::new(t));
97+
let tm: Value<libcc2rs::Tm> = Rc::new(RefCell::new(Default::default()));
98+
assert!(
99+
(((!(({
100+
let __res = (tm.as_pointer()).clone();
101+
match jiff::Timestamp::from_second((t.as_pointer()).read()) {
102+
Ok(__ts) => {
103+
let __dt = __ts.to_zoned(jiff::tz::TimeZone::system());
104+
let __info = __dt.time_zone().to_offset_info(__ts);
105+
let __zone: Vec<u8> = __info.abbreviation().bytes().chain([0]).collect();
106+
let __isdst = if __info.dst().is_dst() { 1 } else { 0 };
107+
__res.with_mut(|__tm| {
108+
*__tm = Tm::from_zoned(&__dt);
109+
*__tm.tm_isdst.borrow_mut() = __isdst;
110+
*__tm.tm_zone.borrow_mut() = Ptr::alloc_array(__zone.into_boxed_slice());
111+
});
112+
__res
113+
}
114+
Err(_) => {
115+
libcc2rs::cpp2rust_errno().write(::libc::EOVERFLOW);
116+
Ptr::null()
117+
}
118+
}
119+
})
120+
.is_null())) as i32)
121+
!= 0)
122+
);
123+
println!(
124+
"{}-{}-{} {}:{}:{} wday={} yday={} {} gmtoff={} isdst={}",
125+
(*(*tm.borrow()).tm_year.borrow()),
126+
(*(*tm.borrow()).tm_mon.borrow()),
127+
(*(*tm.borrow()).tm_mday.borrow()),
128+
(*(*tm.borrow()).tm_hour.borrow()),
129+
(*(*tm.borrow()).tm_min.borrow()),
130+
(*(*tm.borrow()).tm_sec.borrow()),
131+
(*(*tm.borrow()).tm_wday.borrow()),
132+
(*(*tm.borrow()).tm_yday.borrow()),
133+
(*(*tm.borrow()).tm_zone.borrow()),
134+
(*(*tm.borrow()).tm_gmtoff.borrow()),
135+
(*(*tm.borrow()).tm_isdst.borrow())
136+
);
137+
}
138+
pub fn test_localtime_r_4() {
139+
({ print_local_tm_3(0_i64) });
140+
({ print_local_tm_3(951782400_i64) });
141+
({ print_local_tm_3(1704067199_i64) });
142+
({ print_local_tm_3(1721126096_i64) });
143+
({ print_local_tm_3(1735689600_i64) });
144+
}
145+
pub fn test_strftime_5() {
96146
let t: Value<i64> = Rc::new(RefCell::new(1721126096_i64));
97147
let tm: Value<libcc2rs::Tm> = Rc::new(RefCell::new(Default::default()));
98148
assert!(
@@ -263,6 +313,7 @@ pub fn main() {
263313
fn main_0() -> i32 {
264314
({ test_time_0() });
265315
({ test_gmtime_r_2() });
266-
({ test_strftime_3() });
316+
({ test_localtime_r_4() });
317+
({ test_strftime_5() });
267318
return 0;
268319
}

‎tests/unit/out/unsafe/sys_time.rs‎

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,42 @@ pub unsafe fn test_gmtime_r_2() {
5454
(unsafe { print_tm_1(1721126096_i64) });
5555
(unsafe { print_tm_1(4102444800_i64) });
5656
}
57-
pub unsafe fn test_strftime_3() {
57+
pub unsafe fn print_local_tm_3(mut t: i64) {
58+
let mut tm: ::libc::tm = unsafe { std::mem::zeroed() };
59+
assert!(
60+
(((!((libc::localtime_r(
61+
(&mut t as *mut i64).cast_const(),
62+
(&mut tm as *mut ::libc::tm)
63+
))
64+
.is_null())) as i32)
65+
!= 0)
66+
);
67+
printf(
68+
(c"%d-%d-%d %d:%d:%d wday=%d yday=%d %s gmtoff=%ld isdst=%d\n"
69+
.as_ptr()
70+
.cast_mut())
71+
.cast_const() as *const i8,
72+
tm.tm_year,
73+
tm.tm_mon,
74+
tm.tm_mday,
75+
tm.tm_hour,
76+
tm.tm_min,
77+
tm.tm_sec,
78+
tm.tm_wday,
79+
tm.tm_yday,
80+
tm.tm_zone,
81+
tm.tm_gmtoff,
82+
tm.tm_isdst,
83+
);
84+
}
85+
pub unsafe fn test_localtime_r_4() {
86+
(unsafe { print_local_tm_3(0_i64) });
87+
(unsafe { print_local_tm_3(951782400_i64) });
88+
(unsafe { print_local_tm_3(1704067199_i64) });
89+
(unsafe { print_local_tm_3(1721126096_i64) });
90+
(unsafe { print_local_tm_3(1735689600_i64) });
91+
}
92+
pub unsafe fn test_strftime_5() {
5893
let mut t: i64 = 1721126096_i64;
5994
let mut tm: ::libc::tm = unsafe { std::mem::zeroed() };
6095
assert!(
@@ -137,6 +172,7 @@ pub fn main() {
137172
unsafe fn main_0() -> i32 {
138173
(unsafe { test_time_0() });
139174
(unsafe { test_gmtime_r_2() });
140-
(unsafe { test_strftime_3() });
175+
(unsafe { test_localtime_r_4() });
176+
(unsafe { test_strftime_5() });
141177
return 0;
142178
}

‎tests/unit/sys_time.c‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,22 @@ static void test_gmtime_r(void) {
3434
print_tm(4102444800);
3535
}
3636

37+
static void print_local_tm(time_t t) {
38+
struct tm tm;
39+
assert(localtime_r(&t, &tm) != NULL);
40+
printf("%d-%d-%d %d:%d:%d wday=%d yday=%d %s gmtoff=%ld isdst=%d\n",
41+
tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
42+
tm.tm_wday, tm.tm_yday, tm.tm_zone, tm.tm_gmtoff, tm.tm_isdst);
43+
}
44+
45+
static void test_localtime_r(void) {
46+
print_local_tm(0);
47+
print_local_tm(951782400);
48+
print_local_tm(1704067199);
49+
print_local_tm(1721126096);
50+
print_local_tm(1735689600);
51+
}
52+
3753
static void test_strftime(void) {
3854
time_t t = 1721126096;
3955
struct tm tm;
@@ -54,6 +70,7 @@ static void test_strftime(void) {
5470
int main(void) {
5571
test_time();
5672
test_gmtime_r();
73+
test_localtime_r();
5774
test_strftime();
5875
return 0;
5976
}

0 commit comments

Comments
 (0)