@@ -192,14 +192,15 @@ impl StringOp {
192
192
let _ = re_string. pop ( ) ;
193
193
}
194
194
re_string. push ( curr) ;
195
- } else if is_valid_range_quantifier ( & pattern_chars) {
195
+ } else {
196
+ // Check if the following section is a valid range quantifier
197
+ verify_range_quantifier ( & pattern_chars) ?;
198
+
196
199
re_string. push ( curr) ;
197
200
// Set the lower bound of range quantifier to 0 if it is missing
198
201
if pattern_chars. peek ( ) == Some ( & ',' ) {
199
202
re_string. push ( '0' ) ;
200
203
}
201
- } else {
202
- return Err ( ExprError :: InvalidBracketContent ) ;
203
204
}
204
205
}
205
206
_ => re_string. push ( curr) ,
@@ -222,7 +223,7 @@ impl StringOp {
222
223
// "invalid repeat range {lower,upper}"
223
224
-123 => ExprError :: InvalidBracketContent ,
224
225
// "too big number for repeat range"
225
- -201 => ExprError :: InvalidBracketContent ,
226
+ -201 => ExprError :: TooBigRangeQuantifierIndex ,
226
227
_ => ExprError :: InvalidRegexExpression ,
227
228
} ) ?;
228
229
@@ -277,23 +278,27 @@ where
277
278
/// - `r"\{,6\}"`
278
279
/// - `r"\{3,6\}"`
279
280
/// - `r"\{,\}"`
280
- fn is_valid_range_quantifier < I > ( pattern_chars : & I ) -> bool
281
+ fn verify_range_quantifier < I > ( pattern_chars : & I ) -> Result < ( ) , ExprError >
281
282
where
282
283
I : Iterator < Item = char > + Clone ,
283
284
{
284
285
// Parse the string between braces
285
286
let mut quantifier = String :: new ( ) ;
286
287
let mut pattern_chars_clone = pattern_chars. clone ( ) . peekable ( ) ;
287
288
let Some ( mut prev) = pattern_chars_clone. next ( ) else {
288
- return false ;
289
+ return Err ( ExprError :: UnmatchedOpeningBrace ) ;
289
290
} ;
291
+ if pattern_chars_clone. peek ( ) . is_none ( ) {
292
+ return Err ( ExprError :: UnmatchedOpeningBrace ) ;
293
+ }
294
+
290
295
let mut prev_is_escaped = false ;
291
296
while let Some ( curr) = pattern_chars_clone. next ( ) {
292
297
if prev == '\\' && curr == '}' && !prev_is_escaped {
293
298
break ;
294
299
}
295
300
if pattern_chars_clone. peek ( ) . is_none ( ) {
296
- return false ;
301
+ return Err ( ExprError :: UnmatchedOpeningBrace ) ;
297
302
}
298
303
299
304
quantifier. push ( prev) ;
@@ -302,19 +307,32 @@ where
302
307
}
303
308
304
309
// Check if parsed quantifier is valid
305
- let is_valid_range_index = |s : & str | s. parse :: < i32 > ( ) . map_or ( true , |x| x <= i16:: MAX as i32 ) ;
306
310
let re = Regex :: new ( r"^(\d*,\d*|\d+)" ) . expect ( "valid regular expression" ) ;
307
311
if let Some ( captures) = re. captures ( & quantifier) {
308
312
let matched = captures. at ( 0 ) . unwrap_or_default ( ) ;
309
313
match matched. split_once ( ',' ) {
310
- None => is_valid_range_index ( matched) ,
311
- Some ( ( "" , "" ) ) => true ,
312
- Some ( ( x, "" ) ) => is_valid_range_index ( x) ,
313
- Some ( ( "" , x) ) => is_valid_range_index ( x) ,
314
- Some ( ( f, l) ) => f <= l && is_valid_range_index ( f) && is_valid_range_index ( l) ,
314
+ Some ( ( "" , "" ) ) => Ok ( ( ) ) ,
315
+ Some ( ( x, "" ) ) | Some ( ( "" , x) ) => match x. parse :: < i32 > ( ) {
316
+ Ok ( x) if x <= i16:: MAX . into ( ) => Ok ( ( ) ) ,
317
+ Ok ( _) => Err ( ExprError :: TooBigRangeQuantifierIndex ) ,
318
+ Err ( _) => Err ( ExprError :: InvalidBracketContent ) ,
319
+ } ,
320
+ Some ( ( f, l) ) => match ( f. parse :: < i32 > ( ) , l. parse :: < i32 > ( ) ) {
321
+ ( Ok ( f) , Ok ( l) ) if f > l => Err ( ExprError :: InvalidBracketContent ) ,
322
+ ( Ok ( f) , Ok ( l) ) if f > i16:: MAX . into ( ) || l > i16:: MAX . into ( ) => {
323
+ Err ( ExprError :: TooBigRangeQuantifierIndex )
324
+ }
325
+ ( Ok ( _) , Ok ( _) ) => Ok ( ( ) ) ,
326
+ _ => Err ( ExprError :: InvalidBracketContent ) ,
327
+ } ,
328
+ None => match matched. parse :: < i32 > ( ) {
329
+ Ok ( x) if x <= i16:: MAX . into ( ) => Ok ( ( ) ) ,
330
+ Ok ( _) => Err ( ExprError :: TooBigRangeQuantifierIndex ) ,
331
+ Err ( _) => Err ( ExprError :: InvalidBracketContent ) ,
332
+ } ,
315
333
}
316
334
} else {
317
- false
335
+ Err ( ExprError :: InvalidBracketContent )
318
336
}
319
337
}
320
338
@@ -789,7 +807,7 @@ pub fn is_truthy(s: &NumOrStr) -> bool {
789
807
#[ cfg( test) ]
790
808
mod test {
791
809
use crate :: ExprError ;
792
- use crate :: syntax_tree:: is_valid_range_quantifier ;
810
+ use crate :: syntax_tree:: verify_range_quantifier ;
793
811
794
812
use super :: {
795
813
AstNode , AstNodeInner , BinOp , NumericOp , RelationOp , StringOp , check_posix_regex_errors,
@@ -999,19 +1017,47 @@ mod test {
999
1017
1000
1018
#[ test]
1001
1019
fn test_is_valid_range_quantifier ( ) {
1002
- assert ! ( is_valid_range_quantifier( & "3\\ }" . chars( ) ) ) ;
1003
- assert ! ( is_valid_range_quantifier( & "3,\\ }" . chars( ) ) ) ;
1004
- assert ! ( is_valid_range_quantifier( & ",6\\ }" . chars( ) ) ) ;
1005
- assert ! ( is_valid_range_quantifier( & "3,6\\ }" . chars( ) ) ) ;
1006
- assert ! ( is_valid_range_quantifier( & ",\\ }" . chars( ) ) ) ;
1007
- assert ! ( is_valid_range_quantifier( & "3,6\\ }anything" . chars( ) ) ) ;
1008
- assert ! ( !is_valid_range_quantifier( & "\\ {3,6\\ }" . chars( ) ) ) ;
1009
- assert ! ( !is_valid_range_quantifier( & "\\ }" . chars( ) ) ) ;
1010
- assert ! ( !is_valid_range_quantifier( & "" . chars( ) ) ) ;
1011
- assert ! ( !is_valid_range_quantifier( & "3" . chars( ) ) ) ;
1012
- assert ! ( !is_valid_range_quantifier( & "3," . chars( ) ) ) ;
1013
- assert ! ( !is_valid_range_quantifier( & ",6" . chars( ) ) ) ;
1014
- assert ! ( !is_valid_range_quantifier( & "3,6" . chars( ) ) ) ;
1015
- assert ! ( !is_valid_range_quantifier( & "," . chars( ) ) ) ;
1020
+ assert ! ( verify_range_quantifier( & "3\\ }" . chars( ) ) . is_ok( ) ) ;
1021
+ assert ! ( verify_range_quantifier( & "3,\\ }" . chars( ) ) . is_ok( ) ) ;
1022
+ assert ! ( verify_range_quantifier( & ",6\\ }" . chars( ) ) . is_ok( ) ) ;
1023
+ assert ! ( verify_range_quantifier( & "3,6\\ }" . chars( ) ) . is_ok( ) ) ;
1024
+ assert ! ( verify_range_quantifier( & ",\\ }" . chars( ) ) . is_ok( ) ) ;
1025
+ assert ! ( verify_range_quantifier( & "32767\\ }anything" . chars( ) ) . is_ok( ) ) ;
1026
+ assert_eq ! (
1027
+ verify_range_quantifier( & "\\ {3,6\\ }" . chars( ) ) ,
1028
+ Err ( ExprError :: InvalidBracketContent )
1029
+ ) ;
1030
+ assert_eq ! (
1031
+ verify_range_quantifier( & "\\ }" . chars( ) ) ,
1032
+ Err ( ExprError :: InvalidBracketContent )
1033
+ ) ;
1034
+ assert_eq ! (
1035
+ verify_range_quantifier( & "" . chars( ) ) ,
1036
+ Err ( ExprError :: UnmatchedOpeningBrace )
1037
+ ) ;
1038
+ assert_eq ! (
1039
+ verify_range_quantifier( & "3" . chars( ) ) ,
1040
+ Err ( ExprError :: UnmatchedOpeningBrace )
1041
+ ) ;
1042
+ assert_eq ! (
1043
+ verify_range_quantifier( & "3," . chars( ) ) ,
1044
+ Err ( ExprError :: UnmatchedOpeningBrace )
1045
+ ) ;
1046
+ assert_eq ! (
1047
+ verify_range_quantifier( & ",6" . chars( ) ) ,
1048
+ Err ( ExprError :: UnmatchedOpeningBrace )
1049
+ ) ;
1050
+ assert_eq ! (
1051
+ verify_range_quantifier( & "3,6" . chars( ) ) ,
1052
+ Err ( ExprError :: UnmatchedOpeningBrace )
1053
+ ) ;
1054
+ assert_eq ! (
1055
+ verify_range_quantifier( & "," . chars( ) ) ,
1056
+ Err ( ExprError :: UnmatchedOpeningBrace )
1057
+ ) ;
1058
+ assert_eq ! (
1059
+ verify_range_quantifier( & "32768\\ }" . chars( ) ) ,
1060
+ Err ( ExprError :: TooBigRangeQuantifierIndex )
1061
+ ) ;
1016
1062
}
1017
1063
}
0 commit comments