mirror of
https://github.com/github/codeql.git
synced 2026-04-25 00:35:20 +02:00
JavaScript: Move getStringValue(RegExpLiteral) into the library.
This commit is contained in:
@@ -15,32 +15,6 @@
|
||||
|
||||
import javascript
|
||||
|
||||
/**
|
||||
* Holds if `rl` is a simple constant, which is bound to the result of the predicate.
|
||||
*
|
||||
* For example, `/a/g` has string value `"a"` and `/abc/` has string value `"abc"`,
|
||||
* while `/ab?/` and `/a(?=b)/` do not have a string value.
|
||||
*
|
||||
* Flags are ignored, so `/a/i` is still considered to have string value `"a"`,
|
||||
* even though it also matches `"A"`.
|
||||
*
|
||||
* Note the somewhat subtle use of monotonic aggregate semantics, which makes the
|
||||
* `strictconcat` fail if one of the children of the root is not a constant (legacy
|
||||
* semantics would simply skip such children).
|
||||
*/
|
||||
language[monotonicAggregates]
|
||||
string getStringValue(RegExpLiteral rl) {
|
||||
exists(RegExpTerm root | root = rl.getRoot() |
|
||||
result = root.(RegExpConstant).getValue()
|
||||
or
|
||||
result = strictconcat(RegExpTerm ch, int i |
|
||||
ch = root.(RegExpSequence).getChild(i)
|
||||
|
|
||||
ch.(RegExpConstant).getValue() order by i
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a predecessor of `nd` that is not an SSA phi node.
|
||||
*/
|
||||
@@ -163,7 +137,7 @@ class GlobalStringReplacement extends Replacement, DataFlow::MethodCallNode {
|
||||
}
|
||||
|
||||
override predicate replaces(string input, string output) {
|
||||
input = getStringValue(pattern) and
|
||||
input = pattern.getRoot().getConstantValue() and
|
||||
output = this.getArgument(1).getStringValue()
|
||||
or
|
||||
exists(DataFlow::FunctionNode replacer, DataFlow::PropRead pr, DataFlow::ObjectLiteralNode map |
|
||||
|
||||
@@ -173,6 +173,18 @@ class RegExpTerm extends Locatable, @regexpterm {
|
||||
parent.(StringLiteral).flow() instanceof RegExpPatternSource
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single string this regular-expression term matches.
|
||||
*
|
||||
* This predicate is only defined for (sequences/groups of) constant regular expressions.
|
||||
* In particular, terms involving zero-width assertions like `^` or `\b` are not considered
|
||||
* to have a constant value.
|
||||
*
|
||||
* Note that this predicate does not take flags of the enclosing regular-expression literal
|
||||
* into account.
|
||||
*/
|
||||
string getConstantValue() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,6 +235,8 @@ class RegExpConstant extends RegExpTerm, @regexp_constant {
|
||||
predicate isCharacter() { any() }
|
||||
|
||||
override predicate isNullable() { none() }
|
||||
|
||||
override string getConstantValue() { result = getValue() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,6 +303,15 @@ class RegExpSequence extends RegExpTerm, @regexp_seq {
|
||||
override predicate isNullable() {
|
||||
forall(RegExpTerm child | child = getAChild() | child.isNullable())
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
override string getConstantValue() {
|
||||
// note: due to use of monotonic aggregates, this `strictconcat` will fail if
|
||||
// `getConstantValue` is undefined for any child
|
||||
result = strictconcat(RegExpTerm ch, int i | ch = getChild(i) |
|
||||
ch.getConstantValue() order by i
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -549,6 +572,8 @@ class RegExpGroup extends RegExpTerm, @regexp_group {
|
||||
string getName() { isNamedCapture(this, result) }
|
||||
|
||||
override predicate isNullable() { getAChild().isNullable() }
|
||||
|
||||
override string getConstantValue() { result = getAChild().getConstantValue() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user