diff --git a/src/lib.rs b/src/lib.rs index c560816a..be1cb5c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ #![no_std] -#![feature(allocator_api, alloc_error_handler, const_fn)] +#![feature(allocator_api, alloc_error_handler, const_fn, const_raw_ptr_deref)] extern crate alloc; diff --git a/src/types.rs b/src/types.rs index f1a412b0..17ce06d7 100644 --- a/src/types.rs +++ b/src/types.rs @@ -18,11 +18,11 @@ impl Mode { pub struct CStr(str); impl CStr { - pub fn new(data: &str) -> &CStr { - if data.bytes().position(|b| b == b'\x00') != Some(data.len() - 1) { - panic!("CStr must contain a single NUL byte at the end"); - } - unsafe { &*(data as *const str as *const CStr) } + /// Creates a new CStr from a str without performing any additional checks. `data` _must_ end + /// with a NUL byte, and should only have only a single NUL byte, or the string will be + /// truncated. + pub const unsafe fn new_unchecked(data: &str) -> &CStr { + &*(data as *const str as *const CStr) } } @@ -34,9 +34,15 @@ impl Deref for CStr { } } +/// Creates a new `CStr` from a string literal. The string literal should not contain any NUL +/// bytes. Example usage: +/// ``` +/// const MY_CSTR: &CStr = cstr!("My awesome CStr!"); +/// ``` #[macro_export] macro_rules! cstr { ($str:expr) => {{ - $crate::CStr::new(concat!($str, "\x00")) + let s = concat!($str, "\x00"); + unsafe { $crate::CStr::new_unchecked(s) } }}; } diff --git a/tests/utils/Cargo.toml b/tests/utils/Cargo.toml new file mode 100644 index 00000000..fbb54634 --- /dev/null +++ b/tests/utils/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "utils-tests" +version = "0.1.0" +authors = ["Alex Gaynor ", "Geoffrey Thomas "] +edition = "2018" + +[lib] +crate-type = ["staticlib"] +test = false + +[features] +default = ["linux-kernel-module"] + +[dependencies] +linux-kernel-module = { path = "../..", optional = true } + +[dev-dependencies] +kernel-module-testlib = { path = "../../testlib" } diff --git a/tests/utils/src/lib.rs b/tests/utils/src/lib.rs new file mode 100644 index 00000000..79dcde2e --- /dev/null +++ b/tests/utils/src/lib.rs @@ -0,0 +1,22 @@ +#![no_std] +#![feature(const_str_as_bytes)] + +use linux_kernel_module; + +struct UtilsTestModule; + +#[allow(dead_code)] +const TEST_CSTR: &linux_kernel_module::CStr = linux_kernel_module::cstr!("abc"); + +impl linux_kernel_module::KernelModule for UtilsTestModule { + fn init() -> linux_kernel_module::KernelResult { + Ok(UtilsTestModule) + } +} + +linux_kernel_module::kernel_module!( + UtilsTestModule, + author: "Fish in a Barrel Contributors", + description: "A module for testing various utilities", + license: "GPL" +); diff --git a/tests/utils/tests/tests.rs b/tests/utils/tests/tests.rs new file mode 100644 index 00000000..46f88877 --- /dev/null +++ b/tests/utils/tests/tests.rs @@ -0,0 +1,6 @@ +use kernel_module_testlib::with_kernel_module; + +#[test] +fn test_module_loads() { + with_kernel_module(|| {}); +}