Skip to main content

libddwaf/
handle.rs

1use std::ffi::CStr;
2
3use crate::{Context, object::get_default_allocator};
4
5/// A fully configured WAF instance.
6///
7/// This is obtained by [`Builder::build`][crate::Builder::build] and provides facility to create new [`Context`]
8/// that use the underlying instance's configuration.
9#[repr(transparent)]
10pub struct Handle {
11    pub(crate) raw: libddwaf_sys::ddwaf_handle,
12}
13impl Handle {
14    /// Creates a new [`Context`] from this instance.
15    #[must_use]
16    pub fn new_context(&self) -> Context {
17        Context {
18            raw: unsafe {
19                libddwaf_sys::ddwaf_context_init(self.raw, get_default_allocator().into())
20            },
21        }
22    }
23
24    /// Returns the list of actions that may be produced by this instance's ruleset.
25    pub fn known_actions(&self) -> Vec<&CStr> {
26        self.call_cstr_array_fn(libddwaf_sys::ddwaf_known_actions)
27    }
28
29    /// Returns the list of addresses that are used by this instance's ruleset.
30    ///
31    /// Sending data for addresses not in this list to [`Context::run`] should be avoided as this
32    /// data will never result in any side-effects.
33    pub fn known_addresses(&self) -> Vec<&CStr> {
34        self.call_cstr_array_fn(libddwaf_sys::ddwaf_known_addresses)
35    }
36
37    fn call_cstr_array_fn(
38        &self,
39        f: unsafe extern "C" fn(
40            libddwaf_sys::ddwaf_handle,
41            *mut u32,
42        ) -> *const *const std::os::raw::c_char,
43    ) -> Vec<&CStr> {
44        let mut size = std::mem::MaybeUninit::<u32>::uninit();
45        let ptr = unsafe { f(self.raw, size.as_mut_ptr()) };
46        if ptr.is_null() {
47            return vec![];
48        }
49        let size = unsafe { size.assume_init() as usize };
50        let arr = unsafe { std::slice::from_raw_parts(ptr, size) };
51        arr.iter().map(|&x| unsafe { CStr::from_ptr(x) }).collect()
52    }
53}
54impl Drop for Handle {
55    fn drop(&mut self) {
56        unsafe { libddwaf_sys::ddwaf_destroy(self.raw) }
57    }
58}
59// SAFETY: ddwaf instances are effectively immutable
60unsafe impl Send for Handle {}
61// SAFETY: ddwaf instances are effectively immutable
62unsafe impl Sync for Handle {}