Merge branch 'main' into CVE760-reexport

This commit is contained in:
Erik Krogh Kristensen
2020-10-06 12:28:44 +02:00
657 changed files with 29823 additions and 7357 deletions

View File

@@ -31,7 +31,7 @@ predicate isStringSplitOrReplace(MethodCallExpr mce) {
mce.getMethodName() = name and
mce.getNumArgument() = arity
|
name = "replace" and arity = 2
name = ["replace", "replaceAll"] and arity = 2
or
name = "split" and
(arity = 1 or arity = 2)

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name External dependencies
* @description Count the number of dependencies a JavaScript source file has on
* NPM packages or framework libraries.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name External dependency source links
* @kind source-link
* @metricType externalDependency

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicated lines in files
* @description The number of lines in a file (including code, comment and whitespace lines)
* occurring in a block of lines that is duplicated at least once somewhere else.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Similar lines in files
* @description The number of lines in a file (including code, comment and whitespace lines)
* occurring in a block of lines that is similar to a block of lines seen

View File

@@ -70,7 +70,7 @@ predicate regExpMatchesString(RegExpTerm t, string s) {
from MethodCallExpr repl, string s, string friendly
where
repl.getMethodName() = "replace" and
repl.getMethodName() = ["replace", "replaceAll"] and
matchesString(repl.getArgument(0), s) and
repl.getArgument(1).getStringValue() = s and
(if s = "" then friendly = "the empty string" else friendly = "'" + s + "'")

View File

@@ -7,7 +7,7 @@
* @id js/incomplete-hostname-regexp
* @tags correctness
* security
* external/cwe/cwe-20
* external/cwe/cwe-020
*/
import javascript

View File

@@ -75,7 +75,7 @@ DataFlow::Node schemeCheck(DataFlow::Node nd, DangerousScheme scheme) {
exists(DataFlow::MethodCallNode stringop |
stringop.getMethodName().matches("trim%") or
stringop.getMethodName().matches("to%Case") or
stringop.getMethodName() = "replace"
stringop.getMethodName() = ["replace", "replaceAll"]
|
result = schemeCheck(stringop, scheme) and
nd = stringop.getReceiver()

View File

@@ -7,7 +7,7 @@
* @id js/incomplete-url-substring-sanitization
* @tags correctness
* security
* external/cwe/cwe-20
* external/cwe/cwe-020
*/
import javascript

View File

@@ -7,7 +7,7 @@
* @id js/regex/missing-regexp-anchor
* @tags correctness
* security
* external/cwe/cwe-20
* external/cwe/cwe-020
*/
import javascript

View File

@@ -9,7 +9,7 @@
* @id js/useless-regexp-character-escape
* @tags correctness
* security
* external/cwe/cwe-20
* external/cwe/cwe-020
*/
import javascript

View File

@@ -50,7 +50,7 @@ system's passwords.
</example>
<references>
<li>OWASP: <a href="https://www.owasp.org/index.php/Path_traversal">Path Traversal</a>.</li>
<li>OWASP: <a href="https://owasp.org/www-community/attacks/Path_Traversal">Path Traversal</a>.</li>
<li>npm: <a href="https://www.npmjs.com/package/sanitize-filename">sanitize-filename</a> package.</li>
</references>
</qhelp>

View File

@@ -60,7 +60,7 @@ Snyk:
</li>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/Path_traversal">Path Traversal</a>.
<a href="https://owasp.org/www-community/attacks/Path_Traversal">Path Traversal</a>.
</li>
</references>

View File

@@ -10,7 +10,7 @@
* @tags correctness
* security
* external/cwe/cwe-116
* external/cwe/cwe-20
* external/cwe/cwe-020
*/
import javascript

View File

@@ -10,7 +10,7 @@
* @tags security
* external/cwe/cwe-079
* external/cwe/cwe-116
* external/cwe/cwe-20
* external/cwe/cwe-020
*/
import javascript

View File

@@ -8,7 +8,7 @@
* @tags correctness
* security
* external/cwe/cwe-116
* external/cwe/cwe-20
* external/cwe/cwe-020
*/
import javascript

View File

@@ -9,7 +9,7 @@
* @tags correctness
* security
* external/cwe/cwe-116
* external/cwe/cwe-20
* external/cwe/cwe-020
*/
import javascript
@@ -79,6 +79,7 @@ predicate allBackslashesEscaped(DataFlow::Node nd) {
// flow through string methods
exists(DataFlow::MethodCallNode mc, string m |
m = "replace" or
m = "replaceAll" or
m = "slice" or
m = "substr" or
m = "substring" or

View File

@@ -52,6 +52,6 @@ will not see the information:
</example>
<references>
<li>OWASP: <a href="https://www.owasp.org/index.php/Information_Leak_(information_disclosure)">Information Leak</a>.</li>
<li>OWASP: <a href="https://owasp.org/www-community/Improper_Error_Handling">Improper Error Handling</a>.</li>
</references>
</qhelp>

View File

@@ -18,8 +18,8 @@ string cookieProperty() { result = "session" or result = "cookies" or result = "
/** Gets a data flow node that flows to the base of an access to `cookies`, `session`, or `user`. */
private DataFlow::SourceNode nodeLeadingToCookieAccess(DataFlow::TypeBackTracker t) {
t.start() and
exists(DataFlow::PropRead value |
value = result.getAPropertyRead(cookieProperty()).getAPropertyRead() and
exists(DataFlow::PropRef value |
value = result.getAPropertyRead(cookieProperty()).getAPropertyReference() and
// Ignore accesses to values that are part of a CSRF or captcha check
not value.getPropertyName().regexpMatch("(?i).*(csrf|xsrf|captcha).*") and
// Ignore calls like `req.session.save()`
@@ -46,7 +46,12 @@ private DataFlow::SourceNode getARouteUsingCookies(DataFlow::TypeTracker t) {
t.start() and
isRouteHandlerUsingCookies(result)
or
exists(DataFlow::TypeTracker t2 | result = getARouteUsingCookies(t2).track(t2, t))
exists(DataFlow::TypeTracker t2, DataFlow::SourceNode pred | pred = getARouteUsingCookies(t2) |
result = pred.track(t2, t)
or
t = t2 and
HTTP::routeHandlerStep(pred, result)
)
}
/** Gets a data flow node referring to a route handler that uses cookies. */

View File

@@ -33,7 +33,7 @@ by <code>xpath</code>:
</example>
<references>
<li>OWASP: <a href="https://www.owasp.org/index.php?title=Testing_for_XPath_Injection_(OTG-INPVAL-010)">Testing for XPath Injection</a>.</li>
<li>OWASP: <a href="https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/09-Testing_for_XPath_Injection">Testing for XPath Injection</a>.</li>
<li>OWASP: <a href="https://www.owasp.org/index.php/XPATH_Injection">XPath Injection</a>.</li>
<li>npm: <a href="https://www.npmjs.com/package/xpath">xpath</a>.</li>
</references>

View File

@@ -8,10 +8,6 @@
- ide-contextual-queries/local-definitions
- ide-contextual-queries/local-references
- query: Comments/FCommentedOutCode.ql
- query: Metrics/Dependencies/ExternalDependencies.ql
- query: Metrics/Dependencies/ExternalDependenciesSourceLinks.ql
- query: Metrics/FLinesOfCode.ql
- query: Metrics/FLinesOfComment.ql
- query: Metrics/FLinesOfDuplicatedCode.ql
- query: Metrics/FLinesOfSimilarCode.ql
- query: Metrics/FNumberOfTests.ql

View File

@@ -31,7 +31,7 @@ Always verify the sender's identity of incoming messages.
<references>
<li><a href="https://cwe.mitre.org/data/definitions/20.html">CWE-20: Improper Input Validation</a></li>
<li><a href="https://cwe.mitre.org/data/definitions/20.html">CWE-020: Improper Input Validation</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage">Window.postMessage()</a></li>
<li><a href="https://portswigger.net/web-security/dom-based/web-message-manipulation">Web-message manipulation</a></li>
<li><a href="https://labs.detectify.com/2016/12/08/the-pitfalls-of-postmessage/">The pitfalls of postMessage</a></li>

View File

@@ -8,7 +8,7 @@
* @id js/missing-postmessageorigin-verification
* @tags correctness
* security
* external/cwe/cwe-20
* external/cwe/cwe-020
*/
import javascript

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicate function
* @description There is another function that shares a lot of code with this function.
* Extract the common parts to a shared utility function to improve maintainability.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicate script
* @description There is another script that shares a lot of code with this script. Consider combining the
* two scripts to improve maintainability.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Similar function
* @description There is another function that shares a lot of code with this function.
* Extract the common parts to a shared utility function to improve maintainability.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Similar script
* @description There is another script that shares a lot of code with this script.
* Extract the common parts to a new script to improve maintainability..

View File

@@ -0,0 +1,15 @@
/**
* @name API-graph edges
* @description The number of edges (other than points-to edges) in the API graph.
* @kind metric
* @metricType project
* @metricAggregate sum
* @tags meta
* @id js/meta/api-graph-edges
*/
import javascript
import meta.MetaMetrics
select projectRoot(),
count(API::Node pred, string lbl, API::Node succ | succ = pred.getASuccessor(lbl))

View File

@@ -0,0 +1,14 @@
/**
* @name API-graph nodes
* @description The number of nodes in the API graph.
* @kind metric
* @metricType project
* @metricAggregate sum
* @tags meta
* @id js/meta/api-graph-nodes
*/
import javascript
import meta.MetaMetrics
select projectRoot(), count(API::Node nd)

View File

@@ -0,0 +1,14 @@
/**
* @name API-graph points-to edges
* @description The number of points-to edges in the API graph.
* @kind metric
* @metricType project
* @metricAggregate sum
* @tags meta
* @id js/meta/api-graph-points-to-edges
*/
import javascript
import meta.MetaMetrics
select projectRoot(), count(API::Node pred, API::Node succ | pred.refersTo(succ))

View File

@@ -0,0 +1,15 @@
/**
* @name API-graph right-hand-side nodes
* @description The number of data-flow nodes corresponding to a right-hand side of
* a definition of an API-graph node.
* @kind metric
* @metricType project
* @metricAggregate sum
* @tags meta
* @id js/meta/api-graph-rhs-nodes
*/
import javascript
import meta.MetaMetrics
select projectRoot(), count(any(API::Node nd).getARhs())

View File

@@ -0,0 +1,14 @@
/**
* @name API-graph use nodes
* @description The number of data-flow nodes corresponding to a use of an API-graph node.
* @kind metric
* @metricType project
* @metricAggregate sum
* @tags meta
* @id js/meta/api-graph-use-nodes
*/
import javascript
import meta.MetaMetrics
select projectRoot(), count(any(API::Node nd).getAUse())

View File

@@ -113,14 +113,14 @@ class AmdModuleDefinition extends CallExpr {
/**
* Gets the `i`th parameter of the factory function of this module.
*/
private SimpleParameter getFactoryParameter(int i) {
private Parameter getFactoryParameter(int i) {
getFactoryNodeInternal().asExpr().(Function).getParameter(i) = result
}
/**
* Gets the parameter corresponding to the pseudo-dependency `require`.
*/
SimpleParameter getRequireParameter() {
Parameter getRequireParameter() {
result = getDependencyParameter("require")
or
// if no dependencies are listed, the first parameter is assumed to be `require`
@@ -133,7 +133,7 @@ class AmdModuleDefinition extends CallExpr {
/**
* Gets the parameter corresponding to the pseudo-dependency `exports`.
*/
SimpleParameter getExportsParameter() {
Parameter getExportsParameter() {
result = getDependencyParameter("exports")
or
// if no dependencies are listed, the second parameter is assumed to be `exports`
@@ -143,7 +143,7 @@ class AmdModuleDefinition extends CallExpr {
/**
* Gets the parameter corresponding to the pseudo-dependency `module`.
*/
SimpleParameter getModuleParameter() {
Parameter getModuleParameter() {
result = getDependencyParameter("module")
or
// if no dependencies are listed, the third parameter is assumed to be `module`

View File

@@ -24,7 +24,10 @@ module API {
* Gets a data-flow node corresponding to a use of the API component represented by this node.
*
* For example, `require('fs').readFileSync` is a use of the function `readFileSync` from the
* `fs` module, and `require('fs').readFileSync(file)` is a use of the result of that function.
* `fs` module, and `require('fs').readFileSync(file)` is a use of the return of that function.
*
* This includes indirect uses found via data flow, meaning that in
* `f(obj.foo); function f(x) {};` both `obj.foo` and `x` are uses of the `foo` member from `obj`.
*
* As another example, in the assignment `exports.plusOne = (x) => x+1` the two references to
* `x` are uses of the first parameter of `plusOne`.
@@ -35,6 +38,34 @@ module API {
)
}
/**
* Gets an immediate use of the API component represented by this node.
*
* For example, `require('fs').readFileSync` is a an immediate use of the `readFileSync` member
* from the `fs` module.
*
* Unlike `getAUse()`, this predicate only gets the immediate references, not the indirect uses
* found via data flow. This means that in `const x = fs.readFile` only `fs.readFile` is a reference
* to the `readFile` member of `fs`, neither `x` nor any node that `x` flows to is a reference to
* this API component.
*/
DataFlow::SourceNode getAnImmediateUse() { Impl::use(this, result) }
/**
* Gets a call to the function represented by this API component.
*/
DataFlow::CallNode getACall() { result = getReturn().getAnImmediateUse() }
/**
* Gets a `new` call to the function represented by this API component.
*/
DataFlow::NewNode getAnInstantiation() { result = getInstance().getAnImmediateUse() }
/**
* Gets an invocation (with our without `new`) to the function represented by this API component.
*/
DataFlow::InvokeNode getAnInvocation() { result = getACall() or result = getAnInstantiation() }
/**
* Gets a data-flow node corresponding to the right-hand side of a definition of the API
* component represented by this node.
@@ -223,6 +254,9 @@ module API {
) and
length in [1 .. Impl::distanceFromRoot(this)]
}
/** Gets the shortest distance from the root to this node in the API graph. */
int getDepth() { result = Impl::distanceFromRoot(this) }
}
/** The root node of an API graph. */
@@ -267,6 +301,9 @@ module API {
/** Gets a data-flow node that defines this entry point. */
abstract DataFlow::Node getARhs();
/** Gets an API-graph node for this entry point. */
API::Node getNode() { result = root().getASuccessor(this) }
}
/**
@@ -409,16 +446,9 @@ module API {
rhs = f.getAReturn()
)
or
exists(DataFlow::SourceNode src, DataFlow::InvokeNode invk |
use(base, src) and invk = trackUseNode(src).getAnInvocation()
|
exists(int i |
lbl = Label::parameter(i) and
rhs = invk.getArgument(i)
)
or
lbl = Label::receiver() and
rhs = invk.(DataFlow::CallNode).getReceiver()
exists(int i |
lbl = Label::parameter(i) and
argumentPassing(base, i, rhs)
)
or
exists(DataFlow::SourceNode src, DataFlow::PropWrite pw |
@@ -429,6 +459,30 @@ module API {
)
}
/**
* Holds if `arg` is passed as the `i`th argument to a use of `base`, either by means of a
* full invocation, or in a partial function application.
*
* The receiver is considered to be argument -1.
*/
private predicate argumentPassing(TApiNode base, int i, DataFlow::Node arg) {
exists(DataFlow::SourceNode use, DataFlow::SourceNode pred |
use(base, use) and pred = trackUseNode(use)
|
arg = pred.getAnInvocation().getArgument(i)
or
arg = pred.getACall().getReceiver() and
i = -1
or
exists(DataFlow::PartialInvokeNode pin, DataFlow::Node callback | pred.flowsTo(callback) |
pin.isPartialArgument(callback, arg, i)
or
arg = pin.getBoundReceiver(callback) and
i = -1
)
)
}
/**
* Holds if `rhs` is the right-hand side of a definition of node `nd`.
*/
@@ -527,7 +581,11 @@ module API {
ref = DataFlow::moduleImport(m)
)
or
exists(DataFlow::ClassNode cls | nd = MkClassInstance(cls) | ref = cls.getAReceiverNode())
exists(DataFlow::ClassNode cls | nd = MkClassInstance(cls) |
ref = cls.getAReceiverNode()
or
ref = cls.(DataFlow::ClassNode::FunctionStyleClass).getAPrototypeReference()
)
or
nd = MkUse(ref)
or
@@ -716,10 +774,14 @@ private module Label {
bindingset[s]
string parameterByStringIndex(string s) {
result = "parameter " + s and
s.toInt() >= 0
s.toInt() >= -1
}
/** Gets the `parameter` edge label for the `i`th parameter. */
/**
* Gets the `parameter` edge label for the `i`th parameter.
*
* The receiver is considered to be parameter -1.
*/
bindingset[i]
string parameter(int i) { result = parameterByStringIndex(i.toString()) }

View File

@@ -24,13 +24,11 @@ module ArrayTaintTracking {
predicate arrayFunctionTaintStep(DataFlow::Node pred, DataFlow::Node succ, DataFlow::CallNode call) {
// `array.map(function (elt, i, ary) { ... })`: if `array` is tainted, then so are
// `elt` and `ary`; similar for `forEach`
exists(string name, Function f, int i |
(name = "map" or name = "forEach") and
(i = 0 or i = 2) and
exists(Function f |
call.getArgument(0).analyze().getAValue().(AbstractFunction).getFunction() = f and
call.(DataFlow::MethodCallNode).getMethodName() = name and
call.(DataFlow::MethodCallNode).getMethodName() = ["map", "forEach"] and
pred = call.getReceiver() and
succ = DataFlow::parameterNode(f.getParameter(i))
succ = DataFlow::parameterNode(f.getParameter([0, 2]))
)
or
// `array.map` with tainted return value in callback
@@ -47,41 +45,22 @@ module ArrayTaintTracking {
succ = call
or
// `array.push(e)`, `array.unshift(e)`: if `e` is tainted, then so is `array`.
exists(string name |
name = "push" or
name = "unshift"
|
pred = call.getAnArgument() and
succ.(DataFlow::SourceNode).getAMethodCall(name) = call
)
pred = call.getAnArgument() and
succ.(DataFlow::SourceNode).getAMethodCall(["push", "unshift"]) = call
or
// `array.push(...e)`, `array.unshift(...e)`: if `e` is tainted, then so is `array`.
exists(string name |
name = "push" or
name = "unshift"
|
pred = call.getASpreadArgument() and
// Make sure we handle reflective calls
succ = call.getReceiver().getALocalSource() and
call.getCalleeName() = name
)
pred = call.getASpreadArgument() and
// Make sure we handle reflective calls
succ = call.getReceiver().getALocalSource() and
call.getCalleeName() = ["push", "unshift"]
or
// `array.splice(i, del, e)`: if `e` is tainted, then so is `array`.
exists(string name | name = "splice" |
pred = call.getArgument(2) and
succ.(DataFlow::SourceNode).getAMethodCall(name) = call
)
pred = call.getArgument(2) and
succ.(DataFlow::SourceNode).getAMethodCall("splice") = call
or
// `e = array.pop()`, `e = array.shift()`, or similar: if `array` is tainted, then so is `e`.
exists(string name |
name = "pop" or
name = "shift" or
name = "slice" or
name = "splice"
|
call.(DataFlow::MethodCallNode).calls(pred, name) and
succ = call
)
call.(DataFlow::MethodCallNode).calls(pred, ["pop", "shift", "slice", "splice"]) and
succ = call
or
// `e = Array.from(x)`: if `x` is tainted, then so is `e`.
call = DataFlow::globalVarRef("Array").getAPropertyRead("from").getACall() and

View File

@@ -117,11 +117,11 @@ class ResolvedES2015PromiseDefinition extends ResolvedPromiseDefinition {
}
/**
* An aggregated promise produced either by `Promise.all` or `Promise.race`.
* An aggregated promise produced either by `Promise.all`, `Promise.race`, or `Promise.any`.
*/
class AggregateES2015PromiseDefinition extends PromiseCreationCall {
AggregateES2015PromiseDefinition() {
exists(string m | m = "all" or m = "race" |
exists(string m | m = "all" or m = "race" or m = "any" |
this = DataFlow::globalVarRef("Promise").getAMemberCall(m)
)
}
@@ -440,6 +440,18 @@ predicate promiseTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
pred.getEnclosingExpr() = await.getOperand() and
succ.getEnclosingExpr() = await
)
or
exists(DataFlow::CallNode mapSeries |
mapSeries = DataFlow::moduleMember("bluebird", "mapSeries").getACall()
|
// from `xs` to `x` in `require("bluebird").mapSeries(xs, (x) => {...})`.
pred = mapSeries.getArgument(0) and
succ = mapSeries.getABoundCallbackParameter(1, 0)
or
// from `y` to `require("bluebird").mapSeries(x, x => y)`.
pred = mapSeries.getCallback(1).getAReturn() and
succ = mapSeries
)
}
/**

View File

@@ -102,7 +102,7 @@ private class IteratorExceptionStep extends DataFlow::MethodCallNode, DataFlow::
*/
class StringReplaceCall extends DataFlow::MethodCallNode {
StringReplaceCall() {
getMethodName() = "replace" and
getMethodName() = ["replace", "replaceAll"] and
(getNumArgument() = 2 or getReceiver().mayHaveStringValue(_))
}
@@ -128,9 +128,9 @@ class StringReplaceCall extends DataFlow::MethodCallNode {
/**
* Holds if this is a global replacement, that is, the first argument is a regular expression
* with the `g` flag.
* with the `g` flag, or this is a call to `.replaceAll()`.
*/
predicate isGlobal() { getRegExp().isGlobal() }
predicate isGlobal() { getRegExp().isGlobal() or getMethodName() = "replaceAll" }
/**
* Holds if this call to `replace` replaces `old` with `new`.

View File

@@ -427,6 +427,7 @@ module TaintTracking {
name = "padStart" or
name = "repeat" or
name = "replace" or
name = "replaceAll" or
name = "slice" or
name = "small" or
name = "split" or
@@ -452,7 +453,7 @@ module TaintTracking {
exists(int i | pred.asExpr() = succ.getAstNode().(MethodCallExpr).getArgument(i) |
name = "concat"
or
name = "replace" and i = 1
name = ["replace", "replaceAll"] and i = 1
)
)
or
@@ -707,7 +708,8 @@ module TaintTracking {
*/
private ControlFlowNode getACaptureSetter(DataFlow::Node input) {
exists(DataFlow::MethodCallNode call | result = call.asExpr() |
call.getMethodName() = ["search", "replace", "match"] and input = call.getReceiver()
call.getMethodName() = ["search", "replace", "replaceAll", "match"] and
input = call.getReceiver()
or
call.getMethodName() = ["test", "exec"] and input = call.getArgument(0)
)

View File

@@ -819,27 +819,27 @@ class LinkFunction extends Function {
/**
* Gets the scope parameter of this function.
*/
SimpleParameter getScopeParameter() { result = getParameter(0) }
Parameter getScopeParameter() { result = getParameter(0) }
/**
* Gets the element parameter of this function (contains a jqLite-wrapped DOM element).
*/
SimpleParameter getElementParameter() { result = getParameter(1) }
Parameter getElementParameter() { result = getParameter(1) }
/**
* Gets the attributes parameter of this function.
*/
SimpleParameter getAttributesParameter() { result = getParameter(2) }
Parameter getAttributesParameter() { result = getParameter(2) }
/**
* Gets the controller parameter of this function.
*/
SimpleParameter getControllerParameter() { result = getParameter(3) }
Parameter getControllerParameter() { result = getParameter(3) }
/**
* Gets the transclude-function parameter of this function.
*/
SimpleParameter getTranscludeFnParameter() { result = getParameter(4) }
Parameter getTranscludeFnParameter() { result = getParameter(4) }
}
/**
@@ -868,7 +868,7 @@ class AngularScope extends TAngularScope {
*/
Expr getAnAccess() {
exists(CustomDirective d | this = d.getAScope() |
exists(SimpleParameter p |
exists(Parameter p |
p = d.getController().getDependencyParameter("$scope") or
p = d.getALinkFunction().getParameter(0)
|
@@ -884,7 +884,7 @@ class AngularScope extends TAngularScope {
d.hasIsolateScope() and result = d.getMember("scope").asExpr()
)
or
exists(DirectiveController c, DOM::ElementDefinition elem, SimpleParameter p |
exists(DirectiveController c, DOM::ElementDefinition elem, Parameter p |
c.boundTo(elem) and
this.mayApplyTo(elem) and
p = c.getFactoryFunction().getDependencyParameter("$scope") and

View File

@@ -41,7 +41,7 @@ abstract class DependencyInjection extends DataFlow::ValueNode {
*/
abstract class InjectableFunction extends DataFlow::ValueNode {
/** Gets the parameter corresponding to dependency `name`. */
abstract SimpleParameter getDependencyParameter(string name);
abstract Parameter getDependencyParameter(string name);
/**
* Gets the `i`th dependency declaration, which is also named `name`.
@@ -67,7 +67,7 @@ abstract class InjectableFunction extends DataFlow::ValueNode {
/**
* Gets a service corresponding to the dependency-injected `parameter`.
*/
ServiceReference getAResolvedDependency(SimpleParameter parameter) {
ServiceReference getAResolvedDependency(Parameter parameter) {
exists(string name, InjectableFunctionServiceRequest request |
this = request.getAnInjectedFunction() and
parameter = getDependencyParameter(name) and
@@ -79,7 +79,7 @@ abstract class InjectableFunction extends DataFlow::ValueNode {
* Gets a Custom service corresponding to the dependency-injected `parameter`.
* (this is a convenience variant of `getAResolvedDependency`)
*/
DataFlow::Node getCustomServiceDependency(SimpleParameter parameter) {
DataFlow::Node getCustomServiceDependency(Parameter parameter) {
exists(CustomServiceDefinition custom |
custom.getServiceReference() = getAResolvedDependency(parameter) and
result = custom.getAService()
@@ -99,11 +99,11 @@ private class FunctionWithImplicitDependencyAnnotation extends InjectableFunctio
not exists(getAPropertyDependencyInjection(astNode))
}
override SimpleParameter getDependencyParameter(string name) {
override Parameter getDependencyParameter(string name) {
result = astNode.getParameterByName(name)
}
override SimpleParameter getDependencyDeclaration(int i, string name) {
override Parameter getDependencyDeclaration(int i, string name) {
result.getName() = name and
result = astNode.getParameter(i)
}
@@ -139,7 +139,7 @@ private class FunctionWithInjectProperty extends InjectableFunction {
)
}
override SimpleParameter getDependencyParameter(string name) {
override Parameter getDependencyParameter(string name) {
exists(int i | exists(getDependencyDeclaration(i, name)) | result = astNode.getParameter(i))
}
@@ -170,7 +170,7 @@ private class FunctionWithExplicitDependencyAnnotation extends InjectableFunctio
function.flowsToExpr(astNode.getElement(astNode.getSize() - 1))
}
override SimpleParameter getDependencyParameter(string name) {
override Parameter getDependencyParameter(string name) {
exists(int i | astNode.getElement(i).mayHaveStringValue(name) |
result = asFunction().getParameter(i)
)

View File

@@ -479,7 +479,7 @@ abstract class ServiceRequest extends Expr {
/**
* Gets the parameter of this request into which `service` is injected.
*/
abstract SimpleParameter getDependencyParameter(ServiceReference service);
abstract Parameter getDependencyParameter(ServiceReference service);
}
/**
@@ -488,7 +488,7 @@ abstract class ServiceRequest extends Expr {
private class LinkFunctionWithScopeInjection extends ServiceRequest {
LinkFunctionWithScopeInjection() { this instanceof LinkFunction }
override SimpleParameter getDependencyParameter(ServiceReference service) {
override Parameter getDependencyParameter(ServiceReference service) {
service instanceof ScopeServiceReference and
result = this.(LinkFunction).getScopeParameter()
}
@@ -521,7 +521,7 @@ class InjectableFunctionServiceRequest extends ServiceRequest {
result.isInjectable()
}
override SimpleParameter getDependencyParameter(ServiceReference service) {
override Parameter getDependencyParameter(ServiceReference service) {
service = injectedFunction.getAResolvedDependency(result)
}
}

View File

@@ -327,6 +327,85 @@ module ClientRequest {
}
}
/**
* Classes for modelling the url request library `needle`.
*/
private module Needle {
/**
* A model of a URL request made using `require("needle")(...)`.
*/
class PromisedNeedleRequest extends ClientRequest::Range {
DataFlow::Node url;
PromisedNeedleRequest() { this = DataFlow::moduleImport("needle").getACall() }
override DataFlow::Node getUrl() { result = getArgument(1) }
override DataFlow::Node getHost() { none() }
override DataFlow::Node getADataNode() {
result = getOptionArgument([2, 3], "headers")
or
result = getArgument(2)
}
override DataFlow::Node getAResponseDataNode(string responseType, boolean promise) {
responseType = "fetch.response" and
promise = true and
result = this
}
}
/**
* A model of a URL request made using `require("needle")[method](...)`.
* E.g. `needle.get("http://example.org", (err, resp, body) => {})`.
*
* As opposed to the calls modeled in `PromisedNeedleRequest` these calls do not return promises.
* Instead they take an optional callback as their last argument.
*/
class NeedleMethodRequest extends ClientRequest::Range {
boolean hasData;
NeedleMethodRequest() {
exists(string method |
method = ["get", "head"] and hasData = false
or
method = ["post", "put", "patch", "delete"] and hasData = true
or
method = "request" and hasData = [true, false]
|
this = DataFlow::moduleMember("needle", method).getACall()
)
}
override DataFlow::Node getUrl() { result = getArgument(0) }
override DataFlow::Node getHost() { none() }
override DataFlow::Node getADataNode() {
hasData = true and
(
result = getArgument(1)
or
result = getOptionArgument(2, "headers")
)
or
hasData = false and
result = getOptionArgument(1, "headers")
}
override DataFlow::Node getAResponseDataNode(string responseType, boolean promise) {
promise = false and
result = this.getABoundCallbackParameter(this.getNumArgument() - 1, 1) and
responseType = "fetch.response"
or
promise = false and
result = this.getABoundCallbackParameter(this.getNumArgument() - 1, 2) and
responseType = "json"
}
}
}
/**
* A model of a URL request made using the `got` library.
*/
@@ -389,6 +468,53 @@ module ClientRequest {
}
}
/**
* Gets an instantiation `socket` of `require("net").Socket` type tracked using `t`.
*/
private DataFlow::SourceNode netSocketInstantiation(
DataFlow::TypeTracker t, DataFlow::NewNode socket
) {
t.start() and
socket = DataFlow::moduleMember("net", "Socket").getAnInstantiation() and
result = socket
or
exists(DataFlow::TypeTracker t2 | result = netSocketInstantiation(t2, socket).track(t2, t))
}
/**
* A model of a request made using `(new require("net").Socket()).connect(args);`.
*/
class NetSocketRequest extends ClientRequest::Range {
DataFlow::NewNode socket;
NetSocketRequest() {
this = netSocketInstantiation(DataFlow::TypeTracker::end(), socket).getAMethodCall("connect")
}
override DataFlow::Node getUrl() {
result = getArgument([0, 1]) // there are multiple overrides of `connect`, and the URL can be in the first or second argument.
}
override DataFlow::Node getHost() { result = getOptionArgument(0, "host") }
override DataFlow::Node getAResponseDataNode(string responseType, boolean promise) {
responseType = "text" and
promise = false and
exists(DataFlow::CallNode call |
call = netSocketInstantiation(DataFlow::TypeTracker::end(), socket).getAMemberCall("on") and
call.getArgument(0).mayHaveStringValue("data") and
result = call.getABoundCallbackParameter(1, 0)
)
}
override DataFlow::Node getADataNode() {
exists(DataFlow::CallNode call |
call = netSocketInstantiation(DataFlow::TypeTracker::end(), socket).getAMemberCall("write") and
result = call.getArgument(0)
)
}
}
/**
* A model of a URL request made using the `superagent` library.
*/

View File

@@ -30,17 +30,17 @@ module Connect {
*
* `kind` is one of: "error", "request", "response", "next".
*/
abstract SimpleParameter getRouteHandlerParameter(string kind);
abstract Parameter getRouteHandlerParameter(string kind);
/**
* Gets the parameter of the route handler that contains the request object.
*/
SimpleParameter getRequestParameter() { result = getRouteHandlerParameter("request") }
Parameter getRequestParameter() { result = getRouteHandlerParameter("request") }
/**
* Gets the parameter of the route handler that contains the response object.
*/
SimpleParameter getResponseParameter() { result = getRouteHandlerParameter("response") }
Parameter getResponseParameter() { result = getRouteHandlerParameter("response") }
}
/**
@@ -51,7 +51,7 @@ module Connect {
StandardRouteHandler() { this = any(RouteSetup setup).getARouteHandler() }
override SimpleParameter getRouteHandlerParameter(string kind) {
override Parameter getRouteHandlerParameter(string kind) {
result = getRouteHandlerParameter(astNode, kind)
}
}
@@ -180,7 +180,7 @@ module Connect {
HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode {
TrackedRouteHandlerCandidateWithSetup() { this = any(RouteSetup s).getARouteHandler() }
override SimpleParameter getRouteHandlerParameter(string kind) {
override Parameter getRouteHandlerParameter(string kind) {
result = getRouteHandlerParameter(astNode, kind)
}
}

View File

@@ -125,9 +125,7 @@ module Express {
exists(DataFlow::TypeBackTracker t2, DataFlow::SourceNode succ | succ = getARouteHandler(t2) |
result = succ.backtrack(t2, t)
or
exists(HTTP::RouteHandlerCandidateContainer container |
result = container.getRouteHandler(succ)
) and
HTTP::routeHandlerStep(result, succ) and
t = t2
)
}
@@ -197,7 +195,7 @@ module Express {
PassportRouteHandler() { this = any(PassportRouteSetup setup).getARouteHandler() }
override SimpleParameter getRouteHandlerParameter(string kind) {
override Parameter getRouteHandlerParameter(string kind) {
kind = "request" and
result = astNode.getParameter(0)
}
@@ -331,17 +329,17 @@ module Express {
*
* `kind` is one of: "error", "request", "response", "next", or "parameter".
*/
abstract SimpleParameter getRouteHandlerParameter(string kind);
abstract Parameter getRouteHandlerParameter(string kind);
/**
* Gets the parameter of the route handler that contains the request object.
*/
SimpleParameter getRequestParameter() { result = getRouteHandlerParameter("request") }
Parameter getRequestParameter() { result = getRouteHandlerParameter("request") }
/**
* Gets the parameter of the route handler that contains the response object.
*/
SimpleParameter getResponseParameter() { result = getRouteHandlerParameter("response") }
Parameter getResponseParameter() { result = getRouteHandlerParameter("response") }
/**
* Gets a request body access of this handler.
@@ -359,7 +357,7 @@ module Express {
StandardRouteHandler() { this = routeSetup.getARouteHandler() }
override SimpleParameter getRouteHandlerParameter(string kind) {
override Parameter getRouteHandlerParameter(string kind) {
if routeSetup.isParameterHandler()
then result = getRouteParameterHandlerParameter(astNode, kind)
else result = getRouteHandlerParameter(astNode, kind)
@@ -507,6 +505,10 @@ module Express {
// `req.cookies`
kind = "cookie" and
this = request.getAPropertyRead("cookies")
or
// `req.files`, treated the same as `req.body`.
kind = "body" and
this = request.getAPropertyRead("files")
)
or
kind = "body" and
@@ -888,7 +890,7 @@ module Express {
TrackedRouteHandlerCandidateWithSetup() { this = routeSetup.getARouteHandler() }
override SimpleParameter getRouteHandlerParameter(string kind) {
override Parameter getRouteHandlerParameter(string kind) {
if routeSetup.isParameterHandler()
then result = getRouteParameterHandlerParameter(astNode, kind)
else result = getRouteHandlerParameter(astNode, kind)

View File

@@ -223,7 +223,7 @@ module Firebase {
RouteHandler() { this = any(RouteSetup setup).getARouteHandler() }
override SimpleParameter getRouteHandlerParameter(string kind) {
override Parameter getRouteHandlerParameter(string kind) {
kind = "request" and result = astNode.getParameter(0)
or
kind = "response" and result = astNode.getParameter(1)

View File

@@ -233,6 +233,74 @@ module HTTP {
ResponseExpr getAResponseExpr() { result.getRouteHandler() = this }
}
/**
* Holds if `call` decorates the function `pred`.
* This means that `call` returns a function that forwards its arguments to `pred`.
* Only holds when the decorator looks like it is decorating a route-handler.
*
* Below is a code example relating `call`, `decoratee`, `outer`, `inner`.
* ```
* function outer(method) {
* return function inner(req, res) {
* return method.call(this, req, res);
* };
* }
* var route = outer(function decoratee(req, res) { // <- call
* res.end("foo");
* });
* ```
*/
private predicate isDecoratedCall(DataFlow::CallNode call, DataFlow::FunctionNode decoratee) {
// indirect route-handler `result` is given to function `outer`, which returns function `inner` which calls the function `pred`.
exists(int i, DataFlow::FunctionNode outer, HTTP::RouteHandlerCandidate inner |
inner = outer.getAReturn().getALocalSource() and
decoratee = call.getArgument(i).getALocalSource() and
outer.getFunction() = call.getACallee() and
hasForwardingHandlerParameter(i, outer, inner)
)
}
/**
* Holds if the `i`th parameter of `outer` has a call that `inner` forwards its parameters to.
*/
private predicate hasForwardingHandlerParameter(
int i, DataFlow::FunctionNode outer, HTTP::RouteHandlerCandidate inner
) {
isAForwardingRouteHandlerCall(outer.getParameter(i), inner)
}
/**
* Holds if `f` looks like a route-handler and a call to `callee` inside `f` forwards all of the parameters from `f` to that call.
*/
private predicate isAForwardingRouteHandlerCall(
DataFlow::SourceNode callee, HTTP::RouteHandlerCandidate f
) {
exists(DataFlow::CallNode call | call = callee.getACall() |
forall(int arg | arg = [0 .. f.getNumParameter() - 1] |
f.getParameter(arg).flowsTo(call.getArgument(arg))
) and
call.getContainer() = f.getFunction()
)
}
/**
* Holds if there exists a step from `pred` to `succ` for a RouteHandler - beyond the usual steps defined by TypeTracking.
*/
predicate routeHandlerStep(DataFlow::SourceNode pred, DataFlow::SourceNode succ) {
isDecoratedCall(succ, pred)
or
// A forwarding call
isAForwardingRouteHandlerCall(pred, succ)
or
// a container containing route-handlers.
exists(HTTP::RouteHandlerCandidateContainer container | pred = container.getRouteHandler(succ))
or
// (function (req, res) {}).bind(this);
exists(DataFlow::PartialInvokeNode call |
succ = call.getBoundFunction(any(DataFlow::Node n | pred.flowsTo(n)), 0)
)
}
/**
* An expression that sets up a route on a server.
*/
@@ -402,6 +470,23 @@ module HTTP {
*/
abstract Expr getServer();
}
/**
* A parameter containing data received by a NodeJS HTTP server.
* E.g. `chunk` in: `http.createServer().on('request', (req, res) => req.on("data", (chunk) => ...))`.
*/
private class ServerRequestDataEvent extends RemoteFlowSource, DataFlow::ParameterNode {
RequestSource req;
ServerRequestDataEvent() {
exists(DataFlow::MethodCallNode mcn | mcn = req.ref().getAMethodCall(EventEmitter::on()) |
mcn.getArgument(0).mayHaveStringValue("data") and
this = mcn.getABoundCallbackParameter(1, 0)
)
}
override string getSourceType() { result = "NodeJS HTTP server data event" }
}
}
/**
@@ -555,7 +640,9 @@ module HTTP {
create.getArgument(0).asExpr() instanceof NullLiteral
)
) and
exists(RouteHandlerCandidate candidate | candidate.flowsTo(getAPropertyWrite().getRhs()))
exists(RouteHandlerCandidate candidate |
getAPossiblyDecoratedHandler(candidate).flowsTo(getAPropertyWrite().getRhs())
)
}
override DataFlow::SourceNode getRouteHandler(DataFlow::SourceNode access) {
@@ -563,7 +650,7 @@ module HTTP {
exists(DataFlow::PropWrite write, DataFlow::PropRead read |
access = read and
ref(this).getAPropertyRead() = read and
result.flowsTo(write.getRhs()) and
getAPossiblyDecoratedHandler(result).flowsTo(write.getRhs()) and
write = this.getAPropertyWrite()
|
write.getPropertyName() = read.getPropertyName()
@@ -571,10 +658,33 @@ module HTTP {
exists(EnumeratedPropName prop | access = prop.getASourceProp())
or
read = DataFlow::lvalueNode(any(ForOfStmt stmt).getLValue())
or
// for forwarding calls to an element where the key is determined by the request.
getRequestParameterRead().flowsToExpr(read.getPropertyNameExpr())
)
}
}
/**
* Gets a (chained) property-read/method-call on the request parameter of the route-handler `f`.
*/
private DataFlow::SourceNode getRequestParameterRead() {
result = any(RouteHandlerCandidate f).getParameter(0)
or
result = getRequestParameterRead().getAPropertyRead()
or
result = getRequestParameterRead().getAMethodCall()
}
/**
* Gets a node that is either `candidate`, or a call that decorates `candidate`.
*/
DataFlow::SourceNode getAPossiblyDecoratedHandler(RouteHandlerCandidate candidate) {
result = candidate
or
isDecoratedCall(result, candidate)
}
/**
* A collection that contains one or more route potential handlers.
*/
@@ -592,13 +702,14 @@ module HTTP {
}
override DataFlow::SourceNode getRouteHandler(DataFlow::SourceNode access) {
result instanceof RouteHandlerCandidate and
exists(
DataFlow::Node input, TypeTrackingPseudoProperty key, CollectionFlowStep store,
CollectionFlowStep load, DataFlow::Node storeTo, DataFlow::Node loadFrom
|
this.flowsTo(storeTo) and
store.store(input, storeTo, key) and
result.(RouteHandlerCandidate).flowsTo(input) and
getAPossiblyDecoratedHandler(result).flowsTo(input) and
ref(this).flowsTo(loadFrom) and
load.load(loadFrom, access, key)
)

View File

@@ -30,7 +30,7 @@ module Hapi {
/**
* Gets the parameter of the route handler that contains the request object.
*/
SimpleParameter getRequestParameter() { result = function.getParameter(0) }
Parameter getRequestParameter() { result = function.getParameter(0) }
}
/**

View File

@@ -47,7 +47,7 @@ module Koa {
/**
* Gets the parameter of the route handler that contains the context object.
*/
SimpleParameter getContextParameter() { result = function.getParameter(0) }
Parameter getContextParameter() { result = function.getParameter(0) }
/**
* Gets an expression that contains the "context" object of

View File

@@ -394,6 +394,52 @@ module LodashUnderscore {
succ = this.getExceptionalReturn()
}
}
/**
* Holds if there is a taint-step involving a (non-function) underscore method from `pred` to `succ`.
*/
private predicate underscoreTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
exists(string name, DataFlow::CallNode call |
call = any(Member member | member.getName() = name).getACall()
|
name =
["find", "filter", "findWhere", "where", "reject", "pluck", "max", "min", "sortBy",
"shuffle", "sample", "toArray", "partition", "compact", "first", "initial", "last",
"rest", "flatten", "without", "difference", "uniq", "unique", "unzip", "transpose",
"object", "chunk", "values", "mapObject", "pick", "omit", "defaults", "clone", "tap",
"identity"] and
pred = call.getArgument(0) and
succ = call
or
name = ["union", "zip"] and
pred = call.getAnArgument() and
succ = call
or
name =
["each", "map", "every", "some", "max", "min", "sortBy", "partition", "mapObject", "tap"] and
pred = call.getArgument(0) and
succ = call.getABoundCallbackParameter(1, 0)
or
name = ["reduce", "reduceRight"] and
pred = call.getArgument(0) and
succ = call.getABoundCallbackParameter(1, 1)
or
name = ["map", "reduce", "reduceRight"] and
pred = call.getCallback(1).getAReturn() and
succ = call
)
}
/**
* A model for taint-steps involving (non-function) underscore methods.
*/
private class UnderscoreTaintStep extends TaintTracking::AdditionalTaintStep {
UnderscoreTaintStep() { underscoreTaintStep(this, _) }
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
underscoreTaintStep(pred, succ) and pred = this
}
}
}
/**

View File

@@ -13,94 +13,39 @@ module NoSQL {
}
/**
* Gets the value of a `$where` property of an object that flows to `n`.
* Gets a value that has been assigned to the "$where" property of an object that flows to `queryArg`.
*/
private DataFlow::Node getADollarWherePropertyValue(DataFlow::Node n) {
result = n.getALocalSource().getAPropertyWrite("$where").getRhs()
private DataFlow::Node getADollarWhereProperty(API::Node queryArg) {
result = queryArg.getMember("$where").getARhs()
}
/**
* Provides classes modeling the MongoDB library.
*/
private module MongoDB {
/**
* Gets an import of MongoDB.
*/
DataFlow::ModuleImportNode mongodb() { result.getPath() = "mongodb" }
/**
* Gets an access to `mongodb.MongoClient`.
*/
private DataFlow::SourceNode getAMongoClient(DataFlow::TypeTracker t) {
t.start() and
(
result = mongodb().getAPropertyRead("MongoClient")
or
exists(DataFlow::ParameterNode p |
p = result and
p = getAMongoDbCallback().getParameter(1) and
not p.getName().toLowerCase() = "db" // mongodb v2 provides a `Db` here
)
)
private API::Node getAMongoClient() {
result = API::moduleImport("mongodb").getMember("MongoClient")
or
exists(DataFlow::TypeTracker t2 | result = getAMongoClient(t2).track(t2, t))
result = getAMongoDbCallback().getParameter(1) and
not result.getAnImmediateUse().(DataFlow::ParameterNode).getName() = "db" // mongodb v2 provides a `Db` here
}
/** Gets an API-graph node that refers to a `connect` callback. */
private API::Node getAMongoDbCallback() {
result = getAMongoClient().getMember("connect").getLastParameter()
}
/**
* Gets an access to `mongodb.MongoClient`.
* Gets an API-graph node that may refer to a MongoDB database connection.
*/
DataFlow::SourceNode getAMongoClient() { result = getAMongoClient(DataFlow::TypeTracker::end()) }
/** Gets a data flow node that leads to a `connect` callback. */
private DataFlow::SourceNode getAMongoDbCallback(DataFlow::TypeBackTracker t) {
t.start() and
result = getAMongoClient().getAMemberCall("connect").getLastArgument().getALocalSource()
private API::Node getAMongoDb() {
result = getAMongoClient().getMember("db").getReturn()
or
exists(DataFlow::TypeBackTracker t2 | result = getAMongoDbCallback(t2).backtrack(t2, t))
}
/** Gets a data flow node that leads to a `connect` callback. */
private DataFlow::FunctionNode getAMongoDbCallback() {
result = getAMongoDbCallback(DataFlow::TypeBackTracker::end())
}
/**
* Gets an expression that may refer to a MongoDB database connection.
*/
private DataFlow::SourceNode getAMongoDb(DataFlow::TypeTracker t) {
t.start() and
(
exists(DataFlow::ParameterNode p |
p = result and
p = getAMongoDbCallback().getParameter(1) and
not p.getName().toLowerCase() = "client" // mongodb v3 provides a `Mongoclient` here
)
or
result = getAMongoClient().getAMethodCall("db")
)
or
exists(DataFlow::TypeTracker t2 | result = getAMongoDb(t2).track(t2, t))
}
/**
* Gets an expression that may refer to a MongoDB database connection.
*/
DataFlow::SourceNode getAMongoDb() { result = getAMongoDb(DataFlow::TypeTracker::end()) }
/**
* A data flow node that may hold a MongoDB collection.
*/
abstract class Collection extends DataFlow::SourceNode { }
/**
* A collection resulting from calling `Db.collection(...)`.
*/
private class CollectionFromDb extends Collection {
CollectionFromDb() {
this = getAMongoDb().getAMethodCall("collection")
or
this = getAMongoDb().getAMethodCall("collection").getCallback(1).getParameter(0)
}
result = getAMongoDbCallback().getParameter(1) and
not result.getAnImmediateUse().(DataFlow::ParameterNode).getName() = "client" // mongodb v3 provides a `Mongoclient` here
}
/**
@@ -109,32 +54,55 @@ private module MongoDB {
* Note that this also covers `mongoose` models since they are subtypes
* of `mongodb.Collection`.
*/
private class CollectionFromType extends Collection {
CollectionFromType() { hasUnderlyingType("mongodb", "Collection") }
private class TypedMongoCollection extends API::EntryPoint {
TypedMongoCollection() { this = "TypedMongoCollection" }
override DataFlow::SourceNode getAUse() { result.hasUnderlyingType("mongodb", "Collection") }
override DataFlow::Node getARhs() { none() }
}
/** Gets a data flow node referring to a MongoDB collection. */
private DataFlow::SourceNode getACollection(DataFlow::TypeTracker t) {
t.start() and
result instanceof Collection
private API::Node getACollection() {
// A collection resulting from calling `Db.collection(...)`.
exists(API::Node collection | collection = getAMongoDb().getMember("collection").getReturn() |
result = collection
or
result = collection.getParameter(1).getParameter(0)
)
or
exists(DataFlow::TypeTracker t2 | result = getACollection(t2).track(t2, t))
result = any(TypedMongoCollection c).getNode()
}
/** Gets a data flow node referring to a MongoDB collection. */
DataFlow::SourceNode getACollection() { result = getACollection(DataFlow::TypeTracker::end()) }
/** A call to a MongoDB query method. */
private class QueryCall extends DatabaseAccess, DataFlow::MethodCallNode {
private class QueryCall extends DatabaseAccess, DataFlow::CallNode {
int queryArgIdx;
API::Node callee;
QueryCall() {
exists(string m | this = getACollection().getAMethodCall(m) |
CollectionMethodSignatures::interpretsArgumentAsQuery(m, queryArgIdx)
)
exists(string method |
CollectionMethodSignatures::interpretsArgumentAsQuery(method, queryArgIdx) and
callee = getACollection().getMember(method)
) and
this = callee.getACall()
}
override DataFlow::Node getAQueryArgument() { result = getArgument(queryArgIdx) }
DataFlow::Node getACodeOperator() {
result = getADollarWhereProperty(callee.getParameter(queryArgIdx))
}
}
/**
* An expression that is interpreted as a MongoDB query.
*/
class Query extends NoSQL::Query {
QueryCall qc;
Query() { this = qc.getAQueryArgument().asExpr() }
override DataFlow::Node getACodeOperator() { result = qc.getACodeOperator() }
}
/**
@@ -194,17 +162,6 @@ private module MongoDB {
)
}
}
/**
* An expression that is interpreted as a MongoDB query.
*/
class Query extends NoSQL::Query {
Query() { this = any(QueryCall qc).getAQueryArgument().asExpr() }
override DataFlow::Node getACodeOperator() {
result = getADollarWherePropertyValue(this.flow())
}
}
}
/**
@@ -214,81 +171,84 @@ private module Mongoose {
/**
* Gets an import of Mongoose.
*/
DataFlow::ModuleImportNode getAMongooseInstance() { result.getPath() = "mongoose" }
API::Node getAMongooseInstance() { result = API::moduleImport("mongoose") }
/**
* Gets a call to `mongoose.createConnection`.
* Gets a reference to `mongoose.createConnection`.
*/
DataFlow::CallNode createConnection() {
result = getAMongooseInstance().getAMemberCall("createConnection")
}
API::Node createConnection() { result = getAMongooseInstance().getMember("createConnection") }
/**
* A Mongoose function invocation.
* A Mongoose function.
*/
private class InvokeNode extends DataFlow::InvokeNode {
private class MongooseFunction extends API::Node {
/**
* Holds if this invocation returns an object of type `Query`.
* Gets the API-graph node for the result from this function (if the function returns a `Query`).
*/
abstract predicate returnsQuery();
abstract API::Node getQueryReturn();
/**
* Holds if this invocation returns a `Query` that evaluates to one or
* Holds if this function returns a `Query` that evaluates to one or
* more Documents (`asArray` is false if it evaluates to a single
* Document).
*/
abstract predicate returnsDocumentQuery(boolean asArray);
/**
* Holds if this invocation interprets `arg` as a query.
* Gets an argument that this function interprets as a query.
*/
abstract predicate interpretsArgumentAsQuery(DataFlow::Node arg);
abstract API::Node getQueryArgument();
}
/**
* Provides classes modeling the Mongoose Model class
*/
module Model {
private class ModelInvokeNode extends InvokeNode, DataFlow::MethodCallNode {
ModelInvokeNode() { this = ref().getAMethodCall() }
private class ModelFunction extends MongooseFunction {
string methodName;
override predicate returnsQuery() { MethodSignatures::returnsQuery(getMethodName()) }
ModelFunction() { this = getModelObject().getMember(methodName) }
override API::Node getQueryReturn() {
MethodSignatures::returnsQuery(methodName) and result = this.getReturn()
}
override predicate returnsDocumentQuery(boolean asArray) {
MethodSignatures::returnsDocumentQuery(getMethodName(), asArray)
MethodSignatures::returnsDocumentQuery(methodName, asArray)
}
override predicate interpretsArgumentAsQuery(DataFlow::Node arg) {
override API::Node getQueryArgument() {
exists(int n |
MethodSignatures::interpretsArgumentAsQuery(this.getMethodName(), n) and
arg = this.getArgument(n)
MethodSignatures::interpretsArgumentAsQuery(methodName, n) and
result = this.getParameter(n)
)
}
}
/**
* Gets a data flow node referring to a Mongoose Model object.
* A Mongoose collection based on the type `mongoose.Model`.
*/
private DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
(
result = getAMongooseInstance().getAMemberCall("model")
or
exists(DataFlow::SourceNode conn | conn = createConnection() |
result = conn.getAMemberCall("model") or
result = conn.getAPropertyRead("models").getAPropertyRead()
)
or
result.hasUnderlyingType("mongoose", "Model")
) and
t.start()
or
exists(DataFlow::TypeTracker t2 | result = ref(t2).track(t2, t))
private class TypedMongooseModel extends API::EntryPoint {
TypedMongooseModel() { this = "TypedMongooseModel" }
override DataFlow::SourceNode getAUse() { result.hasUnderlyingType("mongoose", "Model") }
override DataFlow::Node getARhs() { none() }
}
/**
* Gets a data flow node referring to a Mongoose model object.
* Gets a API-graph node referring to a Mongoose Model object.
*/
DataFlow::SourceNode ref() { result = ref(DataFlow::TypeTracker::end()) }
private API::Node getModelObject() {
result = getAMongooseInstance().getMember("model").getReturn()
or
exists(API::Node conn | conn = createConnection().getReturn() |
result = conn.getMember("model").getReturn() or
result = conn.getMember("models").getAMember()
)
or
result = any(TypedMongooseModel c).getNode()
}
/**
* Provides signatures for the Model methods.
@@ -350,58 +310,62 @@ private module Mongoose {
* Provides classes modeling the Mongoose Query class
*/
module Query {
private class QueryInvokeNode extends InvokeNode, DataFlow::MethodCallNode {
QueryInvokeNode() { this = ref().getAMethodCall() }
private class QueryFunction extends MongooseFunction {
string methodName;
override predicate returnsQuery() { MethodSignatures::returnsQuery(getMethodName()) }
QueryFunction() { this = getAMongooseQuery().getMember(methodName) }
override predicate returnsDocumentQuery(boolean asArray) {
MethodSignatures::returnsDocumentQuery(getMethodName(), asArray)
override API::Node getQueryReturn() {
MethodSignatures::returnsQuery(methodName) and result = this.getReturn()
}
override predicate interpretsArgumentAsQuery(DataFlow::Node arg) {
override predicate returnsDocumentQuery(boolean asArray) {
MethodSignatures::returnsDocumentQuery(methodName, asArray)
}
override API::Node getQueryArgument() {
exists(int n |
MethodSignatures::interpretsArgumentAsQuery(this.getMethodName(), n) and
arg = this.getArgument(n)
MethodSignatures::interpretsArgumentAsQuery(methodName, n) and
result = this.getParameter(n)
)
}
}
private class NewQueryInvokeNode extends InvokeNode {
NewQueryInvokeNode() {
this = getAMongooseInstance().getAPropertyRead("Query").getAnInstantiation()
}
private class NewQueryFunction extends MongooseFunction {
NewQueryFunction() { this = getAMongooseInstance().getMember("Query") }
override predicate returnsQuery() { any() }
override API::Node getQueryReturn() { result = this.getInstance() }
override predicate returnsDocumentQuery(boolean asArray) { none() }
override predicate interpretsArgumentAsQuery(DataFlow::Node arg) { arg = this.getArgument(2) }
override API::Node getQueryArgument() { result = this.getParameter(2) }
}
/**
* A Mongoose query.
*/
private class TypedMongooseQuery extends API::EntryPoint {
TypedMongooseQuery() { this = "TypedMongooseQuery" }
override DataFlow::SourceNode getAUse() { result.hasUnderlyingType("mongoose", "Query") }
override DataFlow::Node getARhs() { none() }
}
/**
* Gets a data flow node referring to a Mongoose query object.
*/
private DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
(
result.(InvokeNode).returnsQuery() or
result.hasUnderlyingType("mongoose", "Query")
) and
t.start()
API::Node getAMongooseQuery() {
result = any(MongooseFunction f).getQueryReturn()
or
exists(DataFlow::TypeTracker t2, DataFlow::SourceNode succ | succ = ref(t2) |
result = succ.track(t2, t)
or
result = succ.getAMethodCall(any(string name | MethodSignatures::returnsQuery(name))) and
t = t2.continue()
)
result = any(TypedMongooseQuery c).getNode()
or
result =
getAMongooseQuery()
.getMember(any(string name | MethodSignatures::returnsQuery(name)))
.getReturn()
}
/**
* Gets a data flow node referring to a Mongoose query object.
*/
DataFlow::SourceNode ref() { result = ref(DataFlow::TypeTracker::end()) }
/**
* Provides signatures for the Query methods.
*/
@@ -541,19 +505,23 @@ private module Mongoose {
* Provides classes modeling the Mongoose Document class
*/
module Document {
private class DocumentInvokeNode extends InvokeNode, DataFlow::MethodCallNode {
DocumentInvokeNode() { this = ref().getAMethodCall() }
private class DocumentFunction extends MongooseFunction {
string methodName;
override predicate returnsQuery() { MethodSignatures::returnsQuery(getMethodName()) }
DocumentFunction() { this = getAMongooseDocument().getMember(methodName) }
override predicate returnsDocumentQuery(boolean asArray) {
MethodSignatures::returnsDocumentQuery(getMethodName(), asArray)
override API::Node getQueryReturn() {
MethodSignatures::returnsQuery(methodName) and result = this.getReturn()
}
override predicate interpretsArgumentAsQuery(DataFlow::Node arg) {
override predicate returnsDocumentQuery(boolean asArray) {
MethodSignatures::returnsDocumentQuery(methodName, asArray)
}
override API::Node getQueryArgument() {
exists(int n |
MethodSignatures::interpretsArgumentAsQuery(this.getMethodName(), n) and
arg = this.getArgument(n)
MethodSignatures::interpretsArgumentAsQuery(methodName, n) and
result = this.getParameter(n)
)
}
}
@@ -561,67 +529,59 @@ private module Mongoose {
/**
* A Mongoose Document that is retrieved from the backing database.
*/
class RetrievedDocument extends DataFlow::SourceNode {
class RetrievedDocument extends API::Node {
RetrievedDocument() {
exists(boolean asArray, DataFlow::ParameterNode param |
exists(InvokeNode call |
call.returnsDocumentQuery(asArray) and
param = call.getCallback(call.getNumArgument() - 1).getParameter(1)
exists(boolean asArray, API::Node param |
exists(MongooseFunction func |
func.returnsDocumentQuery(asArray) and
param = func.getLastParameter().getParameter(1)
)
or
exists(
DataFlow::SourceNode base, DataFlow::MethodCallNode call, string executor,
int paramIndex
|
executor = "then" and paramIndex = 0
exists(API::Node f |
f = Query::getAMongooseQuery().getMember("then") and
param = f.getParameter(0).getParameter(0)
or
executor = "exec" and paramIndex = 1
f = Query::getAMongooseQuery().getMember("exec") and
param = f.getParameter(0).getParameter(1)
|
base = Query::ref() and
call = base.getAMethodCall(executor) and
param = call.getCallback(0).getParameter(paramIndex) and
exists(DataFlow::MethodCallNode pred |
// limitation: look at the previous method call
// limitation: look at the previous method call
Query::MethodSignatures::returnsDocumentQuery(pred.getMethodName(), asArray) and
pred.getAMethodCall() = call
pred.getAMethodCall() = f.getACall()
)
)
|
asArray = false and this = param
or
asArray = true and
exists(DataFlow::PropRead access |
// limitation: look for direct accesses
access = param.getAPropertyRead() and
not exists(access.getPropertyName()) and
this = access
)
// limitation: look for direct accesses
this = param.getUnknownMember()
)
}
}
/**
* Gets a data flow node referring to a Mongoose Document object.
* A Mongoose document.
*/
private DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
(
result instanceof RetrievedDocument or
result.hasUnderlyingType("mongoose", "Document")
) and
t.start()
or
exists(DataFlow::TypeTracker t2, DataFlow::SourceNode succ | succ = ref(t2) |
result = succ.track(t2, t)
or
result = succ.getAMethodCall(any(string name | MethodSignatures::returnsDocument(name))) and
t = t2.continue()
)
private class TypedMongooseDocument extends API::EntryPoint {
TypedMongooseDocument() { this = "TypedMongooseDocument" }
override DataFlow::SourceNode getAUse() { result.hasUnderlyingType("mongoose", "Document") }
override DataFlow::Node getARhs() { none() }
}
/**
* Gets a data flow node referring to a Mongoose Document object.
*/
DataFlow::SourceNode ref() { result = ref(DataFlow::TypeTracker::end()) }
private API::Node getAMongooseDocument() {
result instanceof RetrievedDocument or
result = any(TypedMongooseDocument c).getNode() or
result =
getAMongooseDocument()
.getMember(any(string name | MethodSignatures::returnsDocument(name)))
.getReturn()
}
private module MethodSignatures {
/**
@@ -679,7 +639,9 @@ private module Mongoose {
string kind;
Credentials() {
exists(string prop | this = createConnection().getOptionArgument(3, prop).asExpr() |
exists(string prop |
this = createConnection().getParameter(3).getMember(prop).getARhs().asExpr()
|
prop = "user" and kind = "user name"
or
prop = "pass" and kind = "password"
@@ -693,38 +655,38 @@ private module Mongoose {
* An expression that is interpreted as a (part of a) MongoDB query.
*/
class MongoDBQueryPart extends NoSQL::Query {
MongoDBQueryPart() { any(InvokeNode call).interpretsArgumentAsQuery(this.flow()) }
MongooseFunction f;
MongoDBQueryPart() { this = f.getQueryArgument().getARhs().asExpr() }
override DataFlow::Node getACodeOperator() {
result = getADollarWherePropertyValue(this.flow())
result = getADollarWhereProperty(f.getQueryArgument())
}
}
/**
* An evaluation of a MongoDB query.
*/
class ShorthandQueryEvaluation extends DatabaseAccess {
InvokeNode invk;
class ShorthandQueryEvaluation extends DatabaseAccess, DataFlow::InvokeNode {
MongooseFunction f;
ShorthandQueryEvaluation() {
this = invk and
this = f.getACall() and
// shorthand for execution: provide a callback
invk.returnsQuery() and
exists(invk.getCallback(invk.getNumArgument() - 1))
exists(f.getQueryReturn()) and
exists(this.getCallback(this.getNumArgument() - 1))
}
override DataFlow::Node getAQueryArgument() {
// NB: the complete information is not easily accessible for deeply chained calls
invk.interpretsArgumentAsQuery(result)
f.getQueryArgument().getARhs() = result
}
}
class ExplicitQueryEvaluation extends DatabaseAccess {
ExplicitQueryEvaluation() {
// explicit execution using a Query method call
exists(string executor | executor = "exec" or executor = "then" or executor = "catch" |
Query::ref().getAMethodCall(executor) = this
)
Query::getAMongooseQuery().getMember(["exec", "then", "catch"]).getACall() = this
}
override DataFlow::Node getAQueryArgument() {
@@ -738,26 +700,6 @@ private module Mongoose {
* Provides classes modeling the Minimongo library.
*/
private module Minimongo {
/**
* Gets an expression that may refer to a Minimongo database.
*/
private DataFlow::SourceNode getADb(DataFlow::TypeTracker t) {
t.start() and
// new (require('minimongo')[DBKINDNAME])()
result = DataFlow::moduleImport("minimongo").getAPropertyRead().getAnInvocation()
or
exists(DataFlow::TypeTracker t2 | result = getADb(t2).track(t2, t))
}
/** Gets a data flow node referring to a Minimongo collection. */
private DataFlow::SourceNode getACollection(DataFlow::TypeTracker t) {
t.start() and
// db[COLLECTIONNAME]
result = getADb(DataFlow::TypeTracker::end()).getAPropertyRead()
or
exists(DataFlow::TypeTracker t2 | result = getACollection(t2).track(t2, t))
}
/**
* Provides signatures for the Collection methods.
*/
@@ -774,25 +716,32 @@ private module Minimongo {
/** A call to a Minimongo query method. */
private class QueryCall extends DatabaseAccess, DataFlow::MethodCallNode {
int queryArgIdx;
API::Node callee;
QueryCall() {
exists(string m | this = getACollection(DataFlow::TypeTracker::end()).getAMethodCall(m) |
exists(string m |
callee = API::moduleImport("minimongo").getAMember().getReturn().getAMember().getMember(m) and
this = callee.getACall() and
CollectionMethodSignatures::interpretsArgumentAsQuery(m, queryArgIdx)
)
}
override DataFlow::Node getAQueryArgument() { result = getArgument(queryArgIdx) }
DataFlow::Node getACodeOperator() {
result = getADollarWhereProperty(callee.getParameter(queryArgIdx))
}
}
/**
* An expression that is interpreted as a Minimongo query.
*/
class Query extends NoSQL::Query {
Query() { this = any(QueryCall qc).getAQueryArgument().asExpr() }
QueryCall qc;
override DataFlow::Node getACodeOperator() {
result = getADollarWherePropertyValue(this.flow())
}
Query() { this = qc.getAQueryArgument().asExpr() }
override DataFlow::Node getACodeOperator() { result = qc.getACodeOperator() }
}
}
@@ -800,49 +749,35 @@ private module Minimongo {
* Provides classes modeling the MarsDB library.
*/
private module MarsDB {
/**
* Gets an expression that may refer to a MarsDB database.
*/
private DataFlow::SourceNode getADb(DataFlow::TypeTracker t) {
t.start() and
// Collection = require('marsdb')
result = DataFlow::moduleImport("marsdb")
or
exists(DataFlow::TypeTracker t2 | result = getADb(t2).track(t2, t))
}
/** Gets a data flow node referring to a MarsDB collection. */
private DataFlow::SourceNode getACollection(DataFlow::TypeTracker t) {
t.start() and
// new Collection(...)
result =
getADb(DataFlow::TypeTracker::end()).getAPropertyRead("Collection").getAnInstantiation()
or
exists(DataFlow::TypeTracker t2 | result = getACollection(t2).track(t2, t))
}
/** A call to a MarsDB query method. */
private class QueryCall extends DatabaseAccess, DataFlow::MethodCallNode {
int queryArgIdx;
API::Node callee;
QueryCall() {
exists(string m | this = getACollection(DataFlow::TypeTracker::end()).getAMethodCall(m) |
exists(string m |
callee = API::moduleImport("marsdb").getMember("Collection").getInstance().getMember(m) and
this = callee.getACall() and
// implements parts of the Minimongo interface
Minimongo::CollectionMethodSignatures::interpretsArgumentAsQuery(m, queryArgIdx)
)
}
override DataFlow::Node getAQueryArgument() { result = getArgument(queryArgIdx) }
DataFlow::Node getACodeOperator() {
result = getADollarWhereProperty(callee.getParameter(queryArgIdx))
}
}
/**
* An expression that is interpreted as a MarsDB query.
*/
class Query extends NoSQL::Query {
Query() { this = any(QueryCall qc).getAQueryArgument().asExpr() }
QueryCall qc;
override DataFlow::Node getACodeOperator() {
result = getADollarWherePropertyValue(this.flow())
}
Query() { this = qc.getAQueryArgument().asExpr() }
override DataFlow::Node getACodeOperator() { result = qc.getACodeOperator() }
}
}

View File

@@ -91,12 +91,12 @@ module NodeJSLib {
/**
* Gets the parameter of the route handler that contains the request object.
*/
SimpleParameter getRequestParameter() { result = getFunction().getParameter(0) }
Parameter getRequestParameter() { result = getFunction().getParameter(0) }
/**
* Gets the parameter of the route handler that contains the response object.
*/
SimpleParameter getResponseParameter() { result = getFunction().getParameter(1) }
Parameter getResponseParameter() { result = getFunction().getParameter(1) }
}
/**
@@ -228,7 +228,12 @@ module NodeJSLib {
t.start() and
result = handler.flow().getALocalSource()
or
exists(DataFlow::TypeBackTracker t2 | result = getARouteHandler(t2).backtrack(t2, t))
exists(DataFlow::TypeBackTracker t2, DataFlow::SourceNode succ | succ = getARouteHandler(t2) |
result = succ.backtrack(t2, t)
or
t = t2 and
HTTP::routeHandlerStep(result, succ)
)
}
override Expr getServer() { result = server }
@@ -735,16 +740,8 @@ module NodeJSLib {
astNode.getParameter(0).getName() = request and
astNode.getParameter(1).getName() = response
|
not (
// heuristic: not a class method (Node.js invokes this with a function call)
astNode = any(MethodDefinition def).getBody()
or
// heuristic: does not return anything (Node.js will not use the return value)
exists(astNode.getAReturnStmt().getExpr())
or
// heuristic: is not invoked (Node.js invokes this at a call site we cannot reason precisely about)
exists(DataFlow::InvokeNode cs | cs.getACallee() = astNode)
)
// heuristic: not a class method (Node.js invokes this with a function call)
not astNode = any(MethodDefinition def).getBody()
)
}
}
@@ -1082,8 +1079,10 @@ module NodeJSLib {
/**
* An instance of net.createServer(), which creates a new TCP/IPC server.
*/
private class NodeJSNetServer extends DataFlow::SourceNode {
NodeJSNetServer() { this = DataFlow::moduleMember("net", "createServer").getAnInvocation() }
class NodeJSNetServer extends DataFlow::InvokeNode {
NodeJSNetServer() {
this = DataFlow::moduleMember(["net", "tls"], "createServer").getAnInvocation()
}
private DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
t.start() and result = this
@@ -1110,6 +1109,8 @@ module NodeJSLib {
|
this = call.getCallback(1).getParameter(0)
)
or
this = server.getCallback([0, 1]).getParameter(0)
}
DataFlow::SourceNode ref() { result = EventEmitter::trackEventEmitter(this) }

View File

@@ -30,12 +30,12 @@ module Restify {
/**
* Gets the parameter of the route handler that contains the request object.
*/
SimpleParameter getRequestParameter() { result = function.getParameter(0) }
Parameter getRequestParameter() { result = function.getParameter(0) }
/**
* Gets the parameter of the route handler that contains the response object.
*/
SimpleParameter getResponseParameter() { result = function.getParameter(1) }
Parameter getResponseParameter() { result = function.getParameter(1) }
}
/**

View File

@@ -31,24 +31,27 @@ private module MySql {
/** Gets the package name `mysql` or `mysql2`. */
API::Node mysql() { result = API::moduleImport(["mysql", "mysql2"]) }
/** Gets a call to `mysql.createConnection`. */
API::Node createConnection() { result = mysql().getMember("createConnection").getReturn() }
/** Gets a reference to `mysql.createConnection`. */
API::Node createConnection() { result = mysql().getMember("createConnection") }
/** Gets a call to `mysql.createPool`. */
API::Node createPool() { result = mysql().getMember("createPool").getReturn() }
/** Gets a reference to `mysql.createPool`. */
API::Node createPool() { result = mysql().getMember("createPool") }
/** Gets a node that contains a MySQL pool created using `mysql.createPool()`. */
API::Node pool() { result = createPool().getReturn() }
/** Gets a data flow node that contains a freshly created MySQL connection instance. */
API::Node connection() {
result = createConnection()
result = createConnection().getReturn()
or
result = createPool().getMember("getConnection").getParameter(0).getParameter(1)
result = pool().getMember("getConnection").getParameter(0).getParameter(1)
}
/** A call to the MySql `query` method. */
private class QueryCall extends DatabaseAccess, DataFlow::MethodCallNode {
QueryCall() {
exists(API::Node recv | recv = createPool() or recv = connection() |
this = recv.getMember("query").getReturn().getAUse()
exists(API::Node recv | recv = pool() or recv = connection() |
this = recv.getMember("query").getACall()
)
}
@@ -63,12 +66,7 @@ private module MySql {
/** A call to the `escape` or `escapeId` method that performs SQL sanitization. */
class EscapingSanitizer extends SQL::SqlSanitizer, MethodCallExpr {
EscapingSanitizer() {
this =
[mysql(), createPool(), connection()]
.getMember(["escape", "escapeId"])
.getReturn()
.getAUse()
.asExpr() and
this = [mysql(), pool(), connection()].getMember(["escape", "escapeId"]).getACall().asExpr() and
input = this.getArgument(0) and
output = this
}
@@ -79,9 +77,9 @@ private module MySql {
string kind;
Credentials() {
exists(API::Node call, string prop |
call in [createConnection(), createPool()] and
call.getAUse().asExpr().(CallExpr).hasOptionArgument(0, prop, this) and
exists(API::Node callee, string prop |
callee in [createConnection(), createPool()] and
this = callee.getParameter(0).getMember(prop).getARhs().asExpr() and
(
prop = "user" and kind = "user name"
or
@@ -98,29 +96,32 @@ private module MySql {
* Provides classes modelling the `pg` package.
*/
private module Postgres {
/** Gets an expression of the form `new require('pg').Client()`. */
API::Node newClient() { result = API::moduleImport("pg").getMember("Client").getInstance() }
/** Gets a reference to the `Client` constructor in the `pg` package, for example `require('pg').Client`. */
API::Node newClient() { result = API::moduleImport("pg").getMember("Client") }
/** Gets a data flow node that holds a freshly created Postgres client instance. */
/** Gets a freshly created Postgres client instance. */
API::Node client() {
result = newClient()
result = newClient().getInstance()
or
// pool.connect(function(err, client) { ... })
result = newPool().getMember("connect").getParameter(0).getParameter(1)
result = pool().getMember("connect").getParameter(0).getParameter(1)
}
/** Gets a constructor that when invoked constructs a new connection pool. */
API::Node newPool() {
// new require('pg').Pool()
result = API::moduleImport("pg").getMember("Pool")
or
// new require('pg-pool')
result = API::moduleImport("pg-pool")
}
/** Gets an expression that constructs a new connection pool. */
API::Node newPool() {
// new require('pg').Pool()
result = API::moduleImport("pg").getMember("Pool").getInstance()
or
// new require('pg-pool')
result = API::moduleImport("pg-pool").getInstance()
}
API::Node pool() { result = newPool().getInstance() }
/** A call to the Postgres `query` method. */
private class QueryCall extends DatabaseAccess, DataFlow::MethodCallNode {
QueryCall() { this = [client(), newPool()].getMember("query").getReturn().getAUse() }
QueryCall() { this = [client(), pool()].getMember("query").getACall() }
override DataFlow::Node getAQueryArgument() { result = getArgument(0) }
}
@@ -135,9 +136,8 @@ private module Postgres {
string kind;
Credentials() {
exists(DataFlow::InvokeNode call, string prop |
call = [client(), newPool()].getAUse() and
this = call.getOptionArgument(0, prop).asExpr() and
exists(string prop |
this = [newClient(), newPool()].getParameter(0).getMember(prop).getARhs().asExpr() and
(
prop = "user" and kind = "user name"
or
@@ -178,7 +178,7 @@ private module Sqlite {
meth = "prepare" or
meth = "run"
|
this = newDb().getMember(meth).getReturn().getAUse()
this = newDb().getMember(meth).getACall()
)
}
@@ -222,7 +222,7 @@ private module MsSql {
/** A call to a MsSql query method. */
private class QueryCall extends DatabaseAccess, DataFlow::MethodCallNode {
QueryCall() { this = request().getMember(["query", "batch"]).getReturn().getAUse() }
QueryCall() { this = request().getMember(["query", "batch"]).getACall() }
override DataFlow::Node getAQueryArgument() { result = getArgument(0) }
}
@@ -250,13 +250,13 @@ private module MsSql {
string kind;
Credentials() {
exists(DataFlow::InvokeNode call, string prop |
exists(API::Node callee, string prop |
(
call = mssql().getMember("connect").getReturn().getAUse()
callee = mssql().getMember("connect")
or
call = mssql().getMember("ConnectionPool").getInstance().getAUse()
callee = mssql().getMember("ConnectionPool")
) and
this = call.getOptionArgument(0, prop).asExpr() and
this = callee.getParameter(0).getMember(prop).getARhs().asExpr() and
(
prop = "user" and kind = "user name"
or
@@ -281,7 +281,7 @@ private module Sequelize {
/** A call to `Sequelize.query`. */
private class QueryCall extends DatabaseAccess, DataFlow::MethodCallNode {
QueryCall() { this = newSequelize().getMember("query").getReturn().getAUse() }
QueryCall() { this = newSequelize().getMember("query").getACall() }
override DataFlow::Node getAQueryArgument() { result = getArgument(0) }
}
@@ -300,7 +300,7 @@ private module Sequelize {
Credentials() {
exists(NewExpr ne, string prop |
ne = newSequelize().getAUse().asExpr() and
ne = sequelize().getAnInstantiation().asExpr() and
(
this = ne.getArgument(1) and prop = "username"
or
@@ -378,8 +378,7 @@ private module Spanner {
*/
class DatabaseRunCall extends SqlExecution {
DatabaseRunCall() {
this =
database().getMember(["run", "runPartitionedUpdate", "runStream"]).getReturn().getAUse()
this = database().getMember(["run", "runPartitionedUpdate", "runStream"]).getACall()
}
}
@@ -388,7 +387,7 @@ private module Spanner {
*/
class TransactionRunCall extends SqlExecution {
TransactionRunCall() {
this = transaction().getMember(["run", "runStream", "runUpdate"]).getReturn().getAUse()
this = transaction().getMember(["run", "runStream", "runUpdate"]).getACall()
}
}
@@ -397,8 +396,7 @@ private module Spanner {
*/
class ExecuteSqlCall extends SqlExecution {
ExecuteSqlCall() {
this =
v1SpannerClient().getMember(["executeSql", "executeStreamingSql"]).getReturn().getAUse()
this = v1SpannerClient().getMember(["executeSql", "executeStreamingSql"]).getACall()
}
override DataFlow::Node getAQueryArgument() {

View File

@@ -29,7 +29,7 @@ private class PromotedExpressCandidate extends Express::RouteHandler,
HTTP::Servers::StandardRouteHandler {
PromotedExpressCandidate() { this instanceof ConnectExpressShared::RouteHandlerCandidate }
override SimpleParameter getRouteHandlerParameter(string kind) {
override Parameter getRouteHandlerParameter(string kind) {
result = ConnectExpressShared::getRouteHandlerParameter(getAstNode(), kind)
}
}
@@ -41,7 +41,7 @@ private class PromotedConnectCandidate extends Connect::RouteHandler,
HTTP::Servers::StandardRouteHandler {
PromotedConnectCandidate() { this instanceof ConnectExpressShared::RouteHandlerCandidate }
override SimpleParameter getRouteHandlerParameter(string kind) {
override Parameter getRouteHandlerParameter(string kind) {
result = ConnectExpressShared::getRouteHandlerParameter(getAstNode(), kind)
}
}

View File

@@ -15,9 +15,7 @@ abstract class HeuristicAdditionalTaintStep extends DataFlow::ValueNode { }
* A call to `tainted.replace(x, y)` that preserves taint.
*/
private class HeuristicStringManipulationTaintStep extends HeuristicAdditionalTaintStep,
TaintTracking::AdditionalTaintStep, DataFlow::MethodCallNode {
HeuristicStringManipulationTaintStep() { getMethodName() = "replace" }
TaintTracking::AdditionalTaintStep, StringReplaceCall {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
pred = getReceiver() and succ = this
}

View File

@@ -34,15 +34,11 @@ module CleartextLogging {
/**
* A call to `.replace()` that seems to mask sensitive information.
*/
class MaskingReplacer extends Barrier, DataFlow::MethodCallNode {
class MaskingReplacer extends Barrier, StringReplaceCall {
MaskingReplacer() {
this.getCalleeName() = "replace" and
exists(RegExpLiteral reg |
reg = this.getArgument(0).getALocalSource().asExpr() and
reg.isGlobal() and
any(RegExpDot term).getLiteral() = reg
) and
exists(this.getArgument(1).getStringValue())
this.isGlobal() and
exists(this.getRawReplacement().getStringValue()) and
any(RegExpDot term).getLiteral() = getRegExp().asExpr()
}
}

View File

@@ -65,7 +65,7 @@ module ClientSideUrlRedirect {
or
exists(MethodCallExpr mce |
queryAccess.asExpr() = mce and
mce = any(RegExpLiteral re).flow().(DataFlow::SourceNode).getAMethodCall("exec").asExpr() and
mce = any(DataFlow::RegExpCreationNode re).getAMethodCall("exec").asExpr() and
nd.asExpr() = mce.getArgument(0)
)
}
@@ -132,6 +132,15 @@ module ClientSideUrlRedirect {
}
}
/**
* An argument to `importScripts(..)` - which is used inside `WebWorker`s to import new scripts - viewed as a `ScriptUrlSink`.
*/
class ImportScriptsSink extends ScriptUrlSink {
ImportScriptsSink() {
this = DataFlow::globalVarRef("importScripts").getACall().getAnArgument()
}
}
/**
* A script or iframe `src` attribute, viewed as a `ScriptUrlSink`.
*/

View File

@@ -199,6 +199,11 @@ class PostMessageEventHandler extends Function {
addEventListener.getArgument(0).mayHaveStringValue("message") and
addEventListener.getArgument(1).getABoundFunctionValue(paramIndex).getFunction() = this
)
or
exists(DataFlow::Node rhs |
rhs = DataFlow::globalObjectRef().getAPropertyWrite("onmessage").getRhs() and
rhs.getABoundFunctionValue(paramIndex).getFunction() = this
)
}
/**

View File

@@ -30,7 +30,7 @@ private DataFlow::Node commandArgument(SystemCommandExecution sys, DataFlow::Typ
t.start() and
result = sys.getACommandArgument()
or
exists(DataFlow::TypeBackTracker t2 | t = t2.smallstep(result, commandArgument(sys, t2)))
exists(DataFlow::TypeBackTracker t2 | t2 = t.smallstep(result, commandArgument(sys, t2)))
}
/**
@@ -63,6 +63,26 @@ private DataFlow::SourceNode argumentList(SystemCommandExecution sys) {
result = argumentList(sys, DataFlow::TypeBackTracker::end())
}
/**
* Gets a data-flow node whose value ends up being interpreted as an element of the argument list
* `args` after a flow summarised by `t`.
*/
private DataFlow::Node argumentListElement(DataFlow::SourceNode args, DataFlow::TypeBackTracker t) {
t.start() and
args = argumentList(_) and
result = args.getAPropertyWrite().getRhs()
or
exists(DataFlow::TypeBackTracker t2 | t2 = t.smallstep(result, argumentListElement(args, t2)))
}
/**
* Gets a data-flow node whose value ends up being interpreted as an element of the argument list
* `args`.
*/
private DataFlow::Node argumentListElement(DataFlow::SourceNode args) {
result = argumentListElement(args, DataFlow::TypeBackTracker::end())
}
/**
* Holds if `source` contributes to the arguments of an indirect command execution `sys`.
*
@@ -86,12 +106,12 @@ predicate isIndirectCommandArgument(DataFlow::Node source, SystemCommandExecutio
exists(DataFlow::ArrayCreationNode args, DataFlow::Node shell, string dashC |
shellCmd(shell.asExpr(), dashC) and
shell = commandArgument(sys) and
args.getAPropertyWrite().getRhs().mayHaveStringValue(dashC) and
args = argumentList(sys) and
(
source = argumentList(sys)
or
source = argumentList(sys).getAPropertyWrite().getRhs()
argumentListElement(args).mayHaveStringValue(dashC) and
exists(DataFlow::SourceNode argsSource | argsSource = argumentList(sys) |
if exists(argsSource.getAPropertyWrite())
then source = argsSource.getAPropertyWrite().getRhs()
else source = argsSource
)
)
}

View File

@@ -218,12 +218,12 @@ module TaintedPath {
output = this
or
// non-global replace or replace of something other than /\.\./g, /[/]/g, or /[\.]/g.
this.getCalleeName() = "replace" and
this instanceof StringReplaceCall and
input = getReceiver() and
output = this and
not exists(RegExpLiteral literal, RegExpTerm term |
getArgument(0).getALocalSource().asExpr() = literal and
literal.isGlobal() and
this.(StringReplaceCall).getRegExp().asExpr() = literal and
this.(StringReplaceCall).isGlobal() and
literal.getRoot() = term
|
term.getAMatchedString() = "/" or
@@ -247,16 +247,15 @@ module TaintedPath {
/**
* A call that removes all instances of "../" in the prefix of the string.
*/
class DotDotSlashPrefixRemovingReplace extends DataFlow::CallNode {
class DotDotSlashPrefixRemovingReplace extends StringReplaceCall {
DataFlow::Node input;
DataFlow::Node output;
DotDotSlashPrefixRemovingReplace() {
this.getCalleeName() = "replace" and
input = getReceiver() and
output = this and
exists(RegExpLiteral literal, RegExpTerm term |
getArgument(0).getALocalSource().asExpr() = literal and
getRegExp().asExpr() = literal and
(term instanceof RegExpStar or term instanceof RegExpPlus) and
term.getChild(0) = getADotDotSlashMatcher()
|
@@ -298,17 +297,16 @@ module TaintedPath {
/**
* A call that removes all "." or ".." from a path, without also removing all forward slashes.
*/
class DotRemovingReplaceCall extends DataFlow::CallNode {
class DotRemovingReplaceCall extends StringReplaceCall {
DataFlow::Node input;
DataFlow::Node output;
DotRemovingReplaceCall() {
this.getCalleeName() = "replace" and
input = getReceiver() and
output = this and
isGlobal() and
exists(RegExpLiteral literal, RegExpTerm term |
getArgument(0).getALocalSource().asExpr() = literal and
literal.isGlobal() and
getRegExp().asExpr() = literal and
literal.getRoot() = term and
not term.getAMatchedString() = "/"
|

View File

@@ -39,10 +39,9 @@ module UnsafeJQueryPlugin {
StringConcatenation::taintStep(pred, succ, _, any(int i | i >= 1))
or
// prefixing through a poor-mans templating system:
exists(DataFlow::MethodCallNode replace |
exists(StringReplaceCall replace |
replace = succ and
pred = replace.getArgument(1) and
replace.getMethodName() = "replace"
pred = replace.getRawReplacement()
)
}
@@ -62,10 +61,27 @@ module UnsafeJQueryPlugin {
* With this taint-step we regain that `foo.bar` is tainted, because `PropertyPresenceSanitizer` could remove it.
*/
private predicate aliasPropertyPresenceStep(DataFlow::Node src, DataFlow::Node sink) {
exists(PropertyPresenceSanitizer sanitizer, DataFlow::PropRead read | read = src |
read = sanitizer.getPropRead() and
sink = AccessPath::getAnAliasedSourceNode(read) and
read.getBasicBlock().(ReachableBasicBlock).strictlyDominates(sink.getBasicBlock())
exists(ReachableBasicBlock srcBB, ReachableBasicBlock sinkBB |
aliasPropertyPresenceStepHelper(src, sink, srcBB, sinkBB) and
srcBB.strictlyDominates(sinkBB)
)
}
/**
* Holds if there is a taint-step from `src` to `sink`, and `srcBB` is the basicblock for `src` and `sinkBB` is the basicblock for `sink`.
*
* This predicate is outlined to get a better join-order.
*/
pragma[noinline]
private predicate aliasPropertyPresenceStepHelper(
DataFlow::PropRead src, DataFlow::Node sink, ReachableBasicBlock srcBB,
ReachableBasicBlock sinkBB
) {
exists(PropertyPresenceSanitizer sanitizer |
src = sanitizer.getPropRead() and
sink = AccessPath::getAnAliasedSourceNode(src) and
srcBB = src.getBasicBlock() and
sinkBB = sink.getBasicBlock()
)
}
}

View File

@@ -195,15 +195,25 @@ module UnsafeJQueryPlugin {
*/
predicate isLikelyIntentionalHtmlSink(DataFlow::Node sink) {
exists(
JQuery::JQueryPluginMethod plugin, DataFlow::PropWrite defaultDef, string default,
JQuery::JQueryPluginMethod plugin, DataFlow::PropWrite defaultDef,
DataFlow::PropRead finalRead
|
hasDefaultOption(plugin, defaultDef) and
defaultDef.getPropertyName() = finalRead.getPropertyName() and
defaultDef.getRhs().mayHaveStringValue(default) and
default.regexpMatch("\\s*<.*") and
defaultDef = getALikelyHTMLWrite(finalRead.getPropertyName()) and
finalRead.flowsTo(sink) and
sink.getTopLevel() = plugin.getTopLevel()
)
}
/**
* Gets a property-write that writes a HTML-like constant string to `prop`.
*/
pragma[noinline]
private DataFlow::PropWrite getALikelyHTMLWrite(string prop) {
exists(string default |
result.getRhs().mayHaveStringValue(default) and
default.regexpMatch("\\s*<.*") and
result.getPropertyName() = prop
)
}
}

View File

@@ -33,11 +33,10 @@ module Shared {
* The XSS queries do not attempt to reason about correctness or completeness of sanitizers,
* so any such replacement stops taint propagation.
*/
class MetacharEscapeSanitizer extends Sanitizer, DataFlow::MethodCallNode {
class MetacharEscapeSanitizer extends Sanitizer, StringReplaceCall {
MetacharEscapeSanitizer() {
getMethodName() = "replace" and
exists(RegExpConstant c |
c.getLiteral() = getArgument(0).getALocalSource().asExpr() and
c.getLiteral() = getRegExp().asExpr() and
c.getValue().regexpMatch("['\"&<>]")
)
}

View File

@@ -51,6 +51,7 @@ module PolynomialReDoS {
name = "split" or
name = "matchAll" or
name = "replace" or
name = "replaceAll" or
name = "search"
)
or

View File

@@ -20,4 +20,8 @@ MyOtherStream.prototype.write = function (data) { /* use (instance (member MyOth
return this;
};
MyOtherStream.prototype.instanceProp = 1; /* def (member instanceProp (instance (member MyOtherStream (member exports (module classes))))) */
MyOtherStream.classProp = 1; /* def (member classProp (member MyOtherStream (member exports (module classes)))) */
module.exports.MyOtherStream = MyOtherStream;

View File

@@ -0,0 +1 @@
import ApiGraphs.VerifyAssertions

View File

@@ -0,0 +1,8 @@
const cp = require('child_process');
module.exports = function () {
return cp.spawn.bind(
cp, // def (parameter -1 (member spawn (member exports (module child_process))))
"cat" // def (parameter 0 (member spawn (member exports (module child_process))))
);
};

View File

@@ -0,0 +1,3 @@
{
"name": "partial-invoke"
}

View File

@@ -6,5 +6,6 @@
| tst2.js:1:1:3:3 | <toplevel> | tst2.js:1:1:3:2 | define( ... 42;\\n}) |
| tst3.js:1:1:3:3 | <toplevel> | tst3.js:1:1:3:2 | define( ... 42;\\n}) |
| tst4.js:1:1:11:3 | <toplevel> | tst4.js:1:1:11:2 | define( ... };\\n}) |
| tst5.js:1:1:6:3 | <toplevel> | tst5.js:1:1:6:2 | define( ... };\\n}) |
| tst.js:1:1:6:3 | <toplevel> | tst.js:1:1:6:2 | define( ... };\\n}) |
| umd.js:1:1:14:4 | <toplevel> | umd.js:4:9:4:43 | define( ... actory) |

View File

@@ -1,3 +1,15 @@
getDependencyParameter
| tst2.js:1:1:3:2 | define( ... 42;\\n}) | exports | tst2.js:1:30:1:36 | exports |
| tst4.js:1:1:11:2 | define( ... };\\n}) | a.js | tst4.js:6:20:6:20 | a |
| tst4.js:1:1:11:2 | define( ... };\\n}) | foo | tst4.js:6:23:6:23 | b |
| tst4.js:1:1:11:2 | define( ... };\\n}) | nested/a | tst4.js:6:26:6:32 | exports |
| tst5.js:1:1:6:2 | define( ... };\\n}) | ./a | tst5.js:1:37:1:37 | a |
| tst5.js:1:1:6:2 | define( ... };\\n}) | ./dir/b | tst5.js:1:40:1:44 | {bar} |
| tst.js:1:1:6:2 | define( ... };\\n}) | ./a | tst.js:1:37:1:37 | a |
| tst.js:1:1:6:2 | define( ... };\\n}) | ./dir/b | tst.js:1:40:1:40 | b |
| umd.js:4:9:4:43 | define( ... actory) | ./a | umd.js:9:19:9:19 | a |
| umd.js:4:9:4:43 | define( ... actory) | ./dir/b | umd.js:9:22:9:22 | b |
#select
| a.js:1:1:3:2 | define( ... 2 };\\n}) | a.js:1:8:3:1 | functio ... 42 };\\n} |
| dir/b.js:1:1:3:2 | define( ... : 42\\n}) | dir/b.js:1:8:3:1 | {\\n bar: 42\\n} |
| lib/a.js:1:1:3:2 | define( ... 2 };\\n}) | lib/a.js:1:8:3:1 | functio ... 42 };\\n} |
@@ -6,6 +18,7 @@
| tst2.js:1:1:3:2 | define( ... 42;\\n}) | tst2.js:1:21:3:1 | functio ... = 42;\\n} |
| tst3.js:1:1:3:2 | define( ... 42;\\n}) | tst3.js:1:8:3:1 | functio ... = 42;\\n} |
| tst4.js:1:1:11:2 | define( ... };\\n}) | tst4.js:6:11:11:1 | functio ... };\\n} |
| tst5.js:1:1:6:2 | define( ... };\\n}) | tst5.js:1:28:6:1 | functio ... };\\n} |
| tst.js:1:1:6:2 | define( ... };\\n}) | tst.js:1:28:6:1 | functio ... };\\n} |
| umd.js:4:9:4:43 | define( ... actory) | umd.js:1:18:1:24 | factory |
| umd.js:4:9:4:43 | define( ... actory) | umd.js:9:9:14:1 | functio ... };\\n} |

View File

@@ -1,4 +1,8 @@
import javascript
query Parameter getDependencyParameter(AmdModuleDefinition mod, string name) {
result = mod.getDependencyParameter(name)
}
from AmdModuleDefinition d
select d, d.getFactoryNode()

View File

@@ -4,6 +4,8 @@
| tst4.js:1:1:11:2 | define( ... };\\n}) | tst4.js:3:9:3:13 | 'foo' |
| tst4.js:1:1:11:2 | define( ... };\\n}) | tst4.js:4:9:4:18 | 'nested/a' |
| tst4.js:1:1:11:2 | define( ... };\\n}) | tst4.js:5:9:5:20 | 'lib/foo.js' |
| tst5.js:1:1:6:2 | define( ... };\\n}) | tst5.js:1:9:1:13 | './a' |
| tst5.js:1:1:6:2 | define( ... };\\n}) | tst5.js:1:16:1:24 | './dir/b' |
| tst.js:1:1:6:2 | define( ... };\\n}) | tst.js:1:9:1:13 | './a' |
| tst.js:1:1:6:2 | define( ... };\\n}) | tst.js:1:16:1:24 | './dir/b' |
| umd.js:4:9:4:43 | define( ... actory) | umd.js:4:17:4:21 | './a' |

View File

@@ -7,6 +7,8 @@
| tst3.js:1:1:3:3 | <toplevel> | foo |
| tst4.js:1:1:11:3 | <toplevel> | bar |
| tst4.js:1:1:11:3 | <toplevel> | foo |
| tst5.js:1:1:6:3 | <toplevel> | bar |
| tst5.js:1:1:6:3 | <toplevel> | foo |
| tst.js:1:1:6:3 | <toplevel> | bar |
| tst.js:1:1:6:3 | <toplevel> | foo |
| umd.js:1:1:14:4 | <toplevel> | bar |

View File

@@ -4,6 +4,7 @@
| lib/foo.js:1:1:3:2 | define( ... : 23\\n}) | lib/foo.js:1:8:3:1 | {\\n foo: 23\\n} | lib/foo.js:1:8:3:1 | {\\n foo: 23\\n} |
| lib/nested/a.js:1:1:3:2 | define( ... 2 };\\n}) | lib/nested/a.js:2:12:2:22 | { foo: 42 } | lib/nested/a.js:2:12:2:22 | { foo: 42 } |
| tst4.js:1:1:11:2 | define( ... };\\n}) | tst4.js:7:12:10:5 | {\\n ... r\\n } | tst4.js:7:12:10:5 | {\\n ... r\\n } |
| tst5.js:1:1:6:2 | define( ... };\\n}) | tst5.js:2:12:5:5 | {\\n ... r\\n } | tst5.js:2:12:5:5 | {\\n ... r\\n } |
| tst.js:1:1:6:2 | define( ... };\\n}) | tst.js:2:12:5:5 | {\\n ... r\\n } | tst.js:2:12:5:5 | {\\n ... r\\n } |
| umd.js:4:9:4:43 | define( ... actory) | umd.js:1:18:1:24 | factory | umd.js:1:18:1:24 | factory |
| umd.js:4:9:4:43 | define( ... actory) | umd.js:1:18:1:24 | factory | umd.js:9:9:14:1 | functio ... };\\n} |

View File

@@ -2,6 +2,8 @@
| tst4.js:1:1:11:3 | <toplevel> | tst4.js:3:9:3:13 | 'foo' | lib/foo.js:1:1:4:0 | <toplevel> |
| tst4.js:1:1:11:3 | <toplevel> | tst4.js:4:9:4:18 | 'nested/a' | lib/nested/a.js:1:1:3:3 | <toplevel> |
| tst4.js:1:1:11:3 | <toplevel> | tst4.js:5:9:5:20 | 'lib/foo.js' | lib/foo.js:1:1:4:0 | <toplevel> |
| tst5.js:1:1:6:3 | <toplevel> | tst5.js:1:9:1:13 | './a' | a.js:1:1:3:3 | <toplevel> |
| tst5.js:1:1:6:3 | <toplevel> | tst5.js:1:16:1:24 | './dir/b' | dir/b.js:1:1:3:3 | <toplevel> |
| tst.js:1:1:6:3 | <toplevel> | tst.js:1:9:1:13 | './a' | a.js:1:1:3:3 | <toplevel> |
| tst.js:1:1:6:3 | <toplevel> | tst.js:1:16:1:24 | './dir/b' | dir/b.js:1:1:3:3 | <toplevel> |
| umd.js:1:1:14:4 | <toplevel> | umd.js:4:17:4:21 | './a' | a.js:1:1:3:3 | <toplevel> |

View File

@@ -7,6 +7,8 @@
| tst3.js:1:1:3:3 | <toplevel> | foo | tst3.js:2:43:2:44 | 42 |
| tst4.js:1:1:11:3 | <toplevel> | bar | tst4.js:9:14:9:18 | b.bar |
| tst4.js:1:1:11:3 | <toplevel> | foo | tst4.js:8:14:8:18 | a.foo |
| tst5.js:1:1:6:3 | <toplevel> | bar | tst5.js:4:14:4:16 | bar |
| tst5.js:1:1:6:3 | <toplevel> | foo | tst5.js:3:14:3:18 | a.foo |
| tst.js:1:1:6:3 | <toplevel> | bar | tst.js:4:14:4:18 | b.bar |
| tst.js:1:1:6:3 | <toplevel> | foo | tst.js:3:14:3:18 | a.foo |
| umd.js:1:1:14:4 | <toplevel> | bar | umd.js:11:14:11:18 | a.foo |

View File

@@ -0,0 +1,6 @@
define(['./a', './dir/b'], function(a, {bar}, exports) {
return {
foo: a.foo,
bar: bar
};
});

View File

@@ -86,3 +86,11 @@
| tst.js:2:17:2:22 | "src1" | tst.js:61:16:61:18 | o.r |
| tst.js:2:17:2:22 | "src1" | tst.js:68:16:68:22 | inner() |
| tst.js:2:17:2:22 | "src1" | tst.js:80:16:80:22 | outer() |
| tst.js:2:17:2:22 | "src1" | tst.js:87:16:87:43 | source1 ... /g, "") |
| tst.js:2:17:2:22 | "src1" | tst.js:88:16:88:46 | "foo".r ... ource1) |
| underscore.js:2:17:2:22 | "src1" | underscore.js:3:15:3:28 | _.max(source1) |
| underscore.js:5:17:5:22 | "src2" | underscore.js:6:15:6:34 | _.union([], source2) |
| underscore.js:5:17:5:22 | "src2" | underscore.js:7:15:7:32 | _.zip(source2, []) |
| underscore.js:9:17:9:22 | "src3" | underscore.js:11:17:11:17 | x |
| underscore.js:14:17:14:22 | "src4" | underscore.js:16:17:16:17 | e |
| underscore.js:19:17:19:22 | "src5" | underscore.js:20:15:20:44 | _.map([ ... ource5) |

View File

@@ -83,4 +83,7 @@
o.notTracked = source1;
var sink22 = o.notTracked;
var sink23 = source1.replaceAll(/f/g, "");
var sink24 = "foo".replaceAll(/f/g, source1);
})();

View File

@@ -0,0 +1,21 @@
(function() {
var source1 = "src1";
var sink1 = _.max(source1); // NOT OK
var source2 = "src2";
var sink2 = _.union([], source2); // NOT OK
var sink3 = _.zip(source2, []); // NOT OK
var source3 = "src3";
_.map(source3, (x) => {
let sink4 = x; // NOT OK
});
var source4 = "src4";
_.reduce(source4, (acc, e) => {
let sink5 = e; // NOT OK
});
var source5 = "src5";
var sink6 = _.map([1,2,3], (x) => source5); // NOT OK
})();

View File

@@ -154,4 +154,15 @@
} catch (e) {
sink(e); // NOT OK
}
})();
})();
(function () {
var source = "source";
var bluebird = require("bluebird");
bluebird.mapSeries(source, x => sink(x)); // NOT OK (for taint-tracking configs)
const foo = bluebird.mapSeries(source, x => x);
sink(foo); // NOT OK (for taint-tracking configs)
})

View File

@@ -18,4 +18,10 @@
var [clean3, tainted3] = await Promise.all(["clean", Promise.resolve(source)]);
sink(clean3); // OK
sink(tainted3); // NOT OK - but only flagged by taint-tracking
var tainted4 = await Promise.race(["clean", Promise.resolve(source)]);
sink(tainted4); // NOT OK - but only flagged by taint-tracking
var tainted5 = await Promise.any(["clean", Promise.resolve(source)]);
sink(tainted5); // NOT OK - but only flagged by taint-tracking
});

View File

@@ -9,6 +9,12 @@ test_ResolvedPromiseDefinition
| flow2.js:18:33:18:79 | Promise ... urce)]) | flow2.js:18:46:18:52 | "clean" |
| flow2.js:18:33:18:79 | Promise ... urce)]) | flow2.js:18:55:18:77 | Promise ... source) |
| flow2.js:18:55:18:77 | Promise ... source) | flow2.js:18:71:18:76 | source |
| flow2.js:22:23:22:70 | Promise ... urce)]) | flow2.js:22:37:22:43 | "clean" |
| flow2.js:22:23:22:70 | Promise ... urce)]) | flow2.js:22:46:22:68 | Promise ... source) |
| flow2.js:22:46:22:68 | Promise ... source) | flow2.js:22:62:22:67 | source |
| flow2.js:25:23:25:69 | Promise ... urce)]) | flow2.js:25:36:25:42 | "clean" |
| flow2.js:25:23:25:69 | Promise ... urce)]) | flow2.js:25:45:25:67 | Promise ... source) |
| flow2.js:25:45:25:67 | Promise ... source) | flow2.js:25:61:25:66 | source |
| flow.js:4:11:4:33 | Promise ... source) | flow.js:4:27:4:32 | source |
| flow.js:20:2:20:24 | Promise ... source) | flow.js:20:18:20:23 | source |
| flow.js:22:2:22:24 | Promise ... source) | flow.js:22:18:22:23 | source |
@@ -201,6 +207,8 @@ flow
| flow2.js:2:15:2:22 | "source" | flow2.js:6:8:6:13 | arr[0] |
| flow2.js:2:15:2:22 | "source" | flow2.js:12:7:12:13 | tainted |
| flow2.js:2:15:2:22 | "source" | flow2.js:16:7:16:14 | tainted2 |
| flow2.js:2:15:2:22 | "source" | flow2.js:23:7:23:14 | tainted4 |
| flow2.js:2:15:2:22 | "source" | flow2.js:26:7:26:14 | tainted5 |
| flow.js:2:15:2:22 | "source" | flow.js:5:7:5:14 | await p1 |
| flow.js:2:15:2:22 | "source" | flow.js:8:7:8:14 | await p2 |
| flow.js:2:15:2:22 | "source" | flow.js:17:8:17:8 | e |
@@ -237,6 +245,8 @@ flow
exclusiveTaintFlow
| flow2.js:2:15:2:22 | "source" | flow2.js:20:7:20:14 | tainted3 |
| flow.js:136:15:136:22 | "source" | flow.js:141:7:141:13 | async() |
| flow.js:160:15:160:22 | "source" | flow.js:164:39:164:39 | x |
| flow.js:160:15:160:22 | "source" | flow.js:167:7:167:9 | foo |
| interflow.js:3:18:3:25 | "source" | interflow.js:18:10:18:14 | error |
typetrack
| flow2.js:4:2:4:31 | Promise ... lean"]) | flow2.js:4:14:4:30 | [source, "clean"] | copy $PromiseResolveField$ |
@@ -253,6 +263,12 @@ typetrack
| flow2.js:18:27:18:79 | await P ... urce)]) | flow2.js:18:33:18:79 | Promise ... urce)]) | load $PromiseResolveField$ |
| flow2.js:18:33:18:79 | Promise ... urce)]) | flow2.js:18:45:18:78 | ["clean ... ource)] | copy $PromiseResolveField$ |
| flow2.js:18:33:18:79 | Promise ... urce)]) | flow2.js:18:45:18:78 | ["clean ... ource)] | store $PromiseResolveField$ |
| flow2.js:22:17:22:70 | await P ... urce)]) | flow2.js:22:23:22:70 | Promise ... urce)]) | load $PromiseResolveField$ |
| flow2.js:22:23:22:70 | Promise ... urce)]) | flow2.js:22:46:22:68 | Promise ... source) | copy $PromiseResolveField$ |
| flow2.js:22:23:22:70 | Promise ... urce)]) | flow2.js:22:46:22:68 | Promise ... source) | store $PromiseResolveField$ |
| flow2.js:25:17:25:69 | await P ... urce)]) | flow2.js:25:23:25:69 | Promise ... urce)]) | load $PromiseResolveField$ |
| flow2.js:25:23:25:69 | Promise ... urce)]) | flow2.js:25:45:25:67 | Promise ... source) | copy $PromiseResolveField$ |
| flow2.js:25:23:25:69 | Promise ... urce)]) | flow2.js:25:45:25:67 | Promise ... source) | store $PromiseResolveField$ |
| flow.js:20:2:20:43 | Promise ... ink(x)) | flow.js:20:36:20:42 | sink(x) | copy $PromiseResolveField$ |
| flow.js:20:2:20:43 | Promise ... ink(x)) | flow.js:20:36:20:42 | sink(x) | store $PromiseResolveField$ |
| flow.js:20:31:20:31 | x | flow.js:20:2:20:24 | Promise ... source) | load $PromiseResolveField$ |

