Skip to content

Commit 56115ef

Browse files
committed
Add safe realpath
1 parent 2b05463 commit 56115ef

3 files changed

Lines changed: 72 additions & 0 deletions

File tree

‎rules/cstdlib/tgt_refcount.rs‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,26 @@ fn f6(a0: Ptr<u8>) -> Ptr<u8> {
3030
}
3131
}
3232

33+
fn f10(a0: Ptr<u8>, a1: Ptr<u8>) -> Ptr<u8> {
34+
let __resolved = a1.clone();
35+
match ::std::fs::canonicalize(a0.to_rust_string()) {
36+
Ok(__p) => {
37+
let mut __bytes = __p.into_os_string().into_encoded_bytes();
38+
__bytes.push(0);
39+
if __resolved.is_null() {
40+
Ptr::alloc_array(__bytes.into_boxed_slice())
41+
} else {
42+
__resolved.with_slice_mut(__bytes.len(), |__s| __s.copy_from_slice(&__bytes));
43+
__resolved
44+
}
45+
}
46+
Err(__e) => {
47+
libcc2rs::cpp2rust_errno().write(__e.raw_os_error().unwrap_or(::libc::EIO));
48+
Ptr::null()
49+
}
50+
}
51+
}
52+
3353
fn f8(a0: AnyPtr, a1: AnyPtr, a2: usize, a3: usize, a4: fn(AnyPtr, AnyPtr) -> i32) -> AnyPtr {
3454
let __base = a1.reinterpret_cast::<u8>();
3555
let mut __lo: isize = 0;

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,49 @@ pub unsafe fn test_setenv_getenv_0() {
3636
((((libc::strcmp(v, (c"replaced".as_ptr().cast_mut()).cast_const())) == (0)) as i32) != 0)
3737
);
3838
}
39+
pub unsafe fn test_realpath_1() {
40+
let mut buf: [libc::c_char; 4096] = [(0 as libc::c_char); 4096];
41+
assert!(
42+
(((!((libc::realpath((c"/".as_ptr().cast_mut()).cast_const(), buf.as_mut_ptr())).is_null()))
43+
as i32)
44+
!= 0)
45+
);
46+
assert!(
47+
((((libc::strcmp(
48+
(buf.as_mut_ptr()).cast_const(),
49+
(c"/".as_ptr().cast_mut()).cast_const()
50+
)) == (0)) as i32)
51+
!= 0)
52+
);
53+
let mut p: *mut libc::c_char = libc::realpath(
54+
(c"/".as_ptr().cast_mut()).cast_const(),
55+
std::ptr::null_mut(),
56+
);
57+
assert!((((!((p).is_null())) as i32) != 0));
58+
assert!(
59+
((((libc::strcmp((p).cast_const(), (c"/".as_ptr().cast_mut()).cast_const())) == (0))
60+
as i32)
61+
!= 0)
62+
);
63+
libcc2rs::free_unsafe((p as *mut libc::c_char as *mut ::libc::c_void));
64+
(*libcc2rs::cpp2rust_errno_unsafe()) = 0;
65+
assert!(
66+
((((libc::realpath(
67+
(c"/cpp2rust_definitely_missing".as_ptr().cast_mut()).cast_const(),
68+
buf.as_mut_ptr()
69+
))
70+
.is_null()) as i32)
71+
!= 0)
72+
);
73+
assert!(((((*libcc2rs::cpp2rust_errno_unsafe()) == (2)) as i32) != 0));
74+
}
3975
pub fn main() {
4076
unsafe {
4177
std::process::exit(main_0() as i32);
4278
}
4379
}
4480
unsafe fn main_0() -> i32 {
4581
(unsafe { test_setenv_getenv_0() });
82+
(unsafe { test_realpath_1() });
4683
return 0;
4784
}

‎tests/unit/stdlib_h.c‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// no-compile: refcount
22
#include <assert.h>
3+
#include <errno.h>
34
#include <stdlib.h>
45
#include <string.h>
56

@@ -14,7 +15,21 @@ static void test_setenv_getenv(void) {
1415
assert(strcmp(v, "replaced") == 0);
1516
}
1617

18+
static void test_realpath(void) {
19+
char buf[4096];
20+
assert(realpath("/", buf) != NULL);
21+
assert(strcmp(buf, "/") == 0);
22+
char *p = realpath("/", NULL);
23+
assert(p != NULL);
24+
assert(strcmp(p, "/") == 0);
25+
free(p);
26+
errno = 0;
27+
assert(realpath("/cpp2rust_definitely_missing", buf) == NULL);
28+
assert(errno == ENOENT);
29+
}
30+
1731
int main(void) {
1832
test_setenv_getenv();
33+
test_realpath();
1934
return 0;
2035
}

0 commit comments

Comments
 (0)