Skip to content

Commit 49dfe5d

Browse files
committed
Swift: Add support for \Uhhhhhhhh escaped characters in regular expressions.
1 parent 05939bd commit 49dfe5d

File tree

2 files changed

+9
-4
lines changed

2 files changed

+9
-4
lines changed

swift/ql/lib/codeql/swift/regex/internal/ParseRegex.qll

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,8 @@ abstract class RegExp extends Expr {
320320
* Matches named character properties. For example:
321321
* - `\p{Space}`
322322
* - `\P{Digit}` upper-case P means inverted
323-
* - `\p{^Word}` caret also means inverted
323+
* - `\p{^Word}` caret also means inverted (not supported in Swift `Regex` but it may be in
324+
* other regex parsers or in future versions of Swift).
324325
*
325326
* These can occur both inside and outside of character classes.
326327
*/
@@ -343,7 +344,8 @@ abstract class RegExp extends Expr {
343344
/**
344345
* Holds if the named character property is inverted. Examples for which it holds:
345346
* - `\P{Digit}` upper-case P means inverted
346-
* - `\p{^Word}` caret also means inverted
347+
* - `\p{^Word}` caret also means inverted (not supported in Swift `Regex` but it may be in
348+
* other regex parsers or in future versions of Swift).
347349
* - `[[:^digit:]]`
348350
*
349351
* Examples for which it doesn't hold:
@@ -381,8 +383,11 @@ abstract class RegExp extends Expr {
381383
// wide hex char \uhhhh
382384
this.getChar(start + 1) = "u" and end = start + 6
383385
or
386+
// wide hex char \Uhhhhhhhh
387+
this.getChar(start + 1) = "U" and end = start + 10
388+
or
384389
// escape not handled above; update when adding a new case
385-
not this.getChar(start + 1) in ["x", "u"] and
390+
not this.getChar(start + 1) in ["x", "u", "U"] and
386391
not exists(this.getChar(start + 1).toInt()) and
387392
end = start + 2
388393
)

swift/ql/test/library-tests/regex/redos_variants.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ func myRegexpVariantsTests(myUrl: URL) throws {
502502

503503
// BAD
504504
// attack string: "X" + "a" x lots
505-
_ = try Regex(#"X(\U00000061|a)*Y"#).firstMatch(in: tainted) // $ MISSING: redos-vulnerable=
505+
_ = try Regex(#"X(\U00000061|a)*Y"#).firstMatch(in: tainted) // $ redos-vulnerable=
506506

507507
// GOOD
508508
_ = try Regex(#"X(\U00000061|b)+Y"#).firstMatch(in: tainted)

0 commit comments

Comments
 (0)