View File

@@ -34,3 +34,4 @@
| dependency-kinds.js:98:33:98:63 | functio ... ency){} | animationDependency |
| dependency-kinds.js:111:17:117:9 | functio ... } | $routeProvider |
| dependency-kinds.js:114:33:115:21 | functio ... } | routeControllerDependency |
| dependency-kinds.js:121:14:123:10 | ['modul ... }] | moduleRunService |

View File

@@ -117,4 +117,8 @@
})
;
angular.module('myModule', [])
.run(['moduleRunService', function({foo, bar}) {
// ...
}])
})();

View File

@@ -66,6 +66,10 @@ test_ClientRequest
| tst.js:200:2:200:21 | $.get("example.php") |
| tst.js:202:5:208:7 | $.ajax( ... }}) |
| tst.js:210:2:210:21 | $.get("example.php") |
| tst.js:219:5:219:41 | data.so ... Host"}) |
| tst.js:229:5:229:67 | needle( ... ptions) |
| tst.js:231:5:233:6 | needle. ... \\n }) |
| tst.js:235:5:237:6 | needle. ... \\n }) |
test_getADataNode
| tst.js:53:5:53:23 | axios({data: data}) | tst.js:53:18:53:21 | data |
| tst.js:57:5:57:39 | axios.p ... data2}) | tst.js:57:19:57:23 | data1 |
@@ -95,11 +99,17 @@ test_getADataNode
| tst.js:179:2:179:60 | $.getJS ... a ) {}) | tst.js:179:31:179:38 | "MyData" |
| tst.js:183:2:183:60 | $.post( ... ) { }) | tst.js:183:28:183:37 | "PostData" |
| tst.js:187:2:193:3 | $.ajax( ... on"\\n\\t}) | tst.js:190:11:190:20 | "AjaxData" |
| tst.js:219:5:219:41 | data.so ... Host"}) | tst.js:223:23:223:30 | "foobar" |
| tst.js:229:5:229:67 | needle( ... ptions) | tst.js:228:32:228:70 | { 'X-Cu ... tuna' } |
| tst.js:229:5:229:67 | needle( ... ptions) | tst.js:229:50:229:57 | "MyData" |
| tst.js:235:5:237:6 | needle. ... \\n }) | tst.js:228:32:228:70 | { 'X-Cu ... tuna' } |
| tst.js:235:5:237:6 | needle. ... \\n }) | tst.js:235:44:235:49 | "data" |
test_getHost
| tst.js:87:5:87:39 | http.ge ... host}) | tst.js:87:34:87:37 | host |
| tst.js:89:5:89:23 | axios({host: host}) | tst.js:89:18:89:21 | host |
| tst.js:91:5:91:34 | got(rel ... host}) | tst.js:91:29:91:32 | host |
| tst.js:93:5:93:35 | net.req ... host }) | tst.js:93:29:93:32 | host |
| tst.js:219:5:219:41 | data.so ... Host"}) | tst.js:219:32:219:39 | "myHost" |
test_getUrl
| tst.js:11:5:11:16 | request(url) | tst.js:11:13:11:15 | url |
| tst.js:13:5:13:20 | request.get(url) | tst.js:13:17:13:19 | url |
@@ -173,6 +183,10 @@ test_getUrl
| tst.js:200:2:200:21 | $.get("example.php") | tst.js:200:8:200:20 | "example.php" |
| tst.js:202:5:208:7 | $.ajax( ... }}) | tst.js:203:10:203:22 | "example.php" |
| tst.js:210:2:210:21 | $.get("example.php") | tst.js:210:8:210:20 | "example.php" |
| tst.js:219:5:219:41 | data.so ... Host"}) | tst.js:219:25:219:40 | {host: "myHost"} |
| tst.js:229:5:229:67 | needle( ... ptions) | tst.js:229:20:229:47 | "http:/ ... oo/bar" |
| tst.js:231:5:233:6 | needle. ... \\n }) | tst.js:231:16:231:35 | "http://example.org" |
| tst.js:235:5:237:6 | needle. ... \\n }) | tst.js:235:17:235:41 | "http:/ ... g/post" |
test_getAResponseDataNode
| tst.js:19:5:19:23 | requestPromise(url) | tst.js:19:5:19:23 | requestPromise(url) | text | true |
| tst.js:21:5:21:23 | superagent.get(url) | tst.js:21:5:21:23 | superagent.get(url) | stream | true |
@@ -233,3 +247,9 @@ test_getAResponseDataNode
| tst.js:200:2:200:21 | $.get("example.php") | tst.js:200:37:200:44 | response | | false |
| tst.js:202:5:208:7 | $.ajax( ... }}) | tst.js:207:21:207:36 | err.responseText | json | false |
| tst.js:210:2:210:21 | $.get("example.php") | tst.js:210:55:210:70 | xhr.responseText | | false |
| tst.js:219:5:219:41 | data.so ... Host"}) | tst.js:221:29:221:32 | data | text | false |
| tst.js:229:5:229:67 | needle( ... ptions) | tst.js:229:5:229:67 | needle( ... ptions) | fetch.response | true |
| tst.js:231:5:233:6 | needle. ... \\n }) | tst.js:231:44:231:47 | resp | fetch.response | false |
| tst.js:231:5:233:6 | needle. ... \\n }) | tst.js:231:50:231:53 | body | json | false |
| tst.js:235:5:237:6 | needle. ... \\n }) | tst.js:235:67:235:70 | resp | fetch.response | false |
| tst.js:235:5:237:6 | needle. ... \\n }) | tst.js:235:73:235:76 | body | json | false |

