#![allow(
clippy::missing_inline_in_public_items,
clippy::must_use_candidate,
clippy::missing_safety_doc
)]
use crate::abi::structs::*;
use crate::abi::types::*;
use std::ffi::c_void;
use std::os::raw::c_int;
use std::ptr;
use std::sync::Mutex;
pub const XSLT_SECPREF_READ_FILE: c_int = 1;
pub const XSLT_SECPREF_WRITE_FILE: c_int = 2;
pub const XSLT_SECPREF_CREATE_DIRECTORY: c_int = 3;
pub const XSLT_SECPREF_READ_NETWORK: c_int = 4;
pub const XSLT_SECPREF_WRITE_NETWORK: c_int = 5;
pub const XSLT_SECPREF_DEFAULT: c_int = 0;
pub const XSLT_SECPREF_DENY: c_int = 0;
pub const XSLT_SECPREF_ALLOW: c_int = 1;
#[repr(C)]
pub struct XsltSecurityPrefs {
pub readFile: c_int,
pub writeFile: c_int,
pub createDirectory: c_int,
pub readNetwork: c_int,
pub writeNetwork: c_int,
}
#[repr(transparent)]
struct SecurityPrefsPtr(*mut c_void);
unsafe impl Send for SecurityPrefsPtr {}
static DEFAULT_SECURITY_PREFS: Mutex<Option<SecurityPrefsPtr>> = Mutex::new(None);
#[no_mangle]
pub unsafe extern "C" fn xsltNewSecurityPrefs() -> *mut c_void {
let prefs = Box::new(XsltSecurityPrefs {
readFile: XSLT_SECPREF_ALLOW,
writeFile: XSLT_SECPREF_ALLOW,
createDirectory: XSLT_SECPREF_ALLOW,
readNetwork: XSLT_SECPREF_ALLOW,
writeNetwork: XSLT_SECPREF_ALLOW,
});
Box::into_raw(prefs) as *mut c_void
}
#[no_mangle]
pub unsafe extern "C" fn xsltFreeSecurityPrefs(sec: *mut c_void) {
if !sec.is_null() {
let _ = Box::from_raw(sec as *mut XsltSecurityPrefs);
}
}
#[no_mangle]
pub unsafe extern "C" fn xsltSetSecurityPrefs(
sec: *mut c_void,
option: c_int,
value: c_int,
) -> c_int {
if sec.is_null() {
return -1;
}
let prefs = &mut *(sec as *mut XsltSecurityPrefs);
match option {
XSLT_SECPREF_READ_FILE => prefs.readFile = value,
XSLT_SECPREF_WRITE_FILE => prefs.writeFile = value,
XSLT_SECPREF_CREATE_DIRECTORY => prefs.createDirectory = value,
XSLT_SECPREF_READ_NETWORK => prefs.readNetwork = value,
XSLT_SECPREF_WRITE_NETWORK => prefs.writeNetwork = value,
_ => return -1,
}
0
}
#[no_mangle]
pub unsafe extern "C" fn xsltGetSecurityPrefs(sec: *mut c_void, option: c_int) -> c_int {
if sec.is_null() {
return XSLT_SECPREF_DENY;
}
let prefs = &*(sec as *mut XsltSecurityPrefs);
match option {
XSLT_SECPREF_READ_FILE => prefs.readFile,
XSLT_SECPREF_WRITE_FILE => prefs.writeFile,
XSLT_SECPREF_CREATE_DIRECTORY => prefs.createDirectory,
XSLT_SECPREF_READ_NETWORK => prefs.readNetwork,
XSLT_SECPREF_WRITE_NETWORK => prefs.writeNetwork,
_ => XSLT_SECPREF_DENY,
}
}
#[no_mangle]
pub unsafe extern "C" fn xsltSetDefaultSecurityPrefs(sec: *mut c_void) {
let mut guard = DEFAULT_SECURITY_PREFS.lock().unwrap();
*guard = Some(SecurityPrefsPtr(sec));
}
#[no_mangle]
pub unsafe extern "C" fn xsltGetDefaultSecurityPrefs() -> *mut c_void {
let guard = DEFAULT_SECURITY_PREFS.lock().unwrap();
guard.as_ref().map_or(ptr::null_mut(), |p| p.0)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_free_security_prefs() {
unsafe {
let prefs = xsltNewSecurityPrefs();
assert!(!prefs.is_null());
xsltFreeSecurityPrefs(prefs);
}
}
#[test]
fn test_free_null() {
unsafe {
xsltFreeSecurityPrefs(ptr::null_mut());
}
}
#[test]
fn test_new_prefs_defaults_allow() {
unsafe {
let prefs = xsltNewSecurityPrefs();
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_READ_FILE),
XSLT_SECPREF_ALLOW
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_WRITE_FILE),
XSLT_SECPREF_ALLOW
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_CREATE_DIRECTORY),
XSLT_SECPREF_ALLOW
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_READ_NETWORK),
XSLT_SECPREF_ALLOW
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_WRITE_NETWORK),
XSLT_SECPREF_ALLOW
);
xsltFreeSecurityPrefs(prefs);
}
}
#[test]
fn test_set_and_get() {
unsafe {
let prefs = xsltNewSecurityPrefs();
assert_eq!(
xsltSetSecurityPrefs(prefs, XSLT_SECPREF_READ_FILE, XSLT_SECPREF_DENY),
0
);
assert_eq!(
xsltSetSecurityPrefs(prefs, XSLT_SECPREF_WRITE_FILE, XSLT_SECPREF_DENY),
0
);
assert_eq!(
xsltSetSecurityPrefs(prefs, XSLT_SECPREF_CREATE_DIRECTORY, XSLT_SECPREF_DENY),
0
);
assert_eq!(
xsltSetSecurityPrefs(prefs, XSLT_SECPREF_READ_NETWORK, XSLT_SECPREF_DENY),
0
);
assert_eq!(
xsltSetSecurityPrefs(prefs, XSLT_SECPREF_WRITE_NETWORK, XSLT_SECPREF_DENY),
0
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_READ_FILE),
XSLT_SECPREF_DENY
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_WRITE_FILE),
XSLT_SECPREF_DENY
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_CREATE_DIRECTORY),
XSLT_SECPREF_DENY
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_READ_NETWORK),
XSLT_SECPREF_DENY
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_WRITE_NETWORK),
XSLT_SECPREF_DENY
);
assert_eq!(
xsltSetSecurityPrefs(prefs, XSLT_SECPREF_READ_FILE, XSLT_SECPREF_ALLOW),
0
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_READ_FILE),
XSLT_SECPREF_ALLOW
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_WRITE_FILE),
XSLT_SECPREF_DENY
);
assert_eq!(
xsltSetSecurityPrefs(prefs, XSLT_SECPREF_WRITE_FILE, XSLT_SECPREF_ALLOW),
0
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_WRITE_FILE),
XSLT_SECPREF_ALLOW
);
assert_eq!(
xsltSetSecurityPrefs(prefs, XSLT_SECPREF_CREATE_DIRECTORY, XSLT_SECPREF_ALLOW),
0
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_CREATE_DIRECTORY),
XSLT_SECPREF_ALLOW
);
assert_eq!(
xsltSetSecurityPrefs(prefs, XSLT_SECPREF_READ_NETWORK, XSLT_SECPREF_ALLOW),
0
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_READ_NETWORK),
XSLT_SECPREF_ALLOW
);
assert_eq!(
xsltSetSecurityPrefs(prefs, XSLT_SECPREF_WRITE_NETWORK, XSLT_SECPREF_ALLOW),
0
);
assert_eq!(
xsltGetSecurityPrefs(prefs, XSLT_SECPREF_WRITE_NETWORK),
XSLT_SECPREF_ALLOW
);
xsltFreeSecurityPrefs(prefs);
}
}
#[test]
fn test_null_pointer() {
unsafe {
assert_eq!(
xsltSetSecurityPrefs(ptr::null_mut(), XSLT_SECPREF_READ_FILE, XSLT_SECPREF_ALLOW),
-1
);
assert_eq!(
xsltGetSecurityPrefs(ptr::null_mut(), XSLT_SECPREF_READ_FILE),
XSLT_SECPREF_DENY
);
}
}
#[test]
fn test_invalid_option() {
unsafe {
let prefs = xsltNewSecurityPrefs();
assert_eq!(xsltSetSecurityPrefs(prefs, 99, XSLT_SECPREF_ALLOW), -1);
assert_eq!(xsltGetSecurityPrefs(prefs, 99), XSLT_SECPREF_DENY);
xsltFreeSecurityPrefs(prefs);
}
}
#[test]
fn test_default_security_prefs() {
unsafe {
assert!(xsltGetDefaultSecurityPrefs().is_null());
let prefs = xsltNewSecurityPrefs();
xsltSetDefaultSecurityPrefs(prefs);
let retrieved = xsltGetDefaultSecurityPrefs();
assert_eq!(retrieved, prefs);
assert_eq!(
xsltGetSecurityPrefs(retrieved, XSLT_SECPREF_READ_FILE),
XSLT_SECPREF_ALLOW
);
xsltSetDefaultSecurityPrefs(ptr::null_mut());
assert!(xsltGetDefaultSecurityPrefs().is_null());
xsltFreeSecurityPrefs(prefs);
}
}
}