Skip to content

Commit eac06af

Browse files
committed
wip
1 parent 59fc7aa commit eac06af

File tree

6 files changed

+42
-493
lines changed

6 files changed

+42
-493
lines changed

javascript/ql/lib/semmle/javascript/AMD.qll

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -191,30 +191,12 @@ class AmdModuleDefinition extends CallExpr instanceof AmdModuleDefinition::Range
191191
}
192192

193193
/**
194+
* DEPRECATED. Abstract values are no longer used to track module exports.
195+
*
194196
* Gets an abstract value representing one or more values that may flow
195197
* into this module's `module.exports` property.
196198
*/
197-
DefiniteAbstractValue getAModuleExportsValue() {
198-
result = [this.getAnImplicitExportsValue(), this.getAnExplicitExportsValue()]
199-
}
200-
201-
pragma[noinline, nomagic]
202-
private AbstractValue getAnImplicitExportsValue() {
203-
// implicit exports: anything that is returned from the factory function
204-
result = this.getModuleExpr().analyze().getAValue()
205-
}
206-
207-
pragma[noinline]
208-
private AbstractValue getAnExplicitExportsValue() {
209-
// explicit exports: anything assigned to `module.exports`
210-
exists(AbstractProperty moduleExports, AmdModule m |
211-
this = m.getDefine() and
212-
moduleExports.getBase().(AbstractModuleObject).getModule() = m and
213-
moduleExports.getPropertyName() = "exports"
214-
|
215-
result = moduleExports.getAValue()
216-
)
217-
}
199+
deprecated DefiniteAbstractValue getAModuleExportsValue() { none() }
218200

219201
/**
220202
* Gets a call to `require` inside this module.
@@ -357,21 +339,19 @@ class AmdModule extends Module {
357339
AmdModuleDefinition getDefine() { amdModuleTopLevel(result, this) }
358340

359341
override DataFlow::Node getAnExportedValue(string name) {
360-
exists(DataFlow::PropWrite pwn | result = pwn.getRhs() |
361-
pwn.getBase().analyze().getAValue() = this.getDefine().getAModuleExportsValue() and
362-
name = pwn.getPropertyName()
363-
)
342+
none() // TODO: AMD getAnExportedValue
364343
}
365344

366345
override DataFlow::Node getABulkExportedNode() {
346+
// TODO: AMD getABulkExportedNode
367347
// Assigned to `module.exports` via the factory's `module` parameter
368-
exists(AbstractModuleObject m, DataFlow::PropWrite write |
369-
m.getModule() = this and
370-
write.getPropertyName() = "exports" and
371-
write.getBase().analyze().getAValue() = m and
372-
result = write.getRhs()
373-
)
374-
or
348+
// exists(AbstractModuleObject m, DataFlow::PropWrite write |
349+
// m.getModule() = this and
350+
// write.getPropertyName() = "exports" and
351+
// write.getBase().analyze().getAValue() = m and
352+
// result = write.getRhs()
353+
// )
354+
// or
375355
// Returned from factory function
376356
result = this.getDefine().getModuleExpr().flow()
377357
}

javascript/ql/lib/semmle/javascript/NodeJS.qll

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,24 +37,34 @@ class NodeModule extends Module {
3737
* into this module's `module.exports` property.
3838
*/
3939
pragma[noinline]
40-
DefiniteAbstractValue getAModuleExportsValue() {
41-
result = this.getAModuleExportsProperty().getAValue()
40+
deprecated DefiniteAbstractValue getAModuleExportsValue() { none() }
41+
42+
/**
43+
* Gets the `SourceNode` corresponding to the value of `module`.
44+
*/
45+
private DataFlow::SourceNode getModuleSourceNode() {
46+
result = DataFlow::ssaDefinitionNode(Ssa::implicitInit(this.getModuleVariable()))
4247
}
4348

44-
pragma[noinline]
45-
private AbstractProperty getAModuleExportsProperty() {
46-
result.getBase().(AbstractModuleObject).getModule() = this and
47-
result.getPropertyName() = "exports"
49+
/**
50+
* Gets a `SourceNode` corresponding to the initial value of `module.exports` or
51+
* anything assigned to `module.exports`.
52+
*/
53+
private DataFlow::SourceNode getExportsSourceNode() {
54+
result = DataFlow::ssaDefinitionNode(Ssa::implicitInit(this.getExportsVariable()))
55+
or
56+
result = this.getModuleSourceNode().getAPropertyWrite("exports").getRhs().getALocalSource()
57+
or
58+
result = this.getModuleSourceNode().getAPropertyRead("exports")
4859
}
4960

5061
/**
5162
* Gets an expression that is an alias for `module.exports`.
5263
* For performance this predicate only computes relevant expressions (in `getAModuleExportsCandidate`).
5364
* So if using this predicate - consider expanding the list of relevant expressions.
5465
*/
55-
DataFlow::AnalyzedNode getAModuleExportsNode() {
56-
result = getAModuleExportsCandidate() and
57-
result.getAValue() = this.getAModuleExportsValue()
66+
deprecated DataFlow::AnalyzedNode getAModuleExportsNode() {
67+
result = this.getExportsSourceNode().getALocalUse()
5868
}
5969

6070
/** Gets a symbol exported by this module. */
@@ -64,21 +74,15 @@ class NodeModule extends Module {
6474
result = this.getAnImplicitlyExportedSymbol()
6575
or
6676
// getters and the like.
67-
exists(DataFlow::PropWrite pwn |
68-
pwn.getBase() = this.getAModuleExportsNode() and
69-
result = pwn.getPropertyName()
70-
)
77+
result = this.getExportsSourceNode().getAPropertyWrite().getPropertyName()
7178
}
7279

7380
override DataFlow::Node getAnExportedValue(string name) {
7481
// a property write whose base is `exports` or `module.exports`
75-
exists(DataFlow::PropWrite pwn | result = pwn.getRhs() |
76-
pwn.getBase() = this.getAModuleExportsNode() and
77-
name = pwn.getPropertyName()
78-
)
82+
result = this.getExportsSourceNode().getAPropertyWrite(name).getRhs()
7983
or
8084
// a re-export using spread-operator. E.g. `const foo = require("./foo"); module.exports = {bar: bar, ...foo};`
81-
exists(ObjectExpr obj | obj = this.getAModuleExportsNode().asExpr() |
85+
exists(ObjectExpr obj | obj = this.getExportsSourceNode().asExpr() |
8286
result =
8387
obj.getAProperty()
8488
.(SpreadProperty)
@@ -99,16 +103,15 @@ class NodeModule extends Module {
99103
// }
100104
exists(DynamicPropertyAccess::EnumeratedPropName read, Import imp, DataFlow::PropWrite write |
101105
read.getSourceObject().getALocalSource().asExpr() = imp and
106+
write = this.getExportsSourceNode().getAPropertyWrite() and
102107
getASourceProp(read) = write.getRhs() and
103-
write.getBase() = this.getAModuleExportsNode() and
104108
write.getPropertyNameExpr().flow().getImmediatePredecessor*() = read and
105109
result = imp.getImportedModule().getAnExportedValue(name)
106110
)
107111
or
108112
// an externs definition (where appropriate)
109113
exists(PropAccess pacc | result = DataFlow::valueNode(pacc) |
110-
pacc.getBase() = this.getAModuleExportsNode().asExpr() and
111-
name = pacc.getPropertyName() and
114+
pacc = this.getExportsSourceNode().getAPropertyRead(name).asExpr() and
112115
this.isExterns() and
113116
exists(pacc.getDocumentation())
114117
)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ class AbstractGlobalObject extends DefiniteAbstractValue, TAbstractGlobalObject
390390
/**
391391
* An abstract value representing a CommonJS `module` object.
392392
*/
393-
class AbstractModuleObject extends DefiniteAbstractValue, TAbstractModuleObject {
393+
deprecated class AbstractModuleObject extends DefiniteAbstractValue, TAbstractModuleObject {
394394
/** Gets the module whose `module` object this abstract value represents. */
395395
Module getModule() { this = TAbstractModuleObject(result) }
396396

@@ -414,7 +414,7 @@ class AbstractModuleObject extends DefiniteAbstractValue, TAbstractModuleObject
414414
/**
415415
* An abstract value representing a CommonJS `exports` object.
416416
*/
417-
class AbstractExportsObject extends DefiniteAbstractValue, TAbstractExportsObject {
417+
deprecated class AbstractExportsObject extends DefiniteAbstractValue, TAbstractExportsObject {
418418
/** Gets the module whose `exports` object this abstract value represents. */
419419
Module getModule() { this = TAbstractExportsObject(result) }
420420

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import AbstractValues
3030
private import InferredTypes
3131
private import Refinements
3232
import internal.BasicExprTypeInference
33-
import internal.InterModuleTypeInference
3433
import internal.InterProceduralTypeInference
3534
import internal.PropertyTypeInference
3635
import internal.VariableTypeInference

javascript/ql/lib/semmle/javascript/dataflow/internal/AbstractValuesImpl.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ newtype TAbstractValue =
4343
TAbstractArguments(Function f) { exists(f.getArgumentsVariable().getAnAccess()) } or
4444
/** An abstract representation of the global object. */
4545
TAbstractGlobalObject() or
46-
/** An abstract representation of a `module` object. */
47-
TAbstractModuleObject(Module m) or
48-
/** An abstract representation of a `exports` object. */
49-
TAbstractExportsObject(Module m) or
46+
/** DEPRECATED. This abstract value is no longer tracked. */
47+
deprecated TAbstractModuleObject(Module m) { none() } or
48+
/** DEPRECATED. This abstract value is no longer tracked. */
49+
deprecated TAbstractExportsObject(Module m) { none() } or
5050
/** An abstract representation of all objects arising from an object literal expression. */
5151
TAbstractObjectLiteral(ObjectExpr oe) or
5252
/**

0 commit comments

Comments
 (0)