Skip to content

Commit e9df860

Browse files
committed
refactor implementation to make Label implementations private
1 parent 6060f2e commit e9df860

File tree

4 files changed

+151
-129
lines changed

4 files changed

+151
-129
lines changed

Diff for: javascript/ql/lib/semmle/javascript/ApiGraphs.qll

+143-119
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,13 @@ module API {
243243
* Gets a node such that there is an edge in the API graph between this node and the other
244244
* one, and that edge is labeled with `lbl`.
245245
*/
246-
Node getASuccessor(ApiLabel lbl) { Impl::edge(this, lbl, result) }
246+
Node getASuccessor(Label::ApiLabel lbl) { Impl::edge(this, lbl, result) }
247247

248248
/**
249249
* Gets a node such that there is an edge in the API graph between that other node and
250250
* this one, and that edge is labeled with `lbl`
251251
*/
252-
Node getAPredecessor(ApiLabel lbl) { this = result.getASuccessor(lbl) }
252+
Node getAPredecessor(Label::ApiLabel lbl) { this = result.getASuccessor(lbl) }
253253

254254
/**
255255
* Gets a node such that there is an edge in the API graph between this node and the other
@@ -315,7 +315,7 @@ module API {
315315
length = 0 and
316316
result = ""
317317
or
318-
exists(Node pred, ApiLabel lbl, string predpath |
318+
exists(Node pred, Label::ApiLabel lbl, string predpath |
319319
Impl::edge(pred, lbl, this) and
320320
predpath = pred.getAPath(length - 1) and
321321
exists(string space | if length = 1 then space = "" else space = " " |
@@ -383,9 +383,7 @@ module API {
383383
abstract DataFlow::Node getARhs();
384384

385385
/** Gets an API-node for this entry point. */
386-
API::Node getNode() {
387-
result = root().getASuccessor(any(Label::LabelEntryPoint l | l.getEntryPoint() = this))
388-
}
386+
API::Node getNode() { result = root().getASuccessor(Label::entryPoint(this)) }
389387
}
390388

