@ -47,11 +47,22 @@ pub struct SCDetectTransformFromBase64Data {
offset : u32 ,
offset_str : * const c_char ,
mode : SCBase64Mode ,
// serialized data for hashing
serialized : * const u8 ,
serialized_len : u32 ,
}
impl Drop for SCDetectTransformFromBase64Data {
fn drop ( & mut self ) {
unsafe {
if ! self . serialized . is_null ( ) {
drop ( Vec ::from_raw_parts (
self . serialized as * mut u8 ,
self . serialized_len as usize ,
self . serialized_len as usize ,
) ) ;
}
if ! self . offset_str . is_null ( ) {
let _ = CString ::from_raw ( self . offset_str as * mut c_char ) ;
}
@ -70,6 +81,8 @@ impl Default for SCDetectTransformFromBase64Data {
offset : 0 ,
offset_str : std ::ptr ::null_mut ( ) ,
mode : TRANSFORM_FROM_BASE64_MODE_DEFAULT ,
serialized : std ::ptr ::null_mut ( ) ,
serialized_len : 0 ,
}
}
}
@ -80,6 +93,22 @@ impl SCDetectTransformFromBase64Data {
.. Default ::default ( )
}
}
pub fn serialize ( & mut self , nbytes : & str , offset : & str ) {
let mut r = Vec ::with_capacity ( 12 + nbytes . len ( ) + offset . len ( ) ) ;
r . push ( self . flags ) ;
r . push ( self . mode as u8 ) ;
r . extend_from_slice ( & self . nbytes . to_le_bytes ( ) ) ;
r . extend_from_slice ( & self . offset . to_le_bytes ( ) ) ;
r . push ( nbytes . len ( ) as u8 ) ;
r . extend_from_slice ( nbytes . as_bytes ( ) ) ;
r . push ( offset . len ( ) as u8 ) ;
r . extend_from_slice ( offset . as_bytes ( ) ) ;
self . serialized_len = r . len ( ) as u32 ;
let ptr = r . as_mut_ptr ( ) ;
std ::mem ::forget ( r ) ;
self . serialized = ptr ;
}
}
fn get_mode_value ( value : & str ) -> Option < SCBase64Mode > {
@ -117,6 +146,8 @@ fn parse_transform_base64(
DETECT_TRANSFORM_BASE64_MAX_PARAM_COUNT , input ) ) ) ;
}
let mut nbytes_str = String ::new ( ) ;
let mut offset_str = String ::new ( ) ;
for value in values {
let ( mut val , mut name ) = take_until_whitespace ( value ) ? ;
val = val . trim ( ) ;
@ -152,17 +183,10 @@ fn parse_transform_base64(
) ) ) ;
}
}
ResultValue ::String ( val ) = > match CString ::new ( val ) {
Ok ( newval ) = > {
transform_base64 . offset_str = newval . into_raw ( ) ;
transform_base64 . flags | = DETECT_TRANSFORM_BASE64_FLAG_OFFSET_VAR ;
}
_ = > {
return Err ( make_error (
"parse string not safely convertible to C" . to_string ( ) ,
) )
}
} ,
ResultValue ::String ( val ) = > {
offset_str = val . clone ( ) ;
transform_base64 . flags | = DETECT_TRANSFORM_BASE64_FLAG_OFFSET_VAR ;
}
}
transform_base64 . flags | = DETECT_TRANSFORM_BASE64_FLAG_OFFSET ;
@ -186,17 +210,10 @@ fn parse_transform_base64(
) ) ) ;
}
}
ResultValue ::String ( val ) = > match CString ::new ( val ) {
Ok ( newval ) = > {
transform_base64 . nbytes_str = newval . into_raw ( ) ;
transform_base64 . flags | = DETECT_TRANSFORM_BASE64_FLAG_NBYTES_VAR ;
}
_ = > {
return Err ( make_error (
"parse string not safely convertible to C" . to_string ( ) ,
) )
}
} ,
ResultValue ::String ( val ) = > {
nbytes_str = val . clone ( ) ;
transform_base64 . flags | = DETECT_TRANSFORM_BASE64_FLAG_NBYTES_VAR ;
}
}
transform_base64 . flags | = DETECT_TRANSFORM_BASE64_FLAG_NBYTES ;
}
@ -206,6 +223,25 @@ fn parse_transform_base64(
} ;
}
transform_base64 . serialize ( & nbytes_str , & offset_str ) ;
if ( transform_base64 . flags & DETECT_TRANSFORM_BASE64_FLAG_NBYTES_VAR ) ! = 0 {
if let Ok ( newval ) = CString ::new ( nbytes_str ) {
transform_base64 . nbytes_str = newval . into_raw ( ) ;
} else {
return Err ( make_error (
"parse string not safely convertible to C" . to_string ( ) ,
) ) ;
}
}
if ( transform_base64 . flags & DETECT_TRANSFORM_BASE64_FLAG_OFFSET_VAR ) ! = 0 {
if let Ok ( newval ) = CString ::new ( offset_str ) {
transform_base64 . offset_str = newval . into_raw ( ) ;
} else {
return Err ( make_error (
"parse string not safely convertible to C" . to_string ( ) ,
) ) ;
}
}
Ok ( ( input , transform_base64 ) )
}
@ -283,6 +319,8 @@ mod tests {
std ::ptr ::null_mut ( )
} ,
mode ,
serialized : std ::ptr ::null_mut ( ) ,
serialized_len : 0 ,
} ;
let ( _ , val ) = parse_transform_base64 ( args ) . unwrap ( ) ;