diff options
| -rw-r--r-- | adapters/fparkan-render-vulkan/src/ffi.rs | 1 | ||||
| -rw-r--r-- | xtask/src/main.rs | 53 |
2 files changed, 52 insertions, 2 deletions
diff --git a/adapters/fparkan-render-vulkan/src/ffi.rs b/adapters/fparkan-render-vulkan/src/ffi.rs index 54e9cf3..5977f43 100644 --- a/adapters/fparkan-render-vulkan/src/ffi.rs +++ b/adapters/fparkan-render-vulkan/src/ffi.rs @@ -1,4 +1,3 @@ -#![allow(unsafe_code)] #![cfg_attr( test, allow( diff --git a/xtask/src/main.rs b/xtask/src/main.rs index da8c16f..e1e5970 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1199,6 +1199,7 @@ fn scan_policy_file(path: &Path, failures: &mut Vec<String>) -> Result<(), Strin path.display() )); } + validate_unsafe_module_attribute_policy(path, &text, failures); let mut previous_line_has_safety_comment = false; for (index, line) in text.lines().enumerate() { let trimmed = line.trim_start(); @@ -1224,6 +1225,27 @@ fn scan_policy_file(path: &Path, failures: &mut Vec<String>) -> Result<(), Strin Ok(()) } +fn validate_unsafe_module_attribute_policy(path: &Path, text: &str, failures: &mut Vec<String>) { + let declares_unsafe_module_boundary = text + .lines() + .map(str::trim_start) + .any(|line| line.starts_with("#![allow(unsafe_code)]")); + match ( + is_audited_unsafe_source(path), + declares_unsafe_module_boundary, + ) { + (true, false) => failures.push(format!( + "{}: audited Vulkan FFI module must declare #![allow(unsafe_code)]", + path.display() + )), + (false, true) => failures.push(format!( + "{}: #![allow(unsafe_code)] is only permitted in audited Vulkan FFI modules", + path.display() + )), + (true, true) | (false, false) => {} + } +} + fn contains_unsafe_construct(line: &str) -> bool { line.contains(concat!("un", "safe {")) || line.contains(concat!("un", "safe fn")) @@ -1240,7 +1262,6 @@ fn has_safety_comment(line: &str) -> bool { } const AUDITED_UNSAFE_SOURCE_FILES: &[&str] = &[ - "adapters/fparkan-render-vulkan/src/ffi.rs", "adapters/fparkan-render-vulkan/src/ffi/instance.rs", "adapters/fparkan-render-vulkan/src/ffi/capabilities.rs", "adapters/fparkan-render-vulkan/src/ffi/resources.rs", @@ -3036,4 +3057,34 @@ source = "git+https://example.invalid/repo" ))); assert!(!contains_unsafe_construct("#![forbid(unsafe_code)]")); } + + #[test] + fn unsafe_module_attributes_must_match_audited_ffi_allowlist() { + let audited = Path::new("adapters/fparkan-render-vulkan/src/ffi/runtime.rs"); + let non_audited = Path::new("adapters/fparkan-render-vulkan/src/ffi.rs"); + + let mut failures = Vec::new(); + validate_unsafe_module_attribute_policy(audited, "mod x;\n", &mut failures); + assert_eq!( + failures, + vec![format!( + "{}: audited Vulkan FFI module must declare #![allow(unsafe_code)]", + audited.display() + )] + ); + + failures.clear(); + validate_unsafe_module_attribute_policy( + non_audited, + "#![allow(unsafe_code)]\nmod runtime;\n", + &mut failures, + ); + assert_eq!( + failures, + vec![format!( + "{}: #![allow(unsafe_code)] is only permitted in audited Vulkan FFI modules", + non_audited.display() + )] + ); + } } |