View File

@@ -209,3 +209,30 @@ import {ClientRequest, net} from 'electron';
$.get("example.php").fail(function(xhr) {console.log(xhr.responseText)});
});
const net = require("net");
(function () {
var data = {
socket: new net.Socket()
}
data.socket.connect({host: "myHost"});
data.socket.on("data", (data) => {});
data.socket.write("foobar");
})();
const needle = require("needle");
(function () {
const options = { headers: { 'X-Custom-Header': 'Bumbaway atuna' } };
needle("POST", "http://example.org/foo/bar", "MyData", options).then(function(resp) { console.log(resp.body) });
needle.get("http://example.org", (err, resp, body) => {
});
needle.post("http://example.org/post", "data", options, (err, resp, body) => {
});
})();

View File

@@ -1,7 +1,5 @@
import javascript
query predicate test_RouteHandler(
Express::RouteHandler rh, SimpleParameter res0, SimpleParameter res1
) {
query predicate test_RouteHandler(Express::RouteHandler rh, Parameter res0, Parameter res1) {
res0 = rh.getRequestParameter() and res1 = rh.getResponseParameter()
}

View File

@@ -794,6 +794,7 @@ test_isRequest
| src/advanced-routehandler-registration.js:123:46:123:48 | req |
| src/advanced-routehandler-registration.js:124:21:124:23 | req |
| src/advanced-routehandler-registration.js:124:46:124:48 | req |
| src/advanced-routehandler-registration.js:146:29:146:31 | req |
| src/advanced-routehandler-registration.js:156:22:156:24 | req |
| src/advanced-routehandler-registration.js:156:47:156:49 | req |
| src/advanced-routehandler-registration.js:157:28:157:30 | req |
@@ -925,10 +926,16 @@ test_RouteSetup_getRouter
test_RedirectInvocation
| src/express.js:5:3:5:35 | res.red ... rget")) | src/express.js:4:23:9:1 | functio ... res);\\n} |
test_StandardRouteHandler
| src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:2:11:2:19 | express() | src/advanced-routehandler-registration.js:46:20:46:22 | req | src/advanced-routehandler-registration.js:46:25:46:27 | res |
| src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:2:11:2:19 | express() | src/advanced-routehandler-registration.js:51:10:51:12 | req | src/advanced-routehandler-registration.js:51:15:51:17 | res |
| src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:2:11:2:19 | express() | src/advanced-routehandler-registration.js:59:20:59:22 | req | src/advanced-routehandler-registration.js:59:25:59:27 | res |
| src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | src/advanced-routehandler-registration.js:64:10:64:12 | req | src/advanced-routehandler-registration.js:64:15:64:17 | res |
| src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | src/advanced-routehandler-registration.js:68:13:68:15 | req | src/advanced-routehandler-registration.js:68:18:68:20 | res |
| src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:2:11:2:19 | express() | src/advanced-routehandler-registration.js:69:20:69:22 | req | src/advanced-routehandler-registration.js:69:25:69:27 | res |
| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:2:11:2:19 | express() | src/advanced-routehandler-registration.js:73:10:73:12 | req | src/advanced-routehandler-registration.js:73:15:73:17 | res |
| src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:2:11:2:19 | express() | src/advanced-routehandler-registration.js:81:20:81:22 | req | src/advanced-routehandler-registration.js:81:25:81:27 | res |
| src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:2:11:2:19 | express() | src/advanced-routehandler-registration.js:92:10:92:12 | req | src/advanced-routehandler-registration.js:92:15:92:17 | res |
| src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:2:11:2:19 | express() | src/advanced-routehandler-registration.js:100:20:100:22 | req | src/advanced-routehandler-registration.js:100:25:100:27 | res |
| src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:2:11:2:19 | express() | src/advanced-routehandler-registration.js:111:10:111:12 | req | src/advanced-routehandler-registration.js:111:15:111:17 | res |
| src/csurf-example.js:20:18:23:1 | functio ... () })\\n} | src/csurf-example.js:7:11:7:19 | express() | src/csurf-example.js:20:28:20:30 | req | src/csurf-example.js:20:33:20:35 | res |
| src/csurf-example.js:25:22:27:1 | functio ... ere')\\n} | src/csurf-example.js:7:11:7:19 | express() | src/csurf-example.js:25:32:25:34 | req | src/csurf-example.js:25:37:25:39 | res |
@@ -1024,29 +1031,42 @@ test_ResponseExpr
| src/advanced-routehandler-registration.js:16:12:16:14 | res | src/advanced-routehandler-registration.js:16:6:16:35 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:24:12:24:14 | res | src/advanced-routehandler-registration.js:24:6:24:35 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:25:12:25:14 | res | src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:46:25:46:27 | res | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:46:25:46:27 | res | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:47:32:47:34 | res | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:47:32:47:34 | res | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:51:15:51:17 | res | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:51:45:51:47 | res | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:59:25:59:27 | res | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:59:25:59:27 | res | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:60:23:60:25 | res | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:60:23:60:25 | res | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:64:15:64:17 | res | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:64:50:64:52 | res | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:68:18:68:20 | res | src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:68:18:68:20 | res | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:68:18:68:20 | res | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:69:25:69:27 | res | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:69:25:69:27 | res | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:70:23:70:25 | res | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:70:23:70:25 | res | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:73:15:73:17 | res | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:73:52:73:54 | res | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:81:25:81:27 | res | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:81:25:81:27 | res | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:82:32:82:34 | res | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:82:32:82:34 | res | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:92:15:92:17 | res | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:92:45:92:47 | res | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:100:25:100:27 | res | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:100:25:100:27 | res | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:101:36:101:38 | res | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:101:36:101:38 | res | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:111:15:111:17 | res | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:111:45:111:47 | res | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:123:26:123:28 | res | src/advanced-routehandler-registration.js:123:20:123:49 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:124:26:124:28 | res | src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:146:34:146:36 | res | src/advanced-routehandler-registration.js:146:28:146:50 | (req, r ... defined |
| src/advanced-routehandler-registration.js:156:27:156:29 | res | src/advanced-routehandler-registration.js:156:21:156:50 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:157:33:157:35 | res | src/advanced-routehandler-registration.js:157:27:157:56 | (req, r ... og(req) |
| src/controllers/handler-in-bulk-require.js:1:50:1:52 | res | src/controllers/handler-in-bulk-require.js:1:44:1:66 | (req, r ... defined |
@@ -1528,29 +1548,42 @@ test_RouteHandler_getAResponseExpr
| src/advanced-routehandler-registration.js:16:6:16:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:16:12:16:14 | res |
| src/advanced-routehandler-registration.js:24:6:24:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:24:12:24:14 | res |
| src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:25:12:25:14 | res |
| src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:46:25:46:27 | res |
| src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:47:32:47:34 | res |
| src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:46:25:46:27 | res |
| src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:47:32:47:34 | res |
| src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:51:15:51:17 | res |
| src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:51:45:51:47 | res |
| src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:59:25:59:27 | res |
| src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:60:23:60:25 | res |
| src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:59:25:59:27 | res |
| src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:60:23:60:25 | res |
| src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:64:15:64:17 | res |
| src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:64:50:64:52 | res |
| src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) | src/advanced-routehandler-registration.js:68:18:68:20 | res |
| src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:68:18:68:20 | res |
| src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:69:25:69:27 | res |
| src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:70:23:70:25 | res |
| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:68:18:68:20 | res |
| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:69:25:69:27 | res |
| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:70:23:70:25 | res |
| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:73:15:73:17 | res |
| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:73:52:73:54 | res |
| src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:81:25:81:27 | res |
| src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:82:32:82:34 | res |
| src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:81:25:81:27 | res |
| src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:82:32:82:34 | res |
| src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:92:15:92:17 | res |
| src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:92:45:92:47 | res |
| src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:100:25:100:27 | res |
| src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:101:36:101:38 | res |
| src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:100:25:100:27 | res |
| src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:101:36:101:38 | res |
| src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:111:15:111:17 | res |
| src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:111:45:111:47 | res |
| src/advanced-routehandler-registration.js:123:20:123:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:123:26:123:28 | res |
| src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:124:26:124:28 | res |
| src/advanced-routehandler-registration.js:146:28:146:50 | (req, r ... defined | src/advanced-routehandler-registration.js:146:34:146:36 | res |
| src/advanced-routehandler-registration.js:156:21:156:50 | (req, r ... og(req) | src/advanced-routehandler-registration.js:156:27:156:29 | res |
| src/advanced-routehandler-registration.js:157:27:157:56 | (req, r ... og(req) | src/advanced-routehandler-registration.js:157:33:157:35 | res |
| src/controllers/handler-in-bulk-require.js:1:44:1:66 | (req, r ... defined | src/controllers/handler-in-bulk-require.js:1:50:1:52 | res |
@@ -1690,6 +1723,7 @@ test_isResponse
| src/advanced-routehandler-registration.js:111:45:111:47 | res |
| src/advanced-routehandler-registration.js:123:26:123:28 | res |
| src/advanced-routehandler-registration.js:124:26:124:28 | res |
| src/advanced-routehandler-registration.js:146:34:146:36 | res |
| src/advanced-routehandler-registration.js:156:27:156:29 | res |
| src/advanced-routehandler-registration.js:157:33:157:35 | res |
| src/controllers/handler-in-bulk-require.js:1:50:1:52 | res |
@@ -1828,11 +1862,25 @@ test_RouteSetup_getARouteHandler
| src/advanced-routehandler-registration.js:28:3:28:24 | app.get ... es2[p]) | src/advanced-routehandler-registration.js:27:12:27:12 | p |
| src/advanced-routehandler-registration.js:28:3:28:24 | app.get ... es2[p]) | src/advanced-routehandler-registration.js:28:14:28:23 | routes2[p] |
| src/advanced-routehandler-registration.js:37:3:37:12 | app.use(h) | src/advanced-routehandler-registration.js:36:12:36:12 | h |
| src/advanced-routehandler-registration.js:51:1:51:61 | app.use ... ever")) | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:51:1:51:61 | app.use ... ever")) | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:51:1:51:61 | app.use ... ever")) | src/advanced-routehandler-registration.js:51:23:51:38 | myRouter1.handle |
| src/advanced-routehandler-registration.js:64:1:64:54 | app.use ... , res)) | src/advanced-routehandler-registration.js:55:12:55:20 | undefined |
| src/advanced-routehandler-registration.js:64:1:64:54 | app.use ... , res)) | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:64:1:64:54 | app.use ... , res)) | src/advanced-routehandler-registration.js:60:5:60:16 | this.handler |
| src/advanced-routehandler-registration.js:64:1:64:54 | app.use ... , res)) | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:64:1:64:54 | app.use ... , res)) | src/advanced-routehandler-registration.js:64:23:64:43 | mySimpl ... .handle |
| src/advanced-routehandler-registration.js:73:1:73:56 | app.use ... , res)) | src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:73:1:73:56 | app.use ... , res)) | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:73:1:73:56 | app.use ... , res)) | src/advanced-routehandler-registration.js:70:5:70:16 | this.handler |
| src/advanced-routehandler-registration.js:73:1:73:56 | app.use ... , res)) | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:73:1:73:56 | app.use ... , res)) | src/advanced-routehandler-registration.js:73:23:73:45 | mySimpl ... .handle |
| src/advanced-routehandler-registration.js:92:1:92:61 | app.use ... ever")) | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:92:1:92:61 | app.use ... ever")) | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:92:1:92:61 | app.use ... ever")) | src/advanced-routehandler-registration.js:92:23:92:38 | myRouter3.handle |
| src/advanced-routehandler-registration.js:111:1:111:61 | app.use ... ever")) | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:111:1:111:61 | app.use ... ever")) | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:111:1:111:61 | app.use ... ever")) | src/advanced-routehandler-registration.js:111:23:111:38 | myRouter4.handle |
| src/advanced-routehandler-registration.js:116:3:116:31 | app.get ... tes[p]) | src/advanced-routehandler-registration.js:116:14:116:30 | importedRoutes[p] |
| src/advanced-routehandler-registration.js:116:3:116:31 | app.get ... tes[p]) | src/route-collection.js:2:6:2:35 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:116:3:116:31 | app.get ... tes[p]) | src/route-collection.js:3:6:3:35 | (req, r ... og(req) |
@@ -1853,6 +1901,8 @@ test_RouteSetup_getARouteHandler
| src/advanced-routehandler-registration.js:139:1:139:58 | app.get ... andler) | src/advanced-routehandler-registration.js:139:9:139:30 | bulkReq ... ky.path |
| src/advanced-routehandler-registration.js:139:1:139:58 | app.get ... andler) | src/advanced-routehandler-registration.js:139:33:139:57 | bulkReq ... handler |
| src/advanced-routehandler-registration.js:139:1:139:58 | app.get ... andler) | src/controllers/handler-in-bulk-require.js:1:44:1:66 | (req, r ... defined |
| src/advanced-routehandler-registration.js:147:1:147:37 | app.use ... (data)) | src/advanced-routehandler-registration.js:146:28:146:50 | (req, r ... defined |
| src/advanced-routehandler-registration.js:147:1:147:37 | app.use ... (data)) | src/advanced-routehandler-registration.js:147:9:147:25 | handlers.handlerA |
| src/advanced-routehandler-registration.js:147:1:147:37 | app.use ... (data)) | src/advanced-routehandler-registration.js:147:9:147:36 | handler ... d(data) |
| src/advanced-routehandler-registration.js:150:2:150:14 | app.get(k, v) | src/advanced-routehandler-registration.js:150:10:150:10 | k |
| src/advanced-routehandler-registration.js:150:2:150:14 | app.get(k, v) | src/advanced-routehandler-registration.js:150:13:150:13 | v |
@@ -2240,13 +2290,20 @@ test_RouteHandler
| src/advanced-routehandler-registration.js:16:6:16:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:16:7:16:9 | req | src/advanced-routehandler-registration.js:16:12:16:14 | res |
| src/advanced-routehandler-registration.js:24:6:24:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:24:7:24:9 | req | src/advanced-routehandler-registration.js:24:12:24:14 | res |
| src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:25:7:25:9 | req | src/advanced-routehandler-registration.js:25:12:25:14 | res |
| src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:46:20:46:22 | req | src/advanced-routehandler-registration.js:46:25:46:27 | res |
| src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:51:10:51:12 | req | src/advanced-routehandler-registration.js:51:15:51:17 | res |
| src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:59:20:59:22 | req | src/advanced-routehandler-registration.js:59:25:59:27 | res |
| src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:64:10:64:12 | req | src/advanced-routehandler-registration.js:64:15:64:17 | res |
| src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) | src/advanced-routehandler-registration.js:68:13:68:15 | req | src/advanced-routehandler-registration.js:68:18:68:20 | res |
| src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:69:20:69:22 | req | src/advanced-routehandler-registration.js:69:25:69:27 | res |
| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:73:10:73:12 | req | src/advanced-routehandler-registration.js:73:15:73:17 | res |
| src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:81:20:81:22 | req | src/advanced-routehandler-registration.js:81:25:81:27 | res |
| src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:92:10:92:12 | req | src/advanced-routehandler-registration.js:92:15:92:17 | res |
| src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:100:20:100:22 | req | src/advanced-routehandler-registration.js:100:25:100:27 | res |
| src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:111:10:111:12 | req | src/advanced-routehandler-registration.js:111:15:111:17 | res |
| src/advanced-routehandler-registration.js:123:20:123:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:123:21:123:23 | req | src/advanced-routehandler-registration.js:123:26:123:28 | res |
| src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:124:21:124:23 | req | src/advanced-routehandler-registration.js:124:26:124:28 | res |
| src/advanced-routehandler-registration.js:146:28:146:50 | (req, r ... defined | src/advanced-routehandler-registration.js:146:29:146:31 | req | src/advanced-routehandler-registration.js:146:34:146:36 | res |
| src/advanced-routehandler-registration.js:156:21:156:50 | (req, r ... og(req) | src/advanced-routehandler-registration.js:156:22:156:24 | req | src/advanced-routehandler-registration.js:156:27:156:29 | res |
| src/advanced-routehandler-registration.js:157:27:157:56 | (req, r ... og(req) | src/advanced-routehandler-registration.js:157:28:157:30 | req | src/advanced-routehandler-registration.js:157:33:157:35 | res |
| src/controllers/handler-in-bulk-require.js:1:44:1:66 | (req, r ... defined | src/controllers/handler-in-bulk-require.js:1:45:1:47 | req | src/controllers/handler-in-bulk-require.js:1:50:1:52 | res |
@@ -2403,25 +2460,39 @@ test_RequestExpr
| src/advanced-routehandler-registration.js:24:32:24:34 | req | src/advanced-routehandler-registration.js:24:6:24:35 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:25:7:25:9 | req | src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:25:32:25:34 | req | src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:46:20:46:22 | req | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:46:20:46:22 | req | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:47:27:47:29 | req | src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:47:27:47:29 | req | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:51:10:51:12 | req | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:51:40:51:42 | req | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:59:20:59:22 | req | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:59:20:59:22 | req | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:60:18:60:20 | req | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:60:18:60:20 | req | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:64:10:64:12 | req | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:64:45:64:47 | req | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:68:13:68:15 | req | src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:68:13:68:15 | req | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:68:13:68:15 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:68:38:68:40 | req | src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:68:38:68:40 | req | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:68:38:68:40 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:69:20:69:22 | req | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:69:20:69:22 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:70:18:70:20 | req | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:70:18:70:20 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:73:10:73:12 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:73:47:73:49 | req | src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) |
| src/advanced-routehandler-registration.js:81:20:81:22 | req | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:81:20:81:22 | req | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:82:27:82:29 | req | src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:82:27:82:29 | req | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:92:10:92:12 | req | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:92:40:92:42 | req | src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:100:20:100:22 | req | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:100:20:100:22 | req | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:101:31:101:33 | req | src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } |
| src/advanced-routehandler-registration.js:101:31:101:33 | req | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:111:10:111:12 | req | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") |
| src/advanced-routehandler-registration.js:111:40:111:42 | req | src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") |
@@ -2429,6 +2500,7 @@ test_RequestExpr
| src/advanced-routehandler-registration.js:123:46:123:48 | req | src/advanced-routehandler-registration.js:123:20:123:49 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:124:21:124:23 | req | src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:124:46:124:48 | req | src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:146:29:146:31 | req | src/advanced-routehandler-registration.js:146:28:146:50 | (req, r ... defined |
| src/advanced-routehandler-registration.js:156:22:156:24 | req | src/advanced-routehandler-registration.js:156:21:156:50 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:156:47:156:49 | req | src/advanced-routehandler-registration.js:156:21:156:50 | (req, r ... og(req) |
| src/advanced-routehandler-registration.js:157:28:157:30 | req | src/advanced-routehandler-registration.js:157:27:157:56 | (req, r ... og(req) |
@@ -2515,24 +2587,38 @@ test_RouteHandler_getARequestExpr
| src/advanced-routehandler-registration.js:24:6:24:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:24:32:24:34 | req |
| src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:25:7:25:9 | req |
| src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:25:32:25:34 | req |
| src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:46:20:46:22 | req |
| src/advanced-routehandler-registration.js:46:11:48:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:47:27:47:29 | req |
| src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:46:20:46:22 | req |
| src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:47:27:47:29 | req |
| src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:51:10:51:12 | req |
| src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:51:40:51:42 | req |
| src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:59:20:59:22 | req |
| src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:60:18:60:20 | req |
| src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:59:20:59:22 | req |
| src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:60:18:60:20 | req |
| src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:64:10:64:12 | req |
| src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:64:45:64:47 | req |
| src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) | src/advanced-routehandler-registration.js:68:13:68:15 | req |
| src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) | src/advanced-routehandler-registration.js:68:38:68:40 | req |
| src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:68:13:68:15 | req |
| src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:68:38:68:40 | req |
| src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:69:20:69:22 | req |
| src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:70:18:70:20 | req |
| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:68:13:68:15 | req |
| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:68:38:68:40 | req |
| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:69:20:69:22 | req |
| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:70:18:70:20 | req |
| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:73:10:73:12 | req |
| src/advanced-routehandler-registration.js:73:9:73:55 | (req, r ... q, res) | src/advanced-routehandler-registration.js:73:47:73:49 | req |
| src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:81:20:81:22 | req |
| src/advanced-routehandler-registration.js:81:11:83:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:82:27:82:29 | req |
| src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:81:20:81:22 | req |
| src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:82:27:82:29 | req |
| src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:92:10:92:12 | req |
| src/advanced-routehandler-registration.js:92:9:92:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:92:40:92:42 | req |
| src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:100:20:100:22 | req |
| src/advanced-routehandler-registration.js:100:11:102:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:101:31:101:33 | req |
| src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:100:20:100:22 | req |
| src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:101:31:101:33 | req |
| src/advanced-routehandler-registration.js:111:9:111:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:111:10:111:12 | req |
@@ -2541,6 +2627,7 @@ test_RouteHandler_getARequestExpr
| src/advanced-routehandler-registration.js:123:20:123:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:123:46:123:48 | req |
| src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:124:21:124:23 | req |
| src/advanced-routehandler-registration.js:124:20:124:49 | (req, r ... og(req) | src/advanced-routehandler-registration.js:124:46:124:48 | req |
| src/advanced-routehandler-registration.js:146:28:146:50 | (req, r ... defined | src/advanced-routehandler-registration.js:146:29:146:31 | req |
| src/advanced-routehandler-registration.js:156:21:156:50 | (req, r ... og(req) | src/advanced-routehandler-registration.js:156:22:156:24 | req |
| src/advanced-routehandler-registration.js:156:21:156:50 | (req, r ... og(req) | src/advanced-routehandler-registration.js:156:47:156:49 | req |
| src/advanced-routehandler-registration.js:157:27:157:56 | (req, r ... og(req) | src/advanced-routehandler-registration.js:157:28:157:30 | req |
@@ -2611,6 +2698,9 @@ getRouteHandlerContainerStep
| src/advanced-routehandler-registration.js:14:15:17:1 | {\\n a: ... (req)\\n} | src/advanced-routehandler-registration.js:16:6:16:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:18:12:18:18 | handler |
| src/advanced-routehandler-registration.js:23:15:26:1 | {\\n a: ... (req)\\n} | src/advanced-routehandler-registration.js:24:6:24:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:28:14:28:23 | routes2[p] |
| src/advanced-routehandler-registration.js:23:15:26:1 | {\\n a: ... (req)\\n} | src/advanced-routehandler-registration.js:25:6:25:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:28:14:28:23 | routes2[p] |
| src/advanced-routehandler-registration.js:54:22:62:1 | {\\n han ... ;\\n }\\n} | src/advanced-routehandler-registration.js:59:11:61:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:64:23:64:43 | mySimpl ... .handle |
| src/advanced-routehandler-registration.js:67:24:72:1 | {\\n han ... ;\\n }\\n} | src/advanced-routehandler-registration.js:68:12:68:41 | (req, r ... og(req) | src/advanced-routehandler-registration.js:70:5:70:16 | this.handler |
| src/advanced-routehandler-registration.js:67:24:72:1 | {\\n han ... ;\\n }\\n} | src/advanced-routehandler-registration.js:69:11:71:3 | functio ... s);\\n } | src/advanced-routehandler-registration.js:73:23:73:45 | mySimpl ... .handle |
| src/advanced-routehandler-registration.js:85:15:88:1 | {\\n a: ... (req)\\n} | src/advanced-routehandler-registration.js:86:6:86:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:90:20:90:29 | routes3[p] |
| src/advanced-routehandler-registration.js:85:15:88:1 | {\\n a: ... (req)\\n} | src/advanced-routehandler-registration.js:87:6:87:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:90:20:90:29 | routes3[p] |
| src/advanced-routehandler-registration.js:104:15:107:1 | {\\n a: ... (req)\\n} | src/advanced-routehandler-registration.js:105:6:105:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:109:20:109:29 | routes4[p] |

View File

@@ -46,7 +46,9 @@
| src/tst.js:43:18:43:38 | functio ... res) {} |
| src/tst.js:46:1:46:23 | functio ... res) {} |
| src/tst.js:52:1:54:1 | functio ... req()\\n} |
| src/tst.js:56:1:58:1 | functio ... s) {\\n\\n} |
| src/tst.js:61:1:63:1 | functio ... turn;\\n} |
| src/tst.js:65:1:67:1 | functio ... rn x;\\n} |
| src/tst.js:70:5:72:5 | functio ... \\n\\n } |
| src/tst.js:74:5:76:5 | functio ... \\n\\n } |
| src/tst.js:79:5:81:5 | functio ... \\n\\n } |

