11//! Comprehensive safety tests for platform_integration FFI functions
2- //!
2+ //!
33//! Tests focus on:
44//! - Null pointer handling
55//! - Buffer overflow prevention
@@ -37,14 +37,14 @@ fn test_get_core_handle_null_safety() {
3737 // Test 1: Null client pointer
3838 let handle = ffi_dash_spv_get_core_handle ( ptr:: null_mut ( ) ) ;
3939 assert ! ( handle. is_null( ) , "Should return null for null client" ) ;
40-
40+
4141 // Test 2: Getting last error after null pointer operation
4242 let error = dash_spv_ffi_get_last_error ( ) ;
4343 if !error. is_null ( ) {
4444 let error_str = CStr :: from_ptr ( error) ;
4545 assert ! (
46- error_str. to_string_lossy( ) . contains( "null" ) ||
47- error_str. to_string_lossy( ) . contains( "Null" ) ,
46+ error_str. to_string_lossy( ) . contains( "null" )
47+ || error_str. to_string_lossy( ) . contains( "Null" ) ,
4848 "Error should mention null pointer"
4949 ) ;
5050 // Note: Error strings are managed internally by the FFI layer
@@ -58,7 +58,7 @@ fn test_release_core_handle_safety() {
5858 unsafe {
5959 // Test 1: Release null handle (should be safe no-op)
6060 ffi_dash_spv_release_core_handle ( ptr:: null_mut ( ) ) ;
61-
61+
6262 // Test 2: Double-free prevention
6363 // In a real implementation with a valid handle:
6464 // let handle = create_valid_handle();
@@ -73,7 +73,7 @@ fn test_get_quorum_public_key_null_pointer_safety() {
7373 unsafe {
7474 let quorum_hash = [ 0u8 ; 32 ] ;
7575 let mut output_buffer = [ 0u8 ; 48 ] ;
76-
76+
7777 // Test 1: Null client
7878 let result = ffi_dash_spv_get_quorum_public_key (
7979 ptr:: null_mut ( ) ,
@@ -84,7 +84,7 @@ fn test_get_quorum_public_key_null_pointer_safety() {
8484 output_buffer. len ( ) ,
8585 ) ;
8686 assert_ffi_error ( result, FFIErrorCode :: NullPointer ) ;
87-
87+
8888 // Test 2: Null quorum hash
8989 let mock_client = create_mock_client ( ) ;
9090 if !mock_client. is_null ( ) {
@@ -98,7 +98,7 @@ fn test_get_quorum_public_key_null_pointer_safety() {
9898 ) ;
9999 assert_ffi_error ( result, FFIErrorCode :: NullPointer ) ;
100100 }
101-
101+
102102 // Test 3: Null output buffer
103103 let result = ffi_dash_spv_get_quorum_public_key (
104104 create_mock_client ( ) ,
@@ -118,7 +118,7 @@ fn test_get_quorum_public_key_buffer_size_validation() {
118118 unsafe {
119119 let quorum_hash = [ 0u8 ; 32 ] ;
120120 let mock_client = create_mock_client ( ) ;
121-
121+
122122 // Test 1: Buffer too small (47 bytes instead of 48)
123123 let mut small_buffer = [ 0u8 ; 47 ] ;
124124 let result = ffi_dash_spv_get_quorum_public_key (
@@ -130,11 +130,8 @@ fn test_get_quorum_public_key_buffer_size_validation() {
130130 small_buffer. len ( ) ,
131131 ) ;
132132 // Should fail with InvalidArgument or similar
133- assert ! (
134- result. error_code != 0 ,
135- "Should fail with small buffer"
136- ) ;
137-
133+ assert ! ( result. error_code != 0 , "Should fail with small buffer" ) ;
134+
138135 // Test 2: Correct buffer size (48 bytes)
139136 let mut correct_buffer = [ 0u8 ; 48 ] ;
140137 let _result = ffi_dash_spv_get_quorum_public_key (
@@ -146,7 +143,7 @@ fn test_get_quorum_public_key_buffer_size_validation() {
146143 correct_buffer. len ( ) ,
147144 ) ;
148145 // Will fail due to null client, but not due to buffer size
149-
146+
150147 // Test 3: Larger buffer (should be fine)
151148 let mut large_buffer = [ 0u8 ; 100 ] ;
152149 let _result = ffi_dash_spv_get_quorum_public_key (
@@ -166,20 +163,15 @@ fn test_get_quorum_public_key_buffer_size_validation() {
166163fn test_get_platform_activation_height_safety ( ) {
167164 unsafe {
168165 let mut height: u32 = 0 ;
169-
166+
170167 // Test 1: Null client
171- let result = ffi_dash_spv_get_platform_activation_height (
172- ptr:: null_mut ( ) ,
173- & mut height as * mut u32 ,
174- ) ;
168+ let result =
169+ ffi_dash_spv_get_platform_activation_height ( ptr:: null_mut ( ) , & mut height as * mut u32 ) ;
175170 assert_ffi_error ( result, FFIErrorCode :: NullPointer ) ;
176-
171+
177172 // Test 2: Null output pointer
178173 let mock_client = create_mock_client ( ) ;
179- let result = ffi_dash_spv_get_platform_activation_height (
180- mock_client,
181- ptr:: null_mut ( ) ,
182- ) ;
174+ let result = ffi_dash_spv_get_platform_activation_height ( mock_client, ptr:: null_mut ( ) ) ;
183175 assert_ffi_error ( result, FFIErrorCode :: NullPointer ) ;
184176 }
185177}
@@ -190,47 +182,44 @@ fn test_thread_safety_concurrent_access() {
190182 // Test concurrent access to FFI functions
191183 let barrier = Arc :: new ( std:: sync:: Barrier :: new ( 3 ) ) ;
192184 let results = Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ;
193-
185+
194186 let mut handles = vec ! [ ] ;
195-
187+
196188 for i in 0 ..3 {
197189 let barrier_clone = barrier. clone ( ) ;
198190 let results_clone = results. clone ( ) ;
199-
191+
200192 let handle = thread:: spawn ( move || {
201193 unsafe {
202194 // Synchronize thread start
203195 barrier_clone. wait ( ) ;
204-
196+
205197 // Each thread tries to get platform activation height
206198 let mut height: u32 = 0 ;
207199 let result = ffi_dash_spv_get_platform_activation_height (
208200 ptr:: null_mut ( ) , // Using null for test
209201 & mut height as * mut u32 ,
210202 ) ;
211-
203+
212204 // Store result
213205 results_clone. lock ( ) . unwrap ( ) . push ( ( i, result. error_code ) ) ;
214206 }
215207 } ) ;
216-
208+
217209 handles. push ( handle) ;
218210 }
219-
211+
220212 // Wait for all threads
221213 for handle in handles {
222214 handle. join ( ) . unwrap ( ) ;
223215 }
224-
216+
225217 // Verify all threads got consistent error codes
226218 let results_vec = results. lock ( ) . unwrap ( ) ;
227219 assert_eq ! ( results_vec. len( ) , 3 ) ;
228220 let expected_error = FFIErrorCode :: NullPointer as i32 ;
229221 for ( thread_id, error_code) in results_vec. iter ( ) {
230- assert_eq ! (
231- * error_code, expected_error,
232- "Thread {} got unexpected error code" , thread_id
233- ) ;
222+ assert_eq ! ( * error_code, expected_error, "Thread {} got unexpected error code" , thread_id) ;
234223 }
235224}
236225
@@ -246,11 +235,11 @@ fn test_memory_safety_patterns() {
246235 // Attempting to use the handle again should be safe (no crash)
247236 // In practice, the implementation should handle this gracefully
248237 }
249-
238+
250239 // Test 2: Buffer overflow prevention
251240 let quorum_hash = [ 0u8 ; 32 ] ;
252241 let mut tiny_buffer = [ 0u8 ; 1 ] ; // Way too small
253-
242+
254243 let result = ffi_dash_spv_get_quorum_public_key (
255244 ptr:: null_mut ( ) ,
256245 0 ,
@@ -259,7 +248,7 @@ fn test_memory_safety_patterns() {
259248 tiny_buffer. as_mut_ptr ( ) ,
260249 tiny_buffer. len ( ) , // Correctly report size
261250 ) ;
262-
251+
263252 // Should fail safely without buffer overflow
264253 assert_ne ! ( result. error_code, 0 ) ;
265254 }
@@ -270,34 +259,28 @@ fn test_memory_safety_patterns() {
270259fn test_error_propagation_thread_local ( ) {
271260 unsafe {
272261 // Test that errors are properly stored in thread-local storage
273-
262+
274263 // Clear any previous error
275264 dash_spv_ffi_clear_error ( ) ;
276-
265+
277266 // Trigger an error
278- let result = ffi_dash_spv_get_platform_activation_height (
279- ptr:: null_mut ( ) ,
280- ptr:: null_mut ( ) ,
281- ) ;
267+ let result = ffi_dash_spv_get_platform_activation_height ( ptr:: null_mut ( ) , ptr:: null_mut ( ) ) ;
282268 assert_ne ! ( result. error_code, 0 ) ;
283-
269+
284270 // Get the error message
285271 let error = dash_spv_ffi_get_last_error ( ) ;
286272 assert ! ( !error. is_null( ) , "Should have error message" ) ;
287-
273+
288274 if !error. is_null ( ) {
289275 let error_str = CStr :: from_ptr ( error) ;
290276 let error_string = error_str. to_string_lossy ( ) ;
291-
277+
292278 // Verify error message is meaningful
293- assert ! (
294- !error_string. is_empty( ) ,
295- "Error message should not be empty"
296- ) ;
297-
279+ assert ! ( !error_string. is_empty( ) , "Error message should not be empty" ) ;
280+
298281 // Note: Error strings are managed internally
299282 }
300-
283+
301284 // Verify error handling after retrieval
302285 dash_spv_ffi_clear_error ( ) ;
303286 let second_error = dash_spv_ffi_get_last_error ( ) ;
@@ -311,7 +294,7 @@ fn test_error_propagation_thread_local() {
311294fn test_boundary_conditions ( ) {
312295 unsafe {
313296 // Test various boundary conditions
314-
297+
315298 // Test 1: Zero-length buffer
316299 let quorum_hash = [ 0u8 ; 32 ] ;
317300 let result = ffi_dash_spv_get_quorum_public_key (
@@ -323,13 +306,13 @@ fn test_boundary_conditions() {
323306 0 , // Zero length
324307 ) ;
325308 assert_ne ! ( result. error_code, 0 ) ;
326-
309+
327310 // Test 2: Maximum values
328311 let result = ffi_dash_spv_get_quorum_public_key (
329312 ptr:: null_mut ( ) ,
330313 u32:: MAX , // Max quorum type
331314 quorum_hash. as_ptr ( ) ,
332- u32:: MAX , // Max height
315+ u32:: MAX , // Max height
333316 ptr:: null_mut ( ) ,
334317 0 ,
335318 ) ;
@@ -344,25 +327,22 @@ fn test_error_string_lifecycle() {
344327 unsafe {
345328 // Clear errors first
346329 dash_spv_ffi_clear_error ( ) ;
347-
330+
348331 // Trigger an error to generate an error string
349- let _ = ffi_dash_spv_get_platform_activation_height (
350- ptr:: null_mut ( ) ,
351- ptr:: null_mut ( ) ,
352- ) ;
353-
332+ let _ = ffi_dash_spv_get_platform_activation_height ( ptr:: null_mut ( ) , ptr:: null_mut ( ) ) ;
333+
354334 let error = dash_spv_ffi_get_last_error ( ) ;
355335 if !error. is_null ( ) {
356336 // Verify we can read the string
357337 let error_cstr = CStr :: from_ptr ( error) ;
358338 let error_string = error_cstr. to_string_lossy ( ) ;
359339 assert ! ( !error_string. is_empty( ) ) ;
360-
340+
361341 // The error string is managed internally and should not be freed by the caller
362342 // Multiple calls should return the same pointer until cleared
363343 let error2 = dash_spv_ffi_get_last_error ( ) ;
364344 assert_eq ! ( error, error2, "Should return same error pointer" ) ;
365-
345+
366346 // Clear and verify it's gone
367347 dash_spv_ffi_clear_error ( ) ;
368348 let error3 = dash_spv_ffi_get_last_error ( ) ;
@@ -378,16 +358,16 @@ fn test_handle_lifecycle() {
378358 unsafe {
379359 // Test null handle operations
380360 let null_handle = ptr:: null_mut ( ) ;
381-
361+
382362 // Getting core handle from null client
383363 let handle = ffi_dash_spv_get_core_handle ( null_handle) ;
384364 assert ! ( handle. is_null( ) ) ;
385-
365+
386366 // Releasing null handle should be safe
387367 ffi_dash_spv_release_core_handle ( null_handle) ;
388-
368+
389369 // Multiple releases of null should be safe
390370 ffi_dash_spv_release_core_handle ( null_handle) ;
391371 ffi_dash_spv_release_core_handle ( null_handle) ;
392372 }
393- }
373+ }
0 commit comments