luadec_sys/
lib.rs

1//! Raw FFI bindings for LuaDec
2//!
3//! This crate provides low-level FFI bindings to the LuaDec C library.
4//! For a high-level safe API, use the `luadec` crate instead.
5
6#![allow(non_camel_case_types)]
7#![allow(non_snake_case)]
8#![allow(non_upper_case_globals)]
9
10use libc::{c_char, size_t};
11
12/// Opaque structure representing the decompile result from C
13#[repr(C)]
14pub struct luadec_result_t {
15    _private: [u8; 0],
16}
17
18extern "C" {
19    /// Decompile bytecode from a buffer
20    pub fn luadec_decompile_buffer(bytecode: *const c_char, size: size_t) -> *mut luadec_result_t;
21    
22    /// Free the result structure
23    pub fn luadec_free_result(result: *mut luadec_result_t);
24    
25    /// Get the decompiled result string (NULL if error occurred)
26    pub fn luadec_get_result(result: *const luadec_result_t) -> *const c_char;
27    
28    /// Get the error string (NULL if no error)
29    pub fn luadec_get_error(result: *const luadec_result_t) -> *const c_char;
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test]
37    fn test_decompile_buffer() {
38        // This is just a placeholder test to ensure the bindings compile
39        unsafe {
40            // Read test2.lua
41            let result = std::fs::read("test2.lua").unwrap();
42            let bytecode = result.as_ptr() as *const c_char;
43            let size: size_t = result.len() as size_t;
44            let result = luadec_decompile_buffer(bytecode, size);
45            assert!(!result.is_null());
46            luadec_free_result(result);
47        }
48    }
49
50    #[test]
51    fn test_decompile_stress_test() {
52        // Stress test: run decompilation 10 times to check for memory leaks or crashes
53        unsafe {
54            // Read test2.lua
55            let bytecode_data = std::fs::read("test2.lua").unwrap();
56            let bytecode = bytecode_data.as_ptr() as *const c_char;
57            let size: size_t = bytecode_data.len() as size_t;
58            
59            for i in 0..10 {
60                println!("Running decompilation iteration {}", i + 1);
61                let result = luadec_decompile_buffer(bytecode, size);
62                assert!(!result.is_null(), "Decompilation failed on iteration {}", i + 1);
63                
64                // Check if we got a result or an error
65                let result_str = luadec_get_result(result);
66                let error_str = luadec_get_error(result);
67                
68                if !result_str.is_null() {
69                    println!("Iteration {} succeeded", i + 1);
70                } else if !error_str.is_null() {
71                    let error = std::ffi::CStr::from_ptr(error_str).to_string_lossy();
72                    println!("Iteration {} failed with error: {}", i + 1, error);
73                } else {
74                    panic!("Iteration {} returned null for both result and error", i + 1);
75                }
76                
77                luadec_free_result(result);
78            }
79            println!("All 10 iterations completed successfully!");
80        }
81    }
82}