Skip to content

Commit df38a12

Browse files
committed
Swift: Complete the escape sequences fix.
1 parent 39302c6 commit df38a12

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

swift/ql/lib/codeql/swift/regex/RegexTreeView.qll

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -610,15 +610,22 @@ private module Impl implements RegexTreeViewSig {
610610
/**
611611
* Holds if this is a unicode escape.
612612
*/
613-
private predicate isUnicode() { this.getText().prefix(2) = ["\\u", "\\U"] }
613+
private predicate isUnicode() { this.getText().prefix(2) = ["\\u", "\\U", "\\x"] }
614614

615615
/**
616616
* Gets the unicode char for this escape.
617617
* E.g. for `\u0061` this returns "a".
618618
*/
619-
private string getUnicode() {
619+
private string getUnicode() { result = parseHexInt(this.getHexString()).toUnicode() }
620+
621+
/**
622+
* Gets the part of this escape that is a hexidecimal string.
623+
*/
624+
private string getHexString() {
620625
this.isUnicode() and
621-
result = parseHexInt(this.getText().suffix(2)).toUnicode()
626+
if this.getText().matches(["\\x{%", "\\u{%"]) // \x{hh...} or \u{hh...}
627+
then result = this.getText().substring(3, this.getText().length() - 1)
628+
else result = this.getText().suffix(2) // \xhh or \uhhhh or \Uhhhhhhhh
622629
}
623630
}
624631

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -507,16 +507,16 @@ func myRegexpVariantsTests(myUrl: URL) throws {
507507
// GOOD
508508
_ = try Regex(#"X(\U00000061|b)+Y"#).firstMatch(in: tainted)
509509

510-
// BAD TODO: we should get this one
510+
// BAD
511511
// attack string: "X" + "a" x lots
512-
_ = try Regex(#"X(\x61|a)*Y"#).firstMatch(in: tainted) // $ MISSING: redos-vulnerable=
512+
_ = try Regex(#"X(\x61|a)*Y"#).firstMatch(in: tainted) // $ redos-vulnerable=
513513

514514
// GOOD
515515
_ = try Regex(#"X(\x61|b)+Y"#).firstMatch(in: tainted)
516516

517-
// BAD TODO: we should get this one
517+
// BAD
518518
// attack string: "X" + "a" x lots
519-
_ = try Regex(#"X(\x{061}|a)*Y"#).firstMatch(in: tainted) // $ MISSING: redos-vulnerable=
519+
_ = try Regex(#"X(\x{061}|a)*Y"#).firstMatch(in: tainted) // $ redos-vulnerable=
520520

521521
// GOOD
522522
_ = try Regex(#"X(\x{061}|b)+Y"#).firstMatch(in: tainted)

0 commit comments

Comments
 (0)