Skip to content

Commit f39872e

Browse files
committed
cache more predicates
1 parent 089d030 commit f39872e

File tree

5 files changed

+60
-4
lines changed

5 files changed

+60
-4
lines changed

javascript/ql/lib/semmle/javascript/Constants.qll

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
*/
44

55
import javascript
6+
private import semmle.javascript.internal.CachedStages
67

78
/**
89
* An expression that evaluates to a constant primitive value.
910
*/
11+
cached
1012
abstract class ConstantExpr extends Expr { }
1113

1214
/**
@@ -16,15 +18,19 @@ module SyntacticConstants {
1618
/**
1719
* An expression that evaluates to a constant value according to a bottom-up syntactic analysis.
1820
*/
21+
cached
1922
abstract class SyntacticConstant extends ConstantExpr { }
2023

2124
/**
2225
* A literal primitive expression.
2326
*
2427
* Note that `undefined`, `NaN` and `Infinity` are global variables, and are not covered by this class.
2528
*/
29+
cached
2630
class PrimitiveLiteralConstant extends SyntacticConstant {
31+
cached
2732
PrimitiveLiteralConstant() {
33+
Stages::Ast::ref() and
2834
this instanceof NumberLiteral
2935
or
3036
this instanceof StringLiteral
@@ -43,19 +49,27 @@ module SyntacticConstants {
4349
/**
4450
* A literal null expression.
4551
*/
46-
class NullConstant extends SyntacticConstant, NullLiteral { }
52+
cached
53+
class NullConstant extends SyntacticConstant, NullLiteral {
54+
cached
55+
NullConstant() { Stages::Ast::ref() and this = this }
56+
}
4757

4858
/**
4959
* A unary operation on a syntactic constant.
5060
*/
61+
cached
5162
class UnaryConstant extends SyntacticConstant, UnaryExpr {
63+
cached
5264
UnaryConstant() { getOperand() instanceof SyntacticConstant }
5365
}
5466

5567
/**
5668
* A binary operation on syntactic constants.
5769
*/
70+
cached
5871
class BinaryConstant extends SyntacticConstant, BinaryExpr {
72+
cached
5973
BinaryConstant() {
6074
getLeftOperand() instanceof SyntacticConstant and
6175
getRightOperand() instanceof SyntacticConstant
@@ -65,7 +79,9 @@ module SyntacticConstants {
6579
/**
6680
* A conditional expression on syntactic constants.
6781
*/
82+
cached
6883
class ConditionalConstant extends SyntacticConstant, ConditionalExpr {
84+
cached
6985
ConditionalConstant() {
7086
getCondition() instanceof SyntacticConstant and
7187
getConsequent() instanceof SyntacticConstant and
@@ -76,7 +92,9 @@ module SyntacticConstants {
7692
/**
7793
* A use of the global variable `undefined` or `void e`.
7894
*/
95+
cached
7996
class UndefinedConstant extends SyntacticConstant {
97+
cached
8098
UndefinedConstant() {
8199
this.(GlobalVarAccess).getName() = "undefined" or
82100
this instanceof VoidExpr
@@ -86,21 +104,27 @@ module SyntacticConstants {
86104
/**
87105
* A use of the global variable `NaN`.
88106
*/
107+
cached
89108
class NaNConstant extends SyntacticConstant {
109+
cached
90110
NaNConstant() { this.(GlobalVarAccess).getName() = "NaN" }
91111
}
92112

93113
/**
94114
* A use of the global variable `Infinity`.
95115
*/
116+
cached
96117
class InfinityConstant extends SyntacticConstant {
118+
cached
97119
InfinityConstant() { this.(GlobalVarAccess).getName() = "Infinity" }
98120
}
99121

100122
/**
101123
* An expression that wraps the syntactic constant it evaluates to.
102124
*/
125+
cached
103126
class WrappedConstant extends SyntacticConstant {
127+
cached
104128
WrappedConstant() { getUnderlyingValue() instanceof SyntacticConstant }
105129
}
106130

@@ -123,6 +147,8 @@ module SyntacticConstants {
123147
/**
124148
* An expression that evaluates to a constant string.
125149
*/
150+
cached
126151
class ConstantString extends ConstantExpr {
152+
cached
127153
ConstantString() { exists(getStringValue()) }
128154
}

javascript/ql/lib/semmle/javascript/Expr.qll

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ class ExprOrType extends @expr_or_type, Documentable {
8989
*
9090
* Also see `getUnderlyingReference` and `stripParens`.
9191
*/
92-
Expr getUnderlyingValue() { result = this }
92+
cached
93+
Expr getUnderlyingValue() { Stages::Ast::ref() and result = this }
9394
}
9495

9596
/**
@@ -274,7 +275,11 @@ private DataFlow::Node getCatchParameterFromStmt(Stmt stmt) {
274275
*/
275276
class Identifier extends @identifier, ExprOrType {
276277
/** Gets the name of this identifier. */
277-
string getName() { literals(result, _, this) }
278+
cached
279+
string getName() {
280+
Stages::Ast::ref() and
281+
literals(result, _, this)
282+
}
278283

279284
override string getAPrimaryQlClass() { result = "Identifier" }
280285
}

javascript/ql/lib/semmle/javascript/MembershipCandidates.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ module MembershipCandidate {
165165
EnumerationRegExp enumeration;
166166
boolean polarity;
167167

168+
pragma[nomagic]
168169
RegExpEnumerationCandidate() {
169170
exists(DataFlow::MethodCallNode mcn, DataFlow::Node base, string m, DataFlow::Node firstArg |
170171
(

javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,12 @@ module TaintTracking {
160160
* of the standard library. Override `Configuration::isSanitizerGuard`
161161
* for analysis-specific taint sanitizer guards.
162162
*/
163+
cached
163164
abstract class AdditionalSanitizerGuardNode extends SanitizerGuardNode {
164165
/**
165166
* Holds if this guard applies to the flow in `cfg`.
166167
*/
168+
cached
167169
abstract predicate appliesTo(Configuration cfg);
168170
}
169171

@@ -1127,7 +1129,7 @@ module TaintTracking {
11271129
idx = astNode.getAnOperand() and
11281130
idx.getPropertyNameExpr() = x and
11291131
// and the other one is guaranteed to be `undefined`
1130-
forex(InferredType tp | tp = undef.getAType() | tp = TTUndefined())
1132+
unique(InferredType tp | tp = pragma[only_bind_into](undef.getAType())) = TTUndefined()
11311133
)
11321134
}
11331135

javascript/ql/lib/semmle/javascript/internal/CachedStages.qll

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ module Stages {
6969
exists(any(Expr e).getStringValue())
7070
or
7171
any(ASTNode node).isAmbient()
72+
or
73+
exists(any(Identifier e).getName())
74+
or
75+
exists(any(ExprOrType e).getUnderlyingValue())
76+
or
77+
exists(ConstantExpr e)
78+
or
79+
exists(SyntacticConstants::NullConstant n)
7280
}
7381
}
7482

@@ -299,6 +307,20 @@ module Stages {
299307
exists(Exports::getALibraryInputParameter())
300308
or
301309
any(RegExpTerm t).isUsedAsRegExp()
310+
or
311+
any(TaintTracking::AdditionalSanitizerGuardNode e).appliesTo(_)
312+
}
313+
314+
cached
315+
class DummySanitizer extends TaintTracking::AdditionalSanitizerGuardNode {
316+
cached
317+
DummySanitizer() { none() }
318+
319+
cached
320+
override predicate appliesTo(TaintTracking::Configuration cfg) { none() }
321+
322+
cached
323+
override predicate sanitizes(boolean outcome, Expr e) { none() }
302324
}
303325
}
304326
}

0 commit comments

Comments
 (0)