mirror of
https://github.com/github/codeql.git
synced 2025-12-25 21:26:37 +01:00
79 lines
2.2 KiB
Plaintext
79 lines
2.2 KiB
Plaintext
/**
|
|
* @name Replacement of a substring with itself
|
|
* @description Replacing a substring with itself has no effect and may indicate a mistake.
|
|
* @kind problem
|
|
* @problem.severity warning
|
|
* @security-severity 7.8
|
|
* @id js/identity-replacement
|
|
* @precision very-high
|
|
* @tags correctness
|
|
* security
|
|
* external/cwe/cwe-116
|
|
*/
|
|
|
|
import javascript
|
|
|
|
/**
|
|
* Holds if `e`, when used as the first argument of `String.prototype.replace`, matches
|
|
* `s` and nothing else.
|
|
*/
|
|
predicate matchesString(Expr e, string s) {
|
|
exists(RegExpLiteral rl |
|
|
rl.flow().(DataFlow::SourceNode).flowsToExpr(e) and
|
|
not rl.isIgnoreCase() and
|
|
regExpMatchesString(rl.getRoot(), s)
|
|
)
|
|
or
|
|
s = e.getStringValue()
|
|
}
|
|
|
|
/**
|
|
* Holds if `t` matches `s` and nothing else.
|
|
*/
|
|
language[monotonicAggregates]
|
|
predicate regExpMatchesString(RegExpTerm t, string s) {
|
|
t.isPartOfRegExpLiteral() and
|
|
(
|
|
// constants match themselves
|
|
s = t.(RegExpConstant).getValue()
|
|
or
|
|
// assertions match the empty string
|
|
(
|
|
t instanceof RegExpCaret or
|
|
t instanceof RegExpDollar or
|
|
t instanceof RegExpWordBoundary or
|
|
t instanceof RegExpNonWordBoundary or
|
|
t instanceof RegExpLookahead or
|
|
t instanceof RegExpLookbehind
|
|
) and
|
|
s = ""
|
|
or
|
|
// groups match their content
|
|
regExpMatchesString(t.(RegExpGroup).getAChild(), s)
|
|
or
|
|
// single-character classes match that character
|
|
exists(RegExpCharacterClass recc | recc = t and not recc.isInverted() |
|
|
recc.getNumChild() = 1 and
|
|
regExpMatchesString(recc.getChild(0), s)
|
|
)
|
|
or
|
|
// sequences match the concatenation of their elements
|
|
exists(RegExpSequence seq | seq = t |
|
|
s =
|
|
concat(int i, RegExpTerm child |
|
|
child = seq.getChild(i)
|
|
|
|
|
any(string subs | regExpMatchesString(child, subs)) order by i
|
|
)
|
|
)
|
|
)
|
|
}
|
|
|
|
from MethodCallExpr repl, string s, string friendly
|
|
where
|
|
repl.getMethodName() = ["replace", "replaceAll"] and
|
|
matchesString(repl.getArgument(0), s) and
|
|
repl.getArgument(1).getStringValue() = s and
|
|
(if s = "" then friendly = "the empty string" else friendly = "'" + s + "'")
|
|
select repl.getArgument(0), "This replaces " + friendly + " with itself."
|