G.MAC.PRO.01 不应通过过程宏将 unsafe 代码包装为 safe 代码
【级别】 要求
【描述】
不要通过过程宏将 unsafe 代码包装为safe 代码,以此来规避 Rust 静态分析检查。
【反例】
Rust
// 用 RUST 的过程宏包装 libc 的函数 printf 来打印一个 C 字符串
// 这个宏的输入参数必须是一个有效的 C 字符串指针,整个宏的使用是不安全的, // 但是因为过程宏中包括了 unsafe,导致过程宏看起来像 safe 调用
//
// rprintf!(b"hello\0" as *const u8);
#[proc_macro]
pub fn rprintf(input: TokenStream) -> TokenStream {
let expr = parse_macro_input!(input as syn::Expr);
// 这里包括 unsafe 代码,这样整个宏可以在 safe 代码中使用
quote!({
unsafe {
printf(b"%s\n\0" as *const _ as *const u8, #expr);
}
}).into()
}
【正例】
Rust
// 用 RUST 的过程宏包装 libc 的函数 printf 来打印一个 C 字符串
// 这个宏的输入参数必须是一个有效的 C 字符串指针,同时也是调用外部函数 // 必须在 unsafe 代码块中使用
//
// unsafe { rprintf!(b"hello\0" as *const u8) };
#[proc_macro]
pub fn rprintf(input: TokenStream) -> TokenStream {
let expr = parse_macro_input!(input as syn::Expr);
// 这里不能包括 unsafe 代码,而是要求整个宏在 unsafe 代码块中使用
quote!({
printf(b"%s\n\0" as *const _ as *const u8, #expr);
}).into()
}
【相关讨论】