View File

@@ -1,6 +1,8 @@
| src/RouterExample.js:4:65:10:1 | (req, r ... ;\\n }\\n} |
| src/app-in-property.js:6:13:6:32 | function(req, res){} |
| src/app-in-property.js:14:21:14:40 | function(req, res){} |
| src/bound-handler.js:4:1:4:28 | functio ... res){} |
| src/bound-handler.js:9:12:9:31 | function(req, res){} |
| src/connect.js:5:9:5:27 | function(req,res){} |
| src/connect.js:8:12:8:31 | function(req, res){} |
| src/connect.js:12:9:12:27 | function(req,res){} |

View File

@@ -47,7 +47,9 @@
| src/tst.js:43:18:43:38 | functio ... res) {} |
| src/tst.js:46:1:46:23 | functio ... res) {} |
| src/tst.js:52:1:54:1 | functio ... req()\\n} |
| src/tst.js:56:1:58:1 | functio ... s) {\\n\\n} |
| src/tst.js:61:1:63:1 | functio ... turn;\\n} |
| src/tst.js:65:1:67:1 | functio ... rn x;\\n} |
| src/tst.js:70:5:72:5 | functio ... \\n\\n } |
| src/tst.js:74:5:76:5 | functio ... \\n\\n } |
| src/tst.js:79:5:81:5 | functio ... \\n\\n } |

