@@ -64,6 +64,9 @@ pub enum DetectUintIndex {
6464pub struct DetectUintArrayData < T > {
6565 pub du : DetectUintData < T > ,
6666 pub index : DetectUintIndex ,
67+ // subslice
68+ pub start : i32 ,
69+ pub end : i32 ,
6770}
6871
6972fn parse_uint_index_precise ( s : & str ) -> IResult < & str , DetectUintIndex > {
@@ -85,8 +88,29 @@ fn parse_uint_index_val(s: &str) -> Option<DetectUintIndex> {
8588 Some ( arg1)
8689}
8790
91+ fn parse_uint_subslice_aux ( s : & str ) -> IResult < & str , ( i32 , i32 ) > {
92+ let ( s, start) = nom_i32 ( s) ?;
93+ let ( s, _) = char ( ':' ) ( s) ?;
94+ let ( s, end) = nom_i32 ( s) ?;
95+ return Ok ( ( s, ( start, end) ) ) ;
96+ }
97+
98+ fn parse_uint_subslice ( parts : & [ & str ] ) -> Option < ( i32 , i32 ) > {
99+ if parts. len ( ) < 3 {
100+ return Some ( ( 0 , 0 ) ) ;
101+ }
102+ let ( _, ( start, end) ) = parse_uint_subslice_aux ( parts[ 2 ] ) . ok ( ) ?;
103+ if start > 0 && end > 0 && end <= start {
104+ return None ;
105+ }
106+ if start < 0 && end < 0 && end <= start {
107+ return None ;
108+ }
109+ return Some ( ( start, end) ) ;
110+ }
111+
88112fn parse_uint_index ( parts : & [ & str ] ) -> Option < DetectUintIndex > {
89- let index = if parts. len ( ) = = 2 {
113+ let index = if parts. len ( ) > = 2 {
90114 match parts[ 1 ] {
91115 "all" => DetectUintIndex :: All ,
92116 "all1" => DetectUintIndex :: All1 ,
@@ -103,36 +127,63 @@ fn parse_uint_index(parts: &[&str]) -> Option<DetectUintIndex> {
103127
104128pub ( crate ) fn detect_parse_array_uint < T : DetectIntType > ( s : & str ) -> Option < DetectUintArrayData < T > > {
105129 let parts: Vec < & str > = s. split ( ',' ) . collect ( ) ;
106- if parts. len ( ) > 2 {
130+ if parts. len ( ) > 3 {
107131 return None ;
108132 }
109133
110134 let index = parse_uint_index ( & parts) ?;
111135 let ( _, du) = detect_parse_uint :: < T > ( parts[ 0 ] ) . ok ( ) ?;
136+ let ( start, end) = parse_uint_subslice ( & parts) ?;
112137
113- Some ( DetectUintArrayData { du, index } )
138+ Some ( DetectUintArrayData {
139+ du,
140+ index,
141+ start,
142+ end,
143+ } )
114144}
115145
116146pub ( crate ) fn detect_parse_array_uint_enum < T1 : DetectIntType , T2 : EnumString < T1 > > (
117147 s : & str ,
118148) -> Option < DetectUintArrayData < T1 > > {
119149 let parts: Vec < & str > = s. split ( ',' ) . collect ( ) ;
120- if parts. len ( ) > 2 {
150+ if parts. len ( ) > 3 {
121151 return None ;
122152 }
123153
124154 let index = parse_uint_index ( & parts) ?;
125155 let du = detect_parse_uint_enum :: < T1 , T2 > ( parts[ 0 ] ) ?;
156+ let ( start, end) = parse_uint_subslice ( & parts) ?;
126157
127- Some ( DetectUintArrayData { du, index } )
158+ Some ( DetectUintArrayData {
159+ du,
160+ index,
161+ start,
162+ end,
163+ } )
128164}
129165
130166pub ( crate ) fn detect_uint_match_at_index < T , U : DetectIntType > (
131167 array : & [ T ] , ctx : & DetectUintArrayData < U > , get_value : impl Fn ( & T ) -> Option < U > , eof : bool ,
132168) -> c_int {
169+ let start = if ctx. start >= 0 {
170+ ctx. start as usize
171+ } else {
172+ ( ( array. len ( ) as i32 ) + ctx. start ) as usize
173+ } ;
174+ let end = if ctx. end > 0 {
175+ ctx. end as usize
176+ } else {
177+ ( ( array. len ( ) as i32 ) + ctx. end ) as usize
178+ } ;
179+ let subslice = if end > array. len ( ) || start >= end {
180+ & array[ ..0 ]
181+ } else {
182+ & array[ start..end]
183+ } ;
133184 match & ctx. index {
134185 DetectUintIndex :: Any => {
135- for response in array {
186+ for response in subslice {
136187 if let Some ( code) = get_value ( response) {
137188 if detect_match_uint :: < U > ( & ctx. du , code) {
138189 return 1 ;
@@ -143,7 +194,7 @@ pub(crate) fn detect_uint_match_at_index<T, U: DetectIntType>(
143194 }
144195 DetectUintIndex :: OrAbsent => {
145196 let mut has_elem = false ;
146- for response in array {
197+ for response in subslice {
147198 if let Some ( code) = get_value ( response) {
148199 if detect_match_uint :: < U > ( & ctx. du , code) {
149200 return 1 ;
@@ -166,7 +217,7 @@ pub(crate) fn detect_uint_match_at_index<T, U: DetectIntType>(
166217 }
167218 }
168219 let mut nb = 0u32 ;
169- for response in array {
220+ for response in subslice {
170221 if let Some ( code) = get_value ( response) {
171222 if detect_match_uint :: < U > ( & ctx. du , code) {
172223 nb += 1 ;
@@ -182,7 +233,7 @@ pub(crate) fn detect_uint_match_at_index<T, U: DetectIntType>(
182233 if !eof {
183234 return 0 ;
184235 }
185- for response in array {
236+ for response in subslice {
186237 if let Some ( code) = get_value ( response) {
187238 if !detect_match_uint :: < U > ( & ctx. du , code) {
188239 return 0 ;
@@ -196,7 +247,7 @@ pub(crate) fn detect_uint_match_at_index<T, U: DetectIntType>(
196247 return 0 ;
197248 }
198249 let mut has_elem = false ;
199- for response in array {
250+ for response in subslice {
200251 if let Some ( code) = get_value ( response) {
201252 if !detect_match_uint :: < U > ( & ctx. du , code) {
202253 return 0 ;
@@ -212,17 +263,17 @@ pub(crate) fn detect_uint_match_at_index<T, U: DetectIntType>(
212263 DetectUintIndex :: Index ( ( oob, idx) ) => {
213264 let index = if * idx < 0 {
214265 // negative values for backward indexing.
215- ( ( array . len ( ) as i32 ) + idx) as usize
266+ ( ( subslice . len ( ) as i32 ) + idx) as usize
216267 } else {
217268 * idx as usize
218269 } ;
219- if array . len ( ) <= index {
270+ if subslice . len ( ) <= index {
220271 if * oob && eof {
221272 return 1 ;
222273 }
223274 return 0 ;
224275 }
225- if let Some ( code) = get_value ( & array [ index] ) {
276+ if let Some ( code) = get_value ( & subslice [ index] ) {
226277 return detect_match_uint :: < U > ( & ctx. du , code) as c_int ;
227278 }
228279 return 0 ;
0 commit comments