C++: Don't repeat work in BrokenCryptoAlgorithm.ql

The main source of slowness in `BrokenCryptoAlgorithm.ql` was that the
regexp on function (macro) names was evaluated once per call
(invocation) instead of once per name. Factoring out separate predicates
for the problematic functions (macros) fixes this.

On https://github.com/ericniebler/range-v3, this change reduces the run
time of the two slowest predicates from

    BrokenCryptoAlgorithm::InsecureMacroSpec#class#f .... 35.1s
    BrokenCryptoAlgorithm::InsecureFunctionCall#class#f . 12.8s

to

    BrokenCryptoAlgorithm::getAnInsecureFunction#f . 1.2s
    BrokenCryptoAlgorithm::getAnInsecureMacro#f .... 12ms
This commit is contained in:
Jonas Jensen
2019-03-18 12:01:37 +01:00
parent f72ff37226
commit 76ff250593

View File

@@ -16,9 +16,14 @@ abstract class InsecureCryptoSpec extends Locatable {
abstract string description();
}
Function getAnInsecureFunction() {
result.getName().regexpMatch(algorithmBlacklistRegex()) and
exists(result.getACallToThisFunction())
}
class InsecureFunctionCall extends InsecureCryptoSpec, FunctionCall {
InsecureFunctionCall() {
this.getTarget().getName().regexpMatch(algorithmBlacklistRegex())
this.getTarget() = getAnInsecureFunction()
}
override string description() { result = "function call" }
@@ -27,9 +32,14 @@ class InsecureFunctionCall extends InsecureCryptoSpec, FunctionCall {
override Location getLocation() { result = FunctionCall.super.getLocation() }
}
Macro getAnInsecureMacro() {
result.getName().regexpMatch(algorithmBlacklistRegex()) and
exists(result.getAnInvocation())
}
class InsecureMacroSpec extends InsecureCryptoSpec, MacroInvocation {
InsecureMacroSpec() {
this.getMacro().getName().regexpMatch(algorithmBlacklistRegex())
this.getMacro() = getAnInsecureMacro()
}
override string description() { result = "macro invocation" }