View File

@@ -1,5 +1,3 @@
| src/bound-handler.js:4:1:4:28 | functio ... res){} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
| src/bound-handler.js:9:12:9:31 | function(req, res){} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
| src/hapi.js:1:1:1:30 | functio ... t, h){} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
| src/iterated-handlers.js:4:2:4:22 | functio ... res){} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
| src/route-objects.js:7:19:7:38 | function(req, res){} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
@@ -11,6 +9,8 @@
| src/route-objects.js:56:12:58:5 | functio ... ;\\n } | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
| src/tst.js:46:1:46:23 | functio ... res) {} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
| src/tst.js:52:1:54:1 | functio ... req()\\n} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
| src/tst.js:56:1:58:1 | functio ... s) {\\n\\n} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
| src/tst.js:61:1:63:1 | functio ... turn;\\n} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
| src/tst.js:65:1:67:1 | functio ... rn x;\\n} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
| src/tst.js:70:5:72:5 | functio ... \\n\\n } | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
| src/tst.js:109:16:111:9 | functio ... } | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |

View File

@@ -2,3 +2,14 @@ var https = require('https');
https.createServer(function (req, res) {});
https.createServer(o, function (req, res) {});
require('http2').createServer((req, res) => {});
require("tls").createServer((socket) => {
socket.on("data", (data) => {})
});
const net = require('net');
const tls = require('tls');
const server = (isSecure ? tls : net).createServer(options, (socket) => {
socket.on("data", (data) => {})
});

