@ -57,6 +57,9 @@ enum RequiresError {
/// Passed in requirements not a valid UTF-8 string.
Utf8Error ,
/// An unknown requirement was provided.
UnknownRequirement ( String ) ,
}
impl RequiresError {
@ -70,6 +73,7 @@ impl RequiresError {
Self ::BadRequires = > "Failed to parse requires expression\0" ,
Self ::MultipleVersions = > "Version may only be specified once\0" ,
Self ::Utf8Error = > "Requires expression is not valid UTF-8\0" ,
Self ::UnknownRequirement ( _ ) = > "Unknown requirements\0" ,
} ;
msg . as_ptr ( ) as * const c_char
}
@ -169,6 +173,9 @@ struct Requires {
/// - All of the inner most must evaluate to true.
/// - To pass, any of the outer must be true.
pub version : Vec < Vec < RuleRequireVersion > > ,
/// Unknown parameters to requires.
pub unknown : Vec < String > ,
}
fn parse_op ( input : & str ) -> IResult < & str , VersionCompareOp > {
@ -242,6 +249,7 @@ fn parse_requires(mut input: &str) -> Result<Requires, RequiresError> {
// Unknown keyword, allow by warn in case we extend
// this in the future.
SCLogWarning ! ( "Unknown requires keyword: {}" , keyword ) ;
requires . unknown . push ( format! ( "{} {}" , keyword , value ) ) ;
}
}
@ -291,6 +299,12 @@ fn check_version(
fn check_requires (
requires : & Requires , suricata_version : & SuricataVersion ,
) -> Result < ( ) , RequiresError > {
if ! requires . unknown . is_empty ( ) {
return Err ( RequiresError ::UnknownRequirement (
requires . unknown . join ( "," ) ,
) ) ;
}
if ! requires . version . is_empty ( ) {
let mut errs = VecDeque ::new ( ) ;
let mut ok = 0 ;
@ -594,6 +608,7 @@ mod test {
patch : 0 ,
}
} ] ] ,
unknown : vec ! [ ] ,
}
) ;
@ -610,6 +625,7 @@ mod test {
patch : 0 ,
}
} ] ] ,
unknown : vec ! [ ] ,
}
) ;
@ -626,6 +642,7 @@ mod test {
patch : 2 ,
}
} ] ] ,
unknown : vec ! [ ] ,
}
) ;
@ -652,6 +669,7 @@ mod test {
}
}
] ] ,
unknown : vec ! [ ] ,
}
) ;
}
@ -748,11 +766,11 @@ mod test {
assert! ( check_requires ( & requires , & SuricataVersion ::new ( 9 , 0 , 0 ) ) . is_err ( ) ) ;
// Unknown keyword.
let requires = parse_requires ( "feature lua, foo bar, version >= 7.0.3") . unwrap ( ) ;
let requires = parse_requires ( "feature true_ lua, foo bar, version >= 7.0.3") . unwrap ( ) ;
assert_eq! (
requires ,
Requires {
features : vec ! [ " lua". to_string ( ) ] ,
features : vec ! [ " true_ lua". to_string ( ) ] ,
version : vec ! [ vec! [ RuleRequireVersion {
op : VersionCompareOp ::Gte ,
version : SuricataVersion {
@ -761,8 +779,14 @@ mod test {
patch : 3 ,
}
} ] ] ,
unknown : vec ! [ "foo bar" . to_string ( ) ] ,
}
) ;
// This should not pass the requires check as it contains an
// unknown requires keyword.
//check_requires(&requires, &SuricataVersion::new(8, 0, 0)).unwrap();
assert! ( check_requires ( & requires , & SuricataVersion ::new ( 8 , 0 , 0 ) ) . is_err ( ) ) ;
}
#[ test ]
@ -802,4 +826,10 @@ mod test {
]
) ;
}
#[ test ]
fn test_requires_keyword ( ) {
let requires = parse_requires ( "keyword true_bar" ) . unwrap ( ) ;
assert! ( check_requires ( & requires , & SuricataVersion ::new ( 8 , 0 , 0 ) ) . is_err ( ) ) ;
}
}