@ -65,6 +65,61 @@ describe("parseTextToArray", () => {
expect ( result . error ) . toBeTruthy ( ) ;
} ) ;
it ( "rejects nested quantifier patterns (ReDoS)" , ( ) = > {
const dangerousPatterns = [ "(a+)+" , "(a*)*" , "(a+)*" , "/(a+)+/g" , "(x*)+" ] ;
for ( const pattern of dangerousPatterns ) {
const result = parseTextToArray ( "test" , {
splitMode : "regex" ,
delimiter : "*" ,
regexPattern : pattern ,
trimItems : true ,
removeEmpty : true ,
} ) ;
expect ( result . items ) . toEqual ( [ ] ) ;
expect ( result . error ) . toContain ( "nested quantifiers" ) ;
}
} ) ;
it ( "allows safe regex patterns" , ( ) = > {
const safePatterns = [ "\\d+" , "[,;]+" , "\\s+" , "(a|b)" ] ;
for ( const pattern of safePatterns ) {
const result = parseTextToArray ( "a1b2c" , {
splitMode : "regex" ,
delimiter : "*" ,
regexPattern : pattern ,
trimItems : true ,
removeEmpty : true ,
} ) ;
expect ( result . error ) . toBeNull ( ) ;
expect ( result . items . length ) . toBeGreaterThan ( 0 ) ;
}
} ) ;
it ( "rejects input exceeding max length in regex mode" , ( ) = > {
const longInput = "a" . repeat ( 100 _001 ) ;
const result = parseTextToArray ( longInput , {
splitMode : "regex" ,
delimiter : "*" ,
regexPattern : "\\d" ,
trimItems : false ,
removeEmpty : false ,
} ) ;
expect ( result . items ) . toEqual ( [ ] ) ;
expect ( result . error ) . toContain ( "Input too long" ) ;
} ) ;
it ( "allows input at max length in regex mode" , ( ) = > {
const input = "a" . repeat ( 100 _000 ) ;
const result = parseTextToArray ( input , {
splitMode : "regex" ,
delimiter : "*" ,
regexPattern : "\\d" ,
trimItems : false ,
removeEmpty : false ,
} ) ;
expect ( result . error ) . toBeNull ( ) ;
} ) ;
it ( "returns error when regex pattern is too long" , ( ) = > {
const result = parseTextToArray ( "a,b,c" , {
splitMode : "regex" ,