mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Merge branch 'main' into CVE760-reexport
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/**
|
||||
* @deprecated
|
||||
* @name External dependency source links
|
||||
* @kind source-link
|
||||
* @metricType externalDependency
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 + "'")
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @id js/incomplete-hostname-regexp
|
||||
* @tags correctness
|
||||
* security
|
||||
* external/cwe/cwe-20
|
||||
* external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @id js/incomplete-url-substring-sanitization
|
||||
* @tags correctness
|
||||
* security
|
||||
* external/cwe/cwe-20
|
||||
* external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @id js/regex/missing-regexp-anchor
|
||||
* @tags correctness
|
||||
* security
|
||||
* external/cwe/cwe-20
|
||||
* external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* @id js/useless-regexp-character-escape
|
||||
* @tags correctness
|
||||
* security
|
||||
* external/cwe/cwe-20
|
||||
* external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* @tags correctness
|
||||
* security
|
||||
* external/cwe/cwe-116
|
||||
* external/cwe/cwe-20
|
||||
* external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* @tags security
|
||||
* external/cwe/cwe-079
|
||||
* external/cwe/cwe-116
|
||||
* external/cwe/cwe-20
|
||||
* external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @tags correctness
|
||||
* security
|
||||
* external/cwe/cwe-116
|
||||
* external/cwe/cwe-20
|
||||
* external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @id js/missing-postmessageorigin-verification
|
||||
* @tags correctness
|
||||
* security
|
||||
* external/cwe/cwe-20
|
||||
* external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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..
|
||||
|
||||
15
javascript/ql/src/meta/ApiGraphs/ApiGraphEdges.ql
Normal file
15
javascript/ql/src/meta/ApiGraphs/ApiGraphEdges.ql
Normal 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))
|
||||
14
javascript/ql/src/meta/ApiGraphs/ApiGraphNodes.ql
Normal file
14
javascript/ql/src/meta/ApiGraphs/ApiGraphNodes.ql
Normal 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)
|
||||
14
javascript/ql/src/meta/ApiGraphs/ApiGraphPointsToEdges.ql
Normal file
14
javascript/ql/src/meta/ApiGraphs/ApiGraphPointsToEdges.ql
Normal 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))
|
||||
15
javascript/ql/src/meta/ApiGraphs/ApiGraphRhsNodes.ql
Normal file
15
javascript/ql/src/meta/ApiGraphs/ApiGraphRhsNodes.ql
Normal 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())
|
||||
14
javascript/ql/src/meta/ApiGraphs/ApiGraphUseNodes.ql
Normal file
14
javascript/ql/src/meta/ApiGraphs/ApiGraphUseNodes.ql
Normal 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())
|
||||
@@ -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`
|
||||
|
||||
@@ -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()) }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) }
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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`.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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() = "/"
|
||||
|
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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("['\"&<>]")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ module PolynomialReDoS {
|
||||
name = "split" or
|
||||
name = "matchAll" or
|
||||
name = "replace" or
|
||||
name = "replaceAll" or
|
||||
name = "search"
|
||||
)
|
||||
or
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
import ApiGraphs.VerifyAssertions
|
||||
8
javascript/ql/test/ApiGraphs/partial-invoke/index.js
Normal file
8
javascript/ql/test/ApiGraphs/partial-invoke/index.js
Normal 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))))
|
||||
);
|
||||
};
|
||||
3
javascript/ql/test/ApiGraphs/partial-invoke/package.json
Normal file
3
javascript/ql/test/ApiGraphs/partial-invoke/package.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"name": "partial-invoke"
|
||||
}
|
||||
@@ -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) |
|
||||
|
||||
@@ -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} |
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import javascript
|
||||
|
||||
query Parameter getDependencyParameter(AmdModuleDefinition mod, string name) {
|
||||
result = mod.getDependencyParameter(name)
|
||||
}
|
||||
|
||||
from AmdModuleDefinition d
|
||||
select d, d.getFactoryNode()
|
||||
|
||||
@@ -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' |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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} |
|
||||
|
||||
@@ -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> |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
6
javascript/ql/test/library-tests/AMD/tst5.js
Normal file
6
javascript/ql/test/library-tests/AMD/tst5.js
Normal file
@@ -0,0 +1,6 @@
|
||||
define(['./a', './dir/b'], function(a, {bar}, exports) {
|
||||
return {
|
||||
foo: a.foo,
|
||||
bar: bar
|
||||
};
|
||||
});
|
||||
@@ -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) |
|
||||
|
||||
@@ -83,4 +83,7 @@
|
||||
|
||||
o.notTracked = source1;
|
||||
var sink22 = o.notTracked;
|
||||
|
||||
var sink23 = source1.replaceAll(/f/g, "");
|
||||
var sink24 = "foo".replaceAll(/f/g, source1);
|
||||
})();
|
||||
|
||||
@@ -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
|
||||
})();
|
||||
@@ -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)
|
||||
})
|
||||
@@ -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
|
||||
});
|
||||
@@ -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$ |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -117,4 +117,8 @@
|
||||
})
|
||||
;
|
||||
|
||||
angular.module('myModule', [])
|
||||
.run(['moduleRunService', function({foo, bar}) {
|
||||
// ...
|
||||
}])
|
||||
})();
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
});
|
||||
})();
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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] |
|
||||
|
||||
@@ -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 } |
|
||||
|
||||
@@ -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){} |
|
||||
|
||||
@@ -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 } |
|
||||
|
||||
@@ -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`. |
|
||||
|
||||
@@ -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) => {})
|
||||
});
|
||||
@@ -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);
|
||||
})
|
||||
});
|
||||
@@ -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, () => {});
|
||||
@@ -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);
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user