Merge pull request #17910 from Napalys/napalys/matchAll-support

JS: Support for matchAll
This commit is contained in:
Napalys Klicius
2024-11-14 15:36:20 +01:00
committed by GitHub
16 changed files with 179 additions and 10 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
Added support for `String.prototype.matchAll`.

View File

@@ -193,7 +193,7 @@ module MembershipCandidate {
or
// u.match(/re/) or u.match("re")
base = this and
m = "match" and
m = ["match", "matchAll"] and
enumeration = RegExp::getRegExpFromNode(firstArg)
)
}

View File

@@ -938,7 +938,7 @@ private predicate isMatchObjectProperty(string name) {
/** Holds if `call` is a call to `match` whose result is used in a way that is incompatible with Match objects. */
private predicate isUsedAsNonMatchObject(DataFlow::MethodCallNode call) {
call.getMethodName() = "match" and
call.getMethodName() = ["match", "matchAll"] and
call.getNumArgument() = 1 and
(
// Accessing a property that is absent on Match objects
@@ -996,7 +996,7 @@ predicate isInterpretedAsRegExp(DataFlow::Node source) {
not isNativeStringMethod(func, methodName)
)
|
methodName = "match" and
methodName = ["match", "matchAll"] and
source = mce.getArgument(0) and
mce.getNumArgument() = 1 and
not isUsedAsNonMatchObject(mce)

View File

@@ -722,7 +722,7 @@ module StringOps {
}
private class MatchCall extends DataFlow::MethodCallNode {
MatchCall() { this.getMethodName() = "match" }
MatchCall() { this.getMethodName() = ["match", "matchAll"] }
}
private class ExecCall extends DataFlow::MethodCallNode {

View File

@@ -716,7 +716,7 @@ module TaintTracking {
pragma[nomagic]
private DataFlow::MethodCallNode matchMethodCall() {
result.getMethodName() = "match" and
result.getMethodName() = ["match", "matchAll"] and
exists(DataFlow::AnalyzedNode analyzed |
pragma[only_bind_into](analyzed) = result.getArgument(0).analyze() and
analyzed.getAType() = TTRegExp()
@@ -904,7 +904,7 @@ module TaintTracking {
*/
private ControlFlowNode getACaptureSetter(DataFlow::Node input) {
exists(DataFlow::MethodCallNode call | result = call.asExpr() |
call.getMethodName() = ["search", "replace", "replaceAll", "match"] and
call.getMethodName() = ["search", "replace", "replaceAll", "match", "matchAll"] and
input = call.getReceiver()
or
call.getMethodName() = ["test", "exec"] and input = call.getArgument(0)
@@ -985,7 +985,7 @@ module TaintTracking {
or
// u.match(/re/) or u.match("re")
base = expr and
m = "match" and
m = ["match", "matchAll"] and
RegExp::isGenericRegExpSanitizer(RegExp::getRegExpFromNode(firstArg.flow()),
sanitizedOutcome)
)