use chrono::Utc;
use stix_rs::objects::Indicator;
use stix_rs::pattern::{validate_pattern, PatternBuilder};
use stix_rs::vocab::IndicatorPatternType;
#[test]
fn test_indicator_with_pattern_validation() {
let indicator = Indicator::builder()
.name("File Hash Indicator")
.pattern("[file:hashes.MD5 = 'abc123']")
.pattern_type(IndicatorPatternType::Stix)
.valid_from(Utc::now())
.validate_pattern(true) .build()
.unwrap();
assert!(indicator.validate_pattern().is_ok());
}
#[test]
fn test_invalid_pattern_rejected() {
let result = Indicator::builder()
.name("Bad Indicator")
.pattern("file:hashes.MD5 = 'abc123'") .pattern_type(IndicatorPatternType::Stix)
.valid_from(Utc::now())
.validate_pattern(true)
.build();
assert!(result.is_err());
}
#[test]
fn test_pattern_builder() {
let pattern = PatternBuilder::new()
.compare("file", "hashes.MD5", "=", "'abc123'")
.and()
.compare("file", "size", ">", "1000")
.build();
assert!(validate_pattern(&pattern).is_ok());
let indicator = Indicator::builder()
.name("Complex File Indicator")
.pattern(&pattern)
.pattern_type(IndicatorPatternType::Stix)
.valid_from(Utc::now())
.build()
.unwrap();
assert!(indicator.validate_pattern().is_ok());
}
#[test]
fn test_various_valid_patterns() {
let patterns = vec![
"[ipv4-addr:value = '192.168.1.1']",
"[domain-name:value = 'evil.com']",
"[url:value = 'https://malicious.com/payload']",
"[email-addr:value = 'attacker@evil.com']",
"[network-traffic:src_port = 443]",
"[process:name = 'malware.exe']",
"[x509-certificate:hashes.SHA-256 = 'abc...']",
"[file:name = 'bad.exe' AND file:size > 1000]",
"[ipv4-addr:value = '10.0.0.1' OR ipv4-addr:value = '10.0.0.2']",
];
for pattern in patterns {
assert!(
validate_pattern(pattern).is_ok(),
"Pattern should be valid: {}",
pattern
);
}
}
#[test]
fn test_non_stix_patterns_not_validated() {
let indicator = Indicator::builder()
.name("PCRE Indicator")
.pattern("^malware.*\\.exe$")
.pattern_type(IndicatorPatternType::Pcre)
.valid_from(Utc::now())
.validate_pattern(true) .build()
.unwrap();
assert!(indicator.validate_pattern().is_ok());
}