Skip to content

Commit de2ee4d

Browse files
committed
stash I can't especify the argument and command differences with new API
1 parent 4cd3618 commit de2ee4d

File tree

1 file changed

+25
-57
lines changed
  • javascript/ql/lib/semmle/javascript/frameworks

1 file changed

+25
-57
lines changed

javascript/ql/lib/semmle/javascript/frameworks/Execa.qll

Lines changed: 25 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -97,65 +97,50 @@ module Execa {
9797
}
9898

9999
/**
100-
* A call to `execa.$` or `execa.$.sync` tag functions
100+
* A call to `execa.$` or `execa.$.sync` or `execa.$({})` or `execa.$.sync({})` tag functions
101101
*/
102-
private class ExecaScriptExpr extends DataFlow::ExprNode {
102+
private class ExecaScriptCall extends API::CallNode {
103103
boolean isSync;
104104

105-
ExecaScriptExpr() {
106-
this.asExpr() =
107-
[
108-
API::moduleImport("execa").getMember("$"),
109-
API::moduleImport("execa").getMember("$").getReturn()
110-
].getAValueReachableFromSource().asExpr() and
111-
isSync = false
112-
or
113-
this.asExpr() =
114-
[
115-
API::moduleImport("execa").getMember("$").getMember("sync"),
116-
API::moduleImport("execa").getMember("$").getMember("sync").getReturn()
117-
].getAValueReachableFromSource().asExpr() and
118-
isSync = true
105+
ExecaScriptCall() {
106+
exists(API::Node script |
107+
script =
108+
[
109+
API::moduleImport("execa").getMember("$"),
110+
API::moduleImport("execa").getMember("$").getReturn()
111+
]
112+
|
113+
this = script.getACall() and
114+
isSync = false
115+
or
116+
this = script.getMember("sync").getACall() and
117+
isSync = true
118+
)
119119
}
120120
}
121121

122+
API::Node test() { result = API::moduleImport("execa").getMember("$").getASuccessor*() }
123+
122124
/**
123125
* The system command execution nodes for `execa.$` or `execa.$.sync` tag functions
124126
*/
125-
class ExecaScriptEec extends SystemCommandExecution, ExecaScriptExpr {
126-
ExecaScriptEec() { isSync = [false, true] }
127+
class ExecaScript extends SystemCommandExecution, ExecaScriptCall {
128+
ExecaScript() { isSync = [false, true] }
127129

128-
override DataFlow::Node getACommandArgument() {
129-
exists(TemplateLiteral tl | isFirstTaggedTemplateParameter(this.asExpr(), tl) |
130-
result.asExpr() = tl.getChildExpr(0) and
131-
not result.asExpr().mayHaveStringValue(" ") // exclude whitespace
132-
)
133-
}
130+
override DataFlow::Node getACommandArgument() { result = this.getParameter(1).asSink() }
134131

135132
override predicate isShellInterpreted(DataFlow::Node arg) {
136-
// $({shell: true})`${cmd} ${arg0} ... ${arg1}`
137-
// ISSUE: $`cmd args` I can't reach the tag function argument easily
138-
exists(TemplateLiteral tmpL | isFirstTaggedTemplateParameter(this.asExpr(), tmpL) |
139-
arg.asExpr() = tmpL.getAChildExpr() and
140-
isExecaShellEnableWithExpr(this.asExpr().(CallExpr).getArgument(0)) and
141-
not arg.asExpr().mayHaveStringValue(" ") // exclude whitespace
142-
)
133+
isExecaShellEnable(this.getParameter(0)) and
134+
arg = this.getParameter(0).asSink()
143135
}
144136

145137
override DataFlow::Node getArgumentList() {
146-
// $`${cmd} ${arg0} ... ${argn}`
147-
exists(TemplateLiteral tmpL | isFirstTaggedTemplateParameter(this.asExpr(), tmpL) |
148-
result.asExpr() = tmpL.getAChildExpr() and
149-
not result.asExpr() = tmpL.getChildExpr(0) and
150-
not result.asExpr().mayHaveStringValue(" ") // exclude whitespace
151-
)
138+
result = this.getParameter(any(int i | i > 1)).asSink()
152139
}
153140

154141
override predicate isSync() { isSync = true }
155142

156-
override DataFlow::Node getOptionsArg() {
157-
result = this.asExpr().getAChildExpr().flow() and result.asExpr() instanceof ObjectExpr
158-
}
143+
override DataFlow::Node getOptionsArg() { result = this.getParameter(0).asSink() }
159144
}
160145

161146
/**
@@ -207,28 +192,11 @@ module Execa {
207192
}
208193
}
209194

210-
// Holds if left parameter is the left child of a template literal and returns the template literal
211-
private predicate isFirstTaggedTemplateParameter(Expr left, TemplateLiteral templateLiteral) {
212-
exists(TaggedTemplateExpr parent |
213-
templateLiteral = parent.getTemplate() and
214-
left = parent.getChildExpr(0)
215-
)
216-
}
217-
218195
/**
219196
* Holds whether Execa has shell enabled options or not, get Parameter responsible for options
220197
*/
221198
pragma[inline]
222199
private predicate isExecaShellEnable(API::Node n) {
223200
n.getMember("shell").asSink().asExpr().(BooleanLiteral).getValue() = "true"
224201
}
225-
226-
// Holds whether Execa has shell enabled options or not, get Parameter responsible for options
227-
private predicate isExecaShellEnableWithExpr(Expr n) {
228-
exists(ObjectExpr o, Property p | o = n.getAChildExpr*() |
229-
o.getAChild() = p and
230-
p.getAChild().(Label).getName() = "shell" and
231-
p.getAChild().(Literal).getValue() = "true"
232-
)
233-
}
234202
}

0 commit comments

Comments
 (0)