Swift: Flag parse failures in the test.

This commit is contained in:
Geoffrey White
2023-06-13 00:00:49 +01:00
parent 44eb7bf642
commit 63ab4788e0
2 changed files with 19 additions and 9 deletions

View File

@@ -130,7 +130,7 @@ func myRegexpVariantsTests(myUrl: URL) throws {
_ = try Regex("(.|\\n)*!").firstMatch(in: tainted)
// NOT GOOD; attack: "\n".repeat(100) + "." TODO: investigate, we should be getting this one.
_ = try Regex("(?s)(.|\\n)*!").firstMatch(in: tainted) // $ MISSING: redos-vulnerable=
_ = try Regex("(?s)(.|\\n)*!").firstMatch(in: tainted) // $ hasParseFailure MISSING: redos-vulnerable=
// GOOD
_ = try Regex("([\\w.]+)*").firstMatch(in: tainted)
@@ -410,10 +410,10 @@ func myRegexpVariantsTests(myUrl: URL) throws {
_ = try Regex("X(\\x61|b)+Y").firstMatch(in: tainted)
// NOT GOOD TODO: we should get this one
_ = try Regex("X(\\x{061}|a)*Y").firstMatch(in: tainted) // $ MISSING: redos-vulnerable=
_ = try Regex("X(\\x{061}|a)*Y").firstMatch(in: tainted) // $ hasParseFailure= MISSING: redos-vulnerable=
// GOOD
_ = try Regex("X(\\x{061}|b)+Y").firstMatch(in: tainted)
_ = try Regex("X(\\x{061}|b)+Y").firstMatch(in: tainted) // $ hasParseFailure
// NOT GOOD
_ = try Regex("X(\\p{Digit}|7)*Y").firstMatch(in: tainted) // $ redos-vulnerable=
@@ -452,13 +452,13 @@ func myRegexpVariantsTests(myUrl: URL) throws {
_ = try Regex("\\b(\\d|0)*x").firstMatch(in: tainted) // $ redos-vulnerable=
// GOOD - possessive quantifiers don't backtrack
_ = try Regex("(a*+)*+b").firstMatch(in: tainted)
_ = try Regex("(a*)*+b").firstMatch(in: tainted)
_ = try Regex("(a*+)*b").firstMatch(in: tainted)
_ = try Regex("(a*+)*+b").firstMatch(in: tainted) // $ hasParseFailure
_ = try Regex("(a*)*+b").firstMatch(in: tainted) // $ hasParseFailure
_ = try Regex("(a*+)*b").firstMatch(in: tainted) // $ hasParseFailure
// BAD
_ = try Regex("(a*)*b").firstMatch(in: tainted) // $ redos-vulnerable=
// BAD - but not detected due to the way possessive quantifiers are approximated
_ = try Regex("((aa|a*+)b)*c").firstMatch(in: tainted) // $ MISSING: redos-vulnerable=
_ = try Regex("((aa|a*+)b)*c").firstMatch(in: tainted) // $ hasParseFailure MISSING: redos-vulnerable=
}

View File

@@ -1,5 +1,6 @@
import swift
import codeql.swift.regex.Regex
private import codeql.swift.regex.internal.ParseRegex
private import codeql.swift.regex.RegexTreeView::RegexTreeView as TreeView
import codeql.regex.nfa.ExponentialBackTracking::Make<TreeView>
import TestUtilities.InlineExpectationsTest
@@ -8,7 +9,7 @@ bindingset[s]
string quote(string s) { if s.matches("% %") then result = "\"" + s + "\"" else result = s }
module RegexTest implements TestSig {
string getARelevantTag() { result = ["regex", "input", "redos-vulnerable"] }
string getARelevantTag() { result = ["regex", "input", "redos-vulnerable", "hasParseFailure"] }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(TreeView::RegExpTerm t, string pump, State s, string prefixMsg |
@@ -18,6 +19,15 @@ module RegexTest implements TestSig {
tag = "redos-vulnerable" and
value = ""
)
or
exists(RegexEval eval, RegExp regex |
eval.getARegex() = regex and
regex.failedToParse(_) and
location = eval.getLocation() and
element = eval.toString() and
tag = "hasParseFailure" and
value = ""
)
}
predicate hasOptionalResult(Location location, string element, string tag, string value) {
@@ -29,7 +39,7 @@ module RegexTest implements TestSig {
value = quote(input.toString())
)
or
exists(RegexEval eval, Expr regex |
exists(RegexEval eval, RegExp regex |
eval.getARegex() = regex and
location = eval.getLocation() and
element = eval.toString() and