391389
/**
@@ -474,11 +472,14 @@ module API {
474472
* incoming edge from `base` labeled `lbl` in the API graph.
475473
*/
476474
cached
477-
predicate rhs(TApiNode base, ApiLabel lbl, DataFlow::Node rhs) {
475+
predicate rhs(TApiNode base, Label::ApiLabel lbl, DataFlow::Node rhs) {
478476
hasSemantics(rhs) and
479477
(
480478
base = MkRoot() and
481-
rhs = lbl.(Label::LabelEntryPoint).getEntryPoint().getARhs()
479+
exists(EntryPoint e |
480+
lbl = Label::entryPoint(e) and
481+
rhs = e.getARhs()
482+
)
482483
or
483484
exists(string m, string prop |
484485
base = MkModuleExport(m) and
@@ -590,7 +591,7 @@ module API {
590591
*/
591592
pragma[noinline]
592593
private predicate propertyRead(
593-
DataFlow::SourceNode pred, string propDesc, ApiLabel lbl, DataFlow::Node ref
594+
DataFlow::SourceNode pred, string propDesc, Label::ApiLabel lbl, DataFlow::Node ref
594595
) {
595596
ref = pred.getAPropertyRead() and
596597
lbl = Label::memberFromRef(ref) and
@@ -614,11 +615,14 @@ module API {
614615
* `lbl` in the API graph.
615616
*/
616617
cached
617-
predicate use(TApiNode base, ApiLabel lbl, DataFlow::Node ref) {
618+
predicate use(TApiNode base, Label::ApiLabel lbl, DataFlow::Node ref) {
618619
hasSemantics(ref) and
619620
(
620621
base = MkRoot() and
621-
ref = lbl.(Label::LabelEntryPoint).getEntryPoint().getAUse()
622+
exists(EntryPoint e |
623+
lbl = Label::entryPoint(e) and
624+
ref = e.getAUse()
625+
)
622626
or
623627
// property reads
624628
exists(DataFlow::SourceNode src, DataFlow::SourceNode pred, string propDesc |
@@ -863,7 +867,7 @@ module API {
863867
* Holds if there is an edge from `pred` to `succ` in the API graph that is labeled with `lbl`.
864868
*/
865869
cached
866-
predicate edge(TApiNode pred, ApiLabel lbl, TApiNode succ) {
870+
predicate edge(TApiNode pred, Label::ApiLabel lbl, TApiNode succ) {
867871
Stages::APIStage::ref() and
868872
exists(string m |
869873
pred = MkRoot() and
@@ -941,8 +945,6 @@ module API {
941945
}
942946
}
943947

944-
import Label as EdgeLabel
945-
946948
/**
947949
* An `InvokeNode` that is connected to the API graph.
948950
*
@@ -999,109 +1001,12 @@ module API {
9991001
/** A `new` call connected to the API graph. */
10001002
class NewNode extends InvokeNode, DataFlow::NewNode { }
10011003

1002-
/** A label in the API-graph */
1003-
abstract class ApiLabel extends Label::TLabel {
1004-
string toString() { result = "???" }
1005-
}
1006-
1007-
private module Label {
1008-
newtype TLabel =
1009-
MkLabelMod(string mod) {
1010-
exists(Impl::MkModuleExport(mod)) or
1011-
exists(Impl::MkModuleImport(mod))
1012-
} or
1013-
MkLabelInstance() or
1014-
MkLabelMember(string prop) {
1015-
exports(_, prop, _) or
1016-
exists(any(DataFlow::ClassNode c).getInstanceMethod(prop)) or
1017-
prop = "exports" or
1018-
prop = any(CanonicalName c).getName() or
1019-
prop = any(DataFlow::PropRef p).getPropertyName() or
1020-
exists(Impl::MkTypeUse(_, prop)) or
1021-
exists(any(Module m).getAnExportedValue(prop))
1022-
} or
1023-
MkLabelUnknownMember() or
1024-
MkLabelParameter(int i) {
1025-
i =
1026-
[-1 .. max(int args |
1027-
args = any(InvokeExpr invk).getNumArgument() or
1028-
args = any(Function f).getNumParameter()
1029-
)] or
1030-
i = [0 .. 10]
1031-
} or
1032-
MkLabelReturn() or
1033-
MkLabelPromised() or
1034-
MkLabelPromisedError() or
1035-
MkLabelEntryPoint(API::EntryPoint e)
1036-
1037-
class LabelEntryPoint extends ApiLabel {
1038-
API::EntryPoint e;
1039-
1040-
LabelEntryPoint() { this = MkLabelEntryPoint(e) }
1041-
1042-
API::EntryPoint getEntryPoint() { result = e }
1043-
1044-
override string toString() { result = e }
1045-
}
1046-
1047-
class LabelPromised extends ApiLabel {
1048-
LabelPromised() { this = MkLabelPromised() }
1049-
1050-
override string toString() { result = "promised" }
1051-
}
1052-
1053-
class LabelPromisedError extends ApiLabel {
1054-
LabelPromisedError() { this = MkLabelPromisedError() }
1055-
1056-
override string toString() { result = "promised" }
1057-
}
1058-
1059-
class LabelReturn extends ApiLabel {
1060-
LabelReturn() { this = MkLabelReturn() }
1061-
1062-
override string toString() { result = "return" }
1063-
}
1064-
1065-
class LabelMod extends ApiLabel {
1066-
string mod;
1067-
1068-
LabelMod() { this = MkLabelMod(mod) }
1069-
1070-
string getMod() { result = mod }
1071-
1072-
override string toString() { result = "module " + mod }
1073-
}
1074-
1075-
class LabelInstance extends ApiLabel {
1076-
LabelInstance() { this = MkLabelInstance() }
1077-
1078-
override string toString() { result = "instance" }
1079-
}
1080-
1081-
class LabelMember extends ApiLabel {
1082-
string prop;
1083-
1084-
LabelMember() { this = MkLabelMember(prop) }
1085-
1086-
string getProperty() { result = prop }
1087-
1088-
override string toString() { result = "member " + prop }
1089-
}
1090-
1091-
class LabelUnknownMember extends ApiLabel {
1092-
LabelUnknownMember() { this = MkLabelUnknownMember() }
1093-
1094-
override string toString() { result = "member *" }
1095-
}
1096-
1097-
class LabelParameter extends ApiLabel {
1098-
int i;
1099-
1100-
LabelParameter() { this = MkLabelParameter(i) }
1101-
1102-
override string toString() { result = "parameter " + i }
1103-
1104-
int getIndex() { result = i }
1004+
/** Provides classes modeling the various edges (labels) in the API graph. */
1005+
module Label {
1006+
/** A label in the API-graph */
1007+
abstract class ApiLabel extends TLabel {
1008+
/** Gets a string representation of this label. */
1009+
string toString() { result = "???" }
11051010
}
11061011

11071012
/** Gets the edge label for the module `m`. */
@@ -1167,10 +1072,129 @@ module API {
11671072
LabelReturn return() { any() }
11681073

11691074
/** Gets the `promised` edge label connecting a promise to its contained value. */
1170-
MkLabelPromised promised() { any() }
1075+
LabelPromised promised() { any() }
11711076

11721077
/** Gets the `promisedError` edge label connecting a promise to its rejected value. */
1173-
MkLabelPromisedError promisedError() { any() }
1078+
LabelPromisedError promisedError() { any() }
1079+
1080+
/** Gets an entry-point label for the entry-point `e`. */
1081+
LabelEntryPoint entryPoint(API::EntryPoint e) { result.getEntryPoint() = e }
1082+
1083+
private import LabelImpl
1084+
1085+
private module LabelImpl {
1086+
newtype TLabel =
1087+
MkLabelMod(string mod) {
1088+
exists(Impl::MkModuleExport(mod)) or
1089+
exists(Impl::MkModuleImport(mod))
1090+
} or
1091+
MkLabelInstance() or
1092+
MkLabelMember(string prop) {
1093+
exports(_, prop, _) or
1094+
exists(any(DataFlow::ClassNode c).getInstanceMethod(prop)) or
1095+
prop = "exports" or
1096+
prop = any(CanonicalName c).getName() or
1097+
prop = any(DataFlow::PropRef p).getPropertyName() or
1098+
exists(Impl::MkTypeUse(_, prop)) or
1099+
exists(any(Module m).getAnExportedValue(prop))
1100+
} or
1101+
MkLabelUnknownMember() or
1102+
MkLabelParameter(int i) {
1103+
i =
1104+
[-1 .. max(int args |
1105+
args = any(InvokeExpr invk).getNumArgument() or
1106+
args = any(Function f).getNumParameter()
1107+
)] or
1108+
i = [0 .. 10]
1109+
} or
1110+
MkLabelReturn() or
1111+
MkLabelPromised() or
1112+
MkLabelPromisedError() or
1113+
MkLabelEntryPoint(API::EntryPoint e)
1114+
1115+
/** A label for an entry-point. */
1116+
class LabelEntryPoint extends ApiLabel {
1117+
API::EntryPoint e;
1118+
1119+
LabelEntryPoint() { this = MkLabelEntryPoint(e) }
1120+
1121+
/** Gets the EntryPoint associated with this label. */
1122+
API::EntryPoint getEntryPoint() { result = e }
1123+
1124+
override string toString() { result = e }
1125+
}
1126+
1127+
/** A label that gets a promised value. */
1128+
class LabelPromised extends ApiLabel {
1129+
LabelPromised() { this = MkLabelPromised() }
1130+
1131+
override string toString() { result = "promised" }
1132+
}
1133+
1134+
/** A label that gets a rejected promise. */
1135+
class LabelPromisedError extends ApiLabel {
1136+
LabelPromisedError() { this = MkLabelPromisedError() }
1137+
1138+
override string toString() { result = "promisedError" }
1139+
}
1140+
1141+
/** A label that gets the return value of a function. */
1142+
class LabelReturn extends ApiLabel {
1143+
LabelReturn() { this = MkLabelReturn() }
1144+
1145+
override string toString() { result = "return" }
1146+
}
1147+
1148+
/** A label for a module. */
1149+
class LabelMod extends ApiLabel {
1150+
string mod;
1151+
1152+
LabelMod() { this = MkLabelMod(mod) }
1153+
1154+
/** Gets the module associated with this label. */
1155+
string getMod() { result = mod }
1156+
1157+
override string toString() { result = "module " + mod }
1158+
}
1159+
1160+
/** A label that gets an instance from a `new` call. */
1161+
class LabelInstance extends ApiLabel {
1162+
LabelInstance() { this = MkLabelInstance() }
1163+
1164+
override string toString() { result = "instance" }
1165+
}
1166+
1167+
/** A label for the member named `prop`. */
1168+
class LabelMember extends ApiLabel {
1169+
string prop;
1170+
1171+
LabelMember() { this = MkLabelMember(prop) }
1172+
1173+
/** Gets the property associated with this label. */
1174+
string getProperty() { result = prop }
1175+
1176+
override string toString() { result = "member " + prop }
1177+
}
1178+
1179+
/** A label for a member with an unknown name. */
1180+
class LabelUnknownMember extends ApiLabel {
1181+
LabelUnknownMember() { this = MkLabelUnknownMember() }
1182+
1183+
override string toString() { result = "member *" }
1184+
}
1185+
1186+
/** A label for parameter `i`. */
1187+
class LabelParameter extends ApiLabel {
1188+
int i;
1189+
1190+
LabelParameter() { this = MkLabelParameter(i) }
1191+
1192+
override string toString() { result = "parameter " + i }
1193+
1194+
/** Gets the index of the parameter for this label. */
1195+
int getIndex() { result = i }
1196+
}
1197+
}
11741198
}
11751199
}
11761200

Diff for: javascript/ql/lib/semmle/javascript/security/dataflow/RemoteFlowSources.qll

+4-7
Original file line numberDiff line numberDiff line change
@@ -117,17 +117,14 @@ private class RemoteFlowSourceAccessPath extends JSONString {
117117
string getSourceType() { result = sourceType }
118118

119119
/** Gets the `i`th component of the access path specifying this remote flow source. */
120-
API::ApiLabel getComponent(int i) {
120+
API::Label::ApiLabel getComponent(int i) {
121121
exists(string raw | raw = this.getValue().splitAt(".", i + 1) |
122122
i = 0 and
123-
result
124-
.(API::EdgeLabel::LabelEntryPoint)
125-
.getEntryPoint()
126-
.(ExternalRemoteFlowSourceSpecEntryPoint)
127-
.getName() = raw
123+
result =
124+
API::Label::entryPoint(any(ExternalRemoteFlowSourceSpecEntryPoint e | e.getName() = raw))
128125
or
129126
i > 0 and
130-
result = API::EdgeLabel::member(raw)
127+
result = API::Label::member(raw)
131128
)
132129
}
133130

Diff for: javascript/ql/src/meta/ApiGraphs/ApiGraphEdges.ql

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ import javascript
1212
import meta.MetaMetrics
1313

1414
select projectRoot(),
15-
count(API::Node pred, API::ApiLabel lbl, API::Node succ | succ = pred.getASuccessor(lbl))
15+
count(API::Node pred, API::Label::ApiLabel lbl, API::Node succ | succ = pred.getASuccessor(lbl))

Diff for: javascript/ql/test/ApiGraphs/VerifyAssertions.qll

+3-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ class Assertion extends Comment {
6363
result = API::root()
6464
or
6565
result =
66-
lookup(i + 1).getASuccessor(any(API::ApiLabel label | label.toString() = getEdgeLabel(i)))
66+
lookup(i + 1)
67+
.getASuccessor(any(API::Label::ApiLabel label | label.toString() = getEdgeLabel(i)))
6768
}
6869

6970
predicate isNegative() { polarity = "!" }
@@ -81,7 +82,7 @@ class Assertion extends Comment {
8182
suffix =
8283
"it does have outgoing edges labelled " +
8384
concat(string lbl |
84-
exists(nd.getASuccessor(any(API::ApiLabel label | label.toString() = lbl)))
85+
exists(nd.getASuccessor(any(API::Label::ApiLabel label | label.toString() = lbl)))
8586
|
8687
lbl, ", "
8788
) + "."

0 commit comments

Comments
 (0)