View File

@@ -68,3 +68,9 @@ function getArrowHandler() {
return (req,res) => f();
}
http.createServer(getArrowHandler());
http.createServer(function (req, res) {
req.on("data", chunk => { // RemoteFlowSource
res.send(chunk);
})
});

View File

@@ -0,0 +1,36 @@
var http = require('http');
function decorate(method) {
return function(req, res) {
return method.call(this, req, res);
};
}
function Server(routes) {
this.routes = routes;
}
Server.prototype = {
requestHandler: function() {
var routes = this.routes;
return function(req, res) { // route handler
var handler = routes[req.url] || routes['*'];
return handler.call(this, req, res);
}.bind(this);
},
};
var routes = {
'/foo/bar': decorate((req, res) => { // route handler
res.end("foo");
}),
'/bar/foo': function(req, res) { // route handler
res.end("bar");
}
};
var appServer = new Server(routes);
var server = http.createServer(appServer.requestHandler());
server.listen(8080, () => {});

View File

@@ -0,0 +1,18 @@
var http = require('http');
// These are exceptions where we override the routes
var handlers = {
someKey: myIndirectHandler
};
function get(req, res) { // route handler
handlers[req.params.key.toLowerCase()](req, res);
}
function myIndirectHandler(req, res) { // route handler
res.setHeader('Content-Type', 'application/json');
res.send("\"some result\"");
}
var server = http.createServer(get);

View File

@@ -8,8 +8,11 @@ test_isCreateServer
| src/http.js:60:1:60:33 | createS ... res){}) |
| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) |
| src/http.js:70:1:70:36 | http.cr ... dler()) |
| src/http.js:72:1:76:2 | http.cr ... })\\n}) |
| src/https.js:4:14:10:2 | https.c ... foo;\\n}) |
| src/https.js:12:1:16:2 | https.c ... r");\\n}) |
| src/indirect2.js:18:14:18:35 | http.cr ... er(get) |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) |
test_RequestInputAccess
| src/http.js:6:26:6:32 | req.url | url | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
| src/http.js:8:3:8:20 | req.headers.cookie | cookie | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
@@ -17,14 +20,17 @@ test_RequestInputAccess
| src/https.js:6:26:6:32 | req.url | url | src/https.js:4:33:10:1 | functio ... .foo;\\n} |
| src/https.js:8:3:8:20 | req.headers.cookie | cookie | src/https.js:4:33:10:1 | functio ... .foo;\\n} |
| src/https.js:9:3:9:17 | req.headers.foo | header | src/https.js:4:33:10:1 | functio ... .foo;\\n} |
| src/indirect.js:17:28:17:34 | req.url | url | src/indirect.js:16:12:20:5 | functio ... ;\\n } |
test_RouteHandler_getAResponseHeader
| src/http.js:4:32:10:1 | functio ... .foo;\\n} | location | src/http.js:7:3:7:42 | res.wri ... rget }) |
| src/http.js:12:19:16:1 | functio ... ar");\\n} | content-type | src/http.js:13:3:13:44 | res.set ... /html') |
| src/https.js:4:33:10:1 | functio ... .foo;\\n} | location | src/https.js:7:3:7:42 | res.wri ... rget }) |
| src/https.js:12:20:16:1 | functio ... ar");\\n} | content-type | src/https.js:13:3:13:44 | res.set ... /html') |
| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | content-type | src/indirect2.js:14:3:14:51 | res.set ... /json') |
test_HeaderDefinition_defines
| src/http.js:13:3:13:44 | res.set ... /html') | content-type | text/html |
| src/https.js:13:3:13:44 | res.set ... /html') | content-type | text/html |
| src/indirect2.js:14:3:14:51 | res.set ... /json') | content-type | application/json |
test_SystemCommandExecution
| es6-imported-exec.js:3:1:3:11 | exec("cmd") | es6-imported-exec.js:3:6:3:10 | "cmd" |
| exec.js:3:1:3:38 | cp.exec ... "], cb) | exec.js:3:13:3:18 | "node" |
@@ -48,18 +54,32 @@ test_ResponseExpr
| src/http.js:63:3:63:5 | res | src/http.js:62:19:65:1 | functio ... r2");\\n} |
| src/http.js:64:3:64:5 | res | src/http.js:62:19:65:1 | functio ... r2");\\n} |
| src/http.js:68:17:68:19 | res | src/http.js:68:12:68:27 | (req,res) => f() |
| src/http.js:72:34:72:36 | res | src/http.js:72:19:76:1 | functio ... \\n })\\n} |
| src/http.js:74:5:74:7 | res | src/http.js:72:19:76:1 | functio ... \\n })\\n} |
| src/https.js:4:47:4:49 | res | src/https.js:4:33:10:1 | functio ... .foo;\\n} |
| src/https.js:7:3:7:5 | res | src/https.js:4:33:10:1 | functio ... .foo;\\n} |
| src/https.js:12:34:12:36 | res | src/https.js:12:20:16:1 | functio ... ar");\\n} |
| src/https.js:13:3:13:5 | res | src/https.js:12:20:16:1 | functio ... ar");\\n} |
| src/https.js:14:3:14:5 | res | src/https.js:12:20:16:1 | functio ... ar");\\n} |
| src/https.js:15:3:15:5 | res | src/https.js:12:20:16:1 | functio ... ar");\\n} |
| src/indirect2.js:9:19:9:21 | res | src/indirect2.js:9:1:11:1 | functio ... res);\\n} |
| src/indirect2.js:10:47:10:49 | res | src/indirect2.js:9:1:11:1 | functio ... res);\\n} |
| src/indirect2.js:13:33:13:35 | res | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} |
| src/indirect2.js:14:3:14:5 | res | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} |
| src/indirect2.js:15:3:15:5 | res | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} |
| src/indirect.js:16:26:16:28 | res | src/indirect.js:16:12:20:5 | functio ... ;\\n } |
| src/indirect.js:19:38:19:40 | res | src/indirect.js:16:12:20:5 | functio ... ;\\n } |
| src/indirect.js:25:30:25:32 | res | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } |
| src/indirect.js:26:5:26:7 | res | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } |
| src/indirect.js:28:29:28:31 | res | src/indirect.js:28:15:30:3 | functio ... ");\\n } |
| src/indirect.js:29:5:29:7 | res | src/indirect.js:28:15:30:3 | functio ... ");\\n } |
test_HeaderDefinition
| src/http.js:7:3:7:42 | res.wri ... rget }) | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
| src/http.js:13:3:13:44 | res.set ... /html') | src/http.js:12:19:16:1 | functio ... ar");\\n} |
| src/http.js:63:3:63:40 | res.set ... , "23") | src/http.js:62:19:65:1 | functio ... r2");\\n} |
| src/https.js:7:3:7:42 | res.wri ... rget }) | src/https.js:4:33:10:1 | functio ... .foo;\\n} |
| src/https.js:13:3:13:44 | res.set ... /html') | src/https.js:12:20:16:1 | functio ... ar");\\n} |
| src/indirect2.js:14:3:14:51 | res.set ... /json') | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} |
test_RouteSetup_getServer
| createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:1:2:42 | https.c ... es) {}) |
| createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:1:3:45 | https.c ... es) {}) |
@@ -70,8 +90,11 @@ test_RouteSetup_getServer
| src/http.js:60:1:60:33 | createS ... res){}) | src/http.js:60:1:60:33 | createS ... res){}) |
| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | src/http.js:62:1:65:2 | http.cr ... 2");\\n}) |
| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:70:1:70:36 | http.cr ... dler()) |
| src/http.js:72:1:76:2 | http.cr ... })\\n}) | src/http.js:72:1:76:2 | http.cr ... })\\n}) |
| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | src/https.js:4:14:10:2 | https.c ... foo;\\n}) |
| src/https.js:12:1:16:2 | https.c ... r");\\n}) | src/https.js:12:1:16:2 | https.c ... r");\\n}) |
| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:18:14:18:35 | http.cr ... er(get) |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:34:14:34:58 | http.cr ... dler()) |
test_ClientRequest
| src/http.js:18:1:18:30 | http.re ... uth" }) |
| src/http.js:21:15:26:6 | http.re ... \\n }) |
@@ -82,6 +105,7 @@ test_HeaderDefinition_getAHeaderName
| src/http.js:13:3:13:44 | res.set ... /html') | content-type |
| src/https.js:7:3:7:42 | res.wri ... rget }) | location |
| src/https.js:13:3:13:44 | res.set ... /html') | content-type |
| src/indirect2.js:14:3:14:51 | res.set ... /json') | content-type |
test_ServerDefinition
| createServer.js:2:1:2:42 | https.c ... es) {}) |
| createServer.js:3:1:3:45 | https.c ... es) {}) |
@@ -92,8 +116,11 @@ test_ServerDefinition
| src/http.js:60:1:60:33 | createS ... res){}) |
| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) |
| src/http.js:70:1:70:36 | http.cr ... dler()) |
| src/http.js:72:1:76:2 | http.cr ... })\\n}) |
| src/https.js:4:14:10:2 | https.c ... foo;\\n}) |
| src/https.js:12:1:16:2 | https.c ... r");\\n}) |
| src/indirect2.js:18:14:18:35 | http.cr ... er(get) |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) |
test_HeaderAccess
| src/http.js:9:3:9:17 | req.headers.foo | foo |
| src/https.js:9:3:9:17 | req.headers.foo | foo |
@@ -103,6 +130,7 @@ test_HeaderDefinition_getNameExpr
| src/http.js:63:3:63:40 | res.set ... , "23") | src/http.js:63:17:63:33 | req.query.myParam |
| src/https.js:7:3:7:42 | res.wri ... rget }) | src/https.js:7:17:7:19 | 302 |
| src/https.js:13:3:13:44 | res.set ... /html') | src/https.js:13:17:13:30 | 'Content-Type' |
| src/indirect2.js:14:3:14:51 | res.set ... /json') | src/indirect2.js:14:17:14:30 | 'Content-Type' |
test_RouteHandler_getAResponseExpr
| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:35:2:37 | res |
| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:38:3:40 | res |
@@ -119,12 +147,25 @@ test_RouteHandler_getAResponseExpr
| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:63:3:63:5 | res |
| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:64:3:64:5 | res |
| src/http.js:68:12:68:27 | (req,res) => f() | src/http.js:68:17:68:19 | res |
| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:34:72:36 | res |
| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:74:5:74:7 | res |
| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:47:4:49 | res |
| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:7:3:7:5 | res |
| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:12:34:12:36 | res |
| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:13:3:13:5 | res |
| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:14:3:14:5 | res |
| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:15:3:15:5 | res |
| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:19:9:21 | res |
| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:47:10:49 | res |
| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:13:33:13:35 | res |
| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:14:3:14:5 | res |
| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:15:3:15:5 | res |
| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:26:16:28 | res |
| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:19:38:19:40 | res |
| src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:25:30:25:32 | res |
| src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:26:5:26:7 | res |
| src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:28:29:28:31 | res |
| src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:29:5:29:7 | res |
test_ServerDefinition_getARouteHandler
| createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} |
| createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:23:3:44 | functio ... res) {} |
@@ -135,14 +176,22 @@ test_ServerDefinition_getARouteHandler
| src/http.js:60:1:60:33 | createS ... res){}) | src/http.js:60:14:60:32 | function(req,res){} |
| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | src/http.js:62:19:65:1 | functio ... r2");\\n} |
| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:68:12:68:27 | (req,res) => f() |
| src/http.js:72:1:76:2 | http.cr ... })\\n}) | src/http.js:72:19:76:1 | functio ... \\n })\\n} |
| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | src/https.js:4:33:10:1 | functio ... .foo;\\n} |
| src/https.js:12:1:16:2 | https.c ... r");\\n}) | src/https.js:12:20:16:1 | functio ... ar");\\n} |
| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:9:1:11:1 | functio ... res);\\n} |
| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:16:12:20:5 | functio ... ;\\n } |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:28:15:30:3 | functio ... ");\\n } |
test_ResponseSendArgument
| src/http.js:14:13:14:17 | "foo" | src/http.js:12:19:16:1 | functio ... ar");\\n} |
| src/http.js:15:11:15:15 | "bar" | src/http.js:12:19:16:1 | functio ... ar");\\n} |
| src/http.js:64:11:64:16 | "bar2" | src/http.js:62:19:65:1 | functio ... r2");\\n} |
| src/https.js:14:13:14:17 | "foo" | src/https.js:12:20:16:1 | functio ... ar");\\n} |
| src/https.js:15:11:15:15 | "bar" | src/https.js:12:20:16:1 | functio ... ar");\\n} |
| src/indirect.js:26:13:26:17 | "foo" | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } |
| src/indirect.js:29:13:29:17 | "bar" | src/indirect.js:28:15:30:3 | functio ... ");\\n } |
test_RouteSetup_getARouteHandler
| createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} |
| createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:23:3:44 | functio ... res) {} |
@@ -157,12 +206,26 @@ test_RouteSetup_getARouteHandler
| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:67:1:69:1 | return of function getArrowHandler |
| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:68:12:68:27 | (req,res) => f() |
| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:70:19:70:35 | getArrowHandler() |
| src/http.js:72:1:76:2 | http.cr ... })\\n}) | src/http.js:72:19:76:1 | functio ... \\n })\\n} |
| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | src/https.js:4:33:10:1 | functio ... .foo;\\n} |
| src/https.js:12:1:16:2 | https.c ... r");\\n}) | src/https.js:12:20:16:1 | functio ... ar");\\n} |
| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:9:1:11:1 | functio ... res);\\n} |
| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:10:3:10:40 | handler ... Case()] |
| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:14:19:21:3 | return of method requestHandler |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:16:12:20:5 | functio ... ;\\n } |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:16:12:20:16 | functio ... d(this) |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:17:21:17:35 | routes[req.url] |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:17:40:17:50 | routes['*'] |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:28:15:30:3 | functio ... ");\\n } |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:34:32:34:57 | appServ ... ndler() |
test_ClientRequest_getADataNode
| src/http.js:27:16:27:73 | http.re ... POST'}) | src/http.js:50:16:50:22 | 'stuff' |
| src/http.js:27:16:27:73 | http.re ... POST'}) | src/http.js:51:14:51:25 | 'more stuff' |
test_RemoteFlowSources
| createServer.js:7:24:7:27 | data |
| createServer.js:14:24:14:27 | data |
| src/http.js:6:26:6:32 | req.url |
| src/http.js:8:3:8:20 | req.headers.cookie |
| src/http.js:9:3:9:17 | req.headers.foo |
@@ -170,9 +233,11 @@ test_RemoteFlowSources
| src/http.js:30:28:30:32 | chunk |
| src/http.js:40:23:40:30 | authInfo |
| src/http.js:45:23:45:27 | error |
| src/http.js:73:18:73:22 | chunk |
| src/https.js:6:26:6:32 | req.url |
| src/https.js:8:3:8:20 | req.headers.cookie |
| src/https.js:9:3:9:17 | req.headers.foo |
| src/indirect.js:17:28:17:34 | req.url |
test_RouteHandler
| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:1:2:42 | https.c ... es) {}) |
| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:1:3:45 | https.c ... es) {}) |
@@ -183,8 +248,14 @@ test_RouteHandler
| src/http.js:60:14:60:32 | function(req,res){} | src/http.js:60:1:60:33 | createS ... res){}) |
| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:1:65:2 | http.cr ... 2");\\n}) |
| src/http.js:68:12:68:27 | (req,res) => f() | src/http.js:70:1:70:36 | http.cr ... dler()) |
| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:1:76:2 | http.cr ... })\\n}) |
| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:14:10:2 | https.c ... foo;\\n}) |
| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:12:1:16:2 | https.c ... r");\\n}) |
| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:18:14:18:35 | http.cr ... er(get) |
| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:18:14:18:35 | http.cr ... er(get) |
| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) |
| src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) |
| src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) |
test_RequestExpr
| createServer.js:2:30:2:32 | req | createServer.js:2:20:2:41 | functio ... res) {} |
| createServer.js:3:33:3:35 | req | createServer.js:3:23:3:44 | functio ... res) {} |
@@ -199,11 +270,22 @@ test_RequestExpr
| src/http.js:62:28:62:30 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} |
| src/http.js:63:17:63:19 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} |
| src/http.js:68:13:68:15 | req | src/http.js:68:12:68:27 | (req,res) => f() |
| src/http.js:72:29:72:31 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} |
| src/http.js:73:3:73:5 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} |
| src/https.js:4:42:4:44 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} |
| src/https.js:6:26:6:28 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} |
| src/https.js:8:3:8:5 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} |
| src/https.js:9:3:9:5 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} |
| src/https.js:12:29:12:31 | req | src/https.js:12:20:16:1 | functio ... ar");\\n} |
| src/indirect2.js:9:14:9:16 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} |
| src/indirect2.js:10:12:10:14 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} |
| src/indirect2.js:10:42:10:44 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} |
| src/indirect2.js:13:28:13:30 | req | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} |
| src/indirect.js:16:21:16:23 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } |
| src/indirect.js:17:28:17:30 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } |
| src/indirect.js:19:33:19:35 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } |
| src/indirect.js:25:25:25:27 | req | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } |
| src/indirect.js:28:24:28:26 | req | src/indirect.js:28:15:30:3 | functio ... ");\\n } |
test_SystemCommandExecution_getAnArgumentForCommand
| exec.js:3:1:3:38 | cp.exec ... "], cb) | exec.js:3:21:3:33 | ["--version"] |
| exec.js:4:1:4:47 | cp.exec ... sion"]) | exec.js:4:23:4:46 | ["-c", ... rsion"] |
@@ -227,8 +309,19 @@ test_RouteHandler_getARequestExpr
| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:28:62:30 | req |
| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:63:17:63:19 | req |
| src/http.js:68:12:68:27 | (req,res) => f() | src/http.js:68:13:68:15 | req |
| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:29:72:31 | req |
| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:73:3:73:5 | req |
| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:42:4:44 | req |
| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:6:26:6:28 | req |
| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:8:3:8:5 | req |
| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:9:3:9:5 | req |
| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:12:29:12:31 | req |
| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:14:9:16 | req |
| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:12:10:14 | req |
| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:42:10:44 | req |
| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:13:28:13:30 | req |
| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:21:16:23 | req |
| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:17:28:17:30 | req |
| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:19:33:19:35 | req |
| src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:25:25:25:27 | req |
| src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:28:24:28:26 | req |

View File

@@ -3,6 +3,7 @@
| mssql2.js:5:15:5:34 | 'select 1 as number' |
| mssql2.js:13:15:13:66 | 'create ... table' |
| mssql2.js:22:24:22:43 | 'select 1 as number' |
| mssql2.js:29:30:29:81 | 'create ... table' |
| mysql1.js:13:18:13:43 | 'SELECT ... lution' |
| mysql1.js:18:18:22:1 | {\\n s ... vid']\\n} |
| mysql1a.js:17:18:17:43 | 'SELECT ... lution' |

Some files were not shown because too many files have changed in this diff Show More