Merge branch 'main' into java/merge-5226

This commit is contained in:
Anders Schack-Mulligen
2021-03-04 11:36:16 +01:00
312 changed files with 12208 additions and 2114 deletions

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* TypeScript 4.2 is now supported.

View File

@@ -0,0 +1,4 @@
lgtm,codescanning
* Sources of user input and sinks for `js/request-forgery` in the http-proxy are now recognized.
Affected packages are
[http-proxy](https://www.npmjs.com/package/http-proxy)

View File

@@ -0,0 +1,4 @@
lgtm,codescanning
* URIs used in the form-data library are now recognized as sinks for `js/request-forgery`.
Affected packages are
[form-data](https://www.npmjs.com/package/form-data)

View File

@@ -0,0 +1,8 @@
lgtm,codescanning
* The security queries now recognize the effect of JSON schema validation, and highlights
cases where this validation is susceptible to denial-of-service attacks.
Affects the package [ajv](https://npmjs.com/package/ajv).
* A new query, `js/resource-exhaustion-from-deep-object-traversal`, has been added to the query suite,
highlighting denial-of-service attacks exploiting operations that traverse deeply user-controlled objects.
* The `js/xss-through-exception` query now recognizes JSON schema validation errors as a source, as they
may contain part of the input data.

View File

@@ -2,7 +2,7 @@
"name": "typescript-parser-wrapper",
"private": true,
"dependencies": {
"typescript": "4.1.2"
"typescript": "4.2.2"
},
"scripts": {
"build": "tsc --project tsconfig.json",

View File

@@ -632,7 +632,14 @@ export class TypeTable {
? tupleType.minLength
: this.typeChecker.getTypeArguments(tupleReference).length;
let hasRestElement = tupleType.hasRestElement ? 't' : 'f';
let prefix = `tuple;${minLength};${hasRestElement}`;
let restIndex = -1;
for (let i = 0; i < tupleType.elementFlags.length; i++) {
if (tupleType.elementFlags[i] & ts.ElementFlags.Rest) {
restIndex = i;
break;
}
}
let prefix = `tuple;${minLength};${restIndex}`;
return this.makeTypeStringVectorFromTypeReferenceArguments(prefix, type);
}
if (objectFlags & ts.ObjectFlags.Anonymous) {
@@ -940,6 +947,9 @@ export class TypeTable {
* Returns a unique string for the given call/constructor signature.
*/
private getSignatureString(kind: ts.SignatureKind, signature: AugmentedSignature): string {
let modifiers : ts.ModifiersArray = signature.getDeclaration()?.modifiers;
let isAbstract = modifiers && modifiers.filter(modifier => modifier.kind == ts.SyntaxKind.AbstractKeyword).length > 0
let parameters = signature.getParameters();
let numberOfTypeParameters = signature.typeParameters == null
? 0
@@ -971,7 +981,7 @@ export class TypeTable {
if (returnTypeId == null) {
return null;
}
let tag = `${kind};${numberOfTypeParameters};${requiredParameters};${restParameterTag};${returnTypeId}`;
let tag = `${kind};${isAbstract ? "t" : "f"};${numberOfTypeParameters};${requiredParameters};${restParameterTag};${returnTypeId}`;
for (let typeParameter of signature.typeParameters || []) {
tag += ";" + typeParameter.symbol.name;
let constraint = typeParameter.getConstraint();

View File

@@ -6,7 +6,7 @@
version "12.7.11"
resolved node-12.7.11.tgz#be879b52031cfb5d295b047f5462d8ef1a716446
typescript@4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.2.tgz#6369ef22516fe5e10304aae5a5c4862db55380e9"
integrity sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==
typescript@4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.2.tgz#1450f020618f872db0ea17317d16d8da8ddb8c4c"
integrity sha512-tbb+NVrLfnsJy3M59lsDgrzWIflR4d4TIUjz+heUnHZwdF7YsrMTKoRERiIvI2lvBG95dfpLxB21WZhys1bgaQ==

View File

@@ -43,7 +43,7 @@ public class Main {
* A version identifier that should be updated every time the extractor changes in such a way that
* it may produce different tuples for the same file under the same {@link ExtractorConfig}.
*/
public static final String EXTRACTOR_VERSION = "2021-02-05";
public static final String EXTRACTOR_VERSION = "2021-02-24";
public static final Pattern NEWLINE = Pattern.compile("\n");

View File

@@ -118,10 +118,11 @@ public class TypeExtractor {
}
case tupleKind:
{
// The first two parts denote minimum length and presence of rest element.
// The first two parts denote minimum length and index of rest element (or -1 if no rest element).
trapWriter.addTuple("tuple_type_min_length", lbl, Integer.parseInt(parts[1]));
if (parts[2].equals("t")) {
trapWriter.addTuple("tuple_type_rest", lbl);
int restIndex = Integer.parseInt(parts[2]);
if (restIndex != -1) {
trapWriter.addTuple("tuple_type_rest_index", lbl, restIndex);
}
firstChild += 2;
break;
@@ -201,18 +202,22 @@ public class TypeExtractor {
private void extractSignature(int index) {
// Format is:
// kind;numTypeParams;requiredParams;restParamType;returnType(;paramName;paramType)*
// kind;isAbstract;numTypeParams;requiredParams;restParamType;returnType(;paramName;paramType)*
String[] parts = split(table.getSignatureString(index));
Label label = trapWriter.globalID("signature;" + index);
int kind = Integer.parseInt(parts[0]);
int numberOfTypeParameters = Integer.parseInt(parts[1]);
int requiredParameters = Integer.parseInt(parts[2]);
String restParamTypeTag = parts[3];
boolean isAbstract = parts[1].equals("t");
if (isAbstract) {
trapWriter.addTuple("is_abstract_signature", label);
}
int numberOfTypeParameters = Integer.parseInt(parts[2]);
int requiredParameters = Integer.parseInt(parts[3]);
String restParamTypeTag = parts[4];
if (!restParamTypeTag.isEmpty()) {
trapWriter.addTuple(
"signature_rest_parameter", label, trapWriter.globalID("type;" + restParamTypeTag));
}
Label returnType = trapWriter.globalID("type;" + parts[4]);
Label returnType = trapWriter.globalID("type;" + parts[5]);
trapWriter.addTuple(
"signature_types",
label,
@@ -221,9 +226,9 @@ public class TypeExtractor {
numberOfTypeParameters,
requiredParameters);
trapWriter.addTuple("signature_contains_type", returnType, label, -1);
int numberOfParameters = (parts.length - 5) / 2; // includes type parameters
int numberOfParameters = (parts.length - 6) / 2; // includes type parameters
for (int i = 0; i < numberOfParameters; ++i) {
int partIndex = 5 + (2 * i);
int partIndex = 6 + (2 * i);
String paramName = parts[partIndex];
String paramTypeId = parts[partIndex + 1];
if (paramTypeId.length() > 0) { // Unconstrained type parameters have an empty type ID.

View File

@@ -5,8 +5,8 @@
<overview>
<p>
Directly writing exceptions to a webpage without sanitization allows for a cross-site scripting
vulnerability if the value of the exception can be influenced by a user.
Directly writing error messages to a webpage without sanitization allows for a cross-site scripting
vulnerability if parts of the error message can be influenced by a user.
</p>
</overview>
@@ -27,6 +27,19 @@ leaving the website vulnerable to cross-site scripting.
<sample src="examples/ExceptionXss.js" />
</example>
<example>
<p>
This second example shows an input being validated using the JSON schema validator <code>ajv</code>,
and in case of an error, the error message is sent directly back in the response.
</p>
<sample src="examples/ExceptionXssAjv.js" />
<p>
This is unsafe, because the error message can contain parts of the input.
For example, the input <code>{'&lt;img src=x onerror=alert(1)&gt;': 'foo'}</code> will generate the error
<code>data/&lt;img src=x onerror=alert(1)&gt; should be number</code>, causing reflected XSS.
</p>
</example>
<references>
<li>
OWASP:

View File

@@ -19,4 +19,4 @@ from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink.getNode(), source, sink,
"$@ is reinterpreted as HTML without escaping meta-characters.", source.getNode(),
"Exception text"
source.getNode().(Source).getDescription()

View File

@@ -0,0 +1,13 @@
import express from 'express';
import Ajv from 'ajv';
let app = express();
let ajv = new Ajv();
ajv.addSchema({type: 'object', additionalProperties: {type: 'number'}}, 'pollData');
app.post('/polldata', (req, res) => {
if (!ajv.validate('pollData', req.body)) {
res.send(ajv.errorsText());
}
});

View File

@@ -0,0 +1,55 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Processing user-controlled data with a method that allocates excessive amounts
of memory can lead to denial of service.
</p>
<p>
If the JSON schema validation library <code>ajv</code> is configured with
<code>allErrors: true</code> there is no limit to how many error objects
will be allocated. An attacker can exploit this by sending an object that
deliberately contains a huge number of errors, and in some cases, with
longer and longer error messages. This can cause the service to become
unresponsive due to the slow error-checking process.
</p>
</overview>
<recommendation>
<p>
Do not use <code>allErrors: true</code> in production.
</p>
</recommendation>
<example>
<p>
In the example below, the user-submitted object <code>req.body</code> is
validated using <code>ajv</code> and <code>allErrors: true</code>:
</p>
<sample src="examples/DeepObjectResourceExhaustion.js"/>
<p>
Although this ensures that <code>req.body</code> conforms to the schema,
the validation itself could be vulnerable to a denial-of-service attack.
An attacker could send an object containing so many errors that the server
runs out of memory.
</p>
<p>
A solution is to not pass in <code>allErrors: true</code>, which means
<code>ajv</code> will only report the first error, not all of them:
</p>
<sample src="examples/DeepObjectResourceExhaustion_fixed.js"/>
</example>
<references>
<li>Ajv documentation: <a href="https://github.com/ajv-validator/ajv/blob/master/docs/security.md#untrusted-schemas">security considerations</a>
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,23 @@
/**
* @name Resources exhaustion from deep object traversal
* @description Processing user-controlled object hierarchies inefficiently can lead to denial of service.
* @kind path-problem
* @problem.severity warning
* @precision high
* @id js/resource-exhaustion-from-deep-object-traversal
* @tags security
* external/cwe/cwe-400
*/
import javascript
import DataFlow::PathGraph
import semmle.javascript.security.dataflow.DeepObjectResourceExhaustion::DeepObjectResourceExhaustion
from
Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node link,
string reason
where
cfg.hasFlowPath(source, sink) and
sink.getNode().(Sink).hasReason(link, reason)
select sink, source, sink, "Denial of service caused by processing user input from $@ with $@.",
source.getNode(), "here", link, reason

View File

@@ -0,0 +1,14 @@
import express from 'express';
import Ajv from 'ajv';
let ajv = new Ajv({ allErrors: true });
ajv.addSchema(require('./input-schema'), 'input');
var app = express();
app.get('/user/:id', function(req, res) {
if (!ajv.validate('input', req.body)) {
res.end(ajv.errorsText());
return;
}
// ...
});

View File

@@ -0,0 +1,14 @@
import express from 'express';
import Ajv from 'ajv';
let ajv = new Ajv({ allErrors: process.env['REST_DEBUG'] });
ajv.addSchema(require('./input-schema'), 'input');
var app = express();
app.get('/user/:id', function(req, res) {
if (!ajv.validate('input', req.body)) {
res.end(ajv.errorsText());
return;
}
// ...
});

View File

@@ -36,6 +36,7 @@ import semmle.javascript.InclusionTests
import semmle.javascript.JSDoc
import semmle.javascript.JSON
import semmle.javascript.JsonParsers
import semmle.javascript.JsonSchema
import semmle.javascript.JsonStringifiers
import semmle.javascript.JSX
import semmle.javascript.Lines
@@ -94,6 +95,7 @@ import semmle.javascript.frameworks.LazyCache
import semmle.javascript.frameworks.LodashUnderscore
import semmle.javascript.frameworks.Logging
import semmle.javascript.frameworks.HttpFrameworks
import semmle.javascript.frameworks.HttpProxy
import semmle.javascript.frameworks.Markdown
import semmle.javascript.frameworks.NoSQL
import semmle.javascript.frameworks.PkgCloud

View File

@@ -158,7 +158,7 @@ class AmdModuleDefinition extends CallExpr {
result = [getAnImplicitExportsValue(), getAnExplicitExportsValue()]
}
pragma[noinline]
pragma[noinline, nomagic]
private AbstractValue getAnImplicitExportsValue() {
// implicit exports: anything that is returned from the factory function
result = getModuleExpr().analyze().getAValue()

View File

@@ -25,7 +25,7 @@ module ArrayTaintTracking {
// `array.map(function (elt, i, ary) { ... })`: if `array` is tainted, then so are
// `elt` and `ary`; similar for `forEach`
exists(Function f |
call.getArgument(0).analyze().getAValue().(AbstractFunction).getFunction() = f and
call.getArgument(0).getAFunctionValue(0).getFunction() = f and
call.(DataFlow::MethodCallNode).getMethodName() = ["map", "forEach"] and
pred = call.getReceiver() and
succ = DataFlow::parameterNode(f.getParameter([0, 2]))

View File

@@ -344,7 +344,7 @@ module DOM {
or
exists(JQuery::MethodCall call | this = call and call.getMethodName() = "get" |
call.getNumArgument() = 1 and
forex(InferredType t | t = call.getArgument(0).analyze().getAType() | t = TTNumber())
unique(InferredType t | t = call.getArgument(0).analyze().getAType()) = TTNumber()
)
or
// A `this` node from a callback given to a `$().each(callback)` call.

View File

@@ -115,7 +115,7 @@ class Expr extends @expr, ExprOrStmt, ExprOrType, AST::ValueNode {
predicate isImpure() { any() }
/**
* Holds if this expression is pure, that is, is its evaluation is guaranteed
* Holds if this expression is pure, that is, its evaluation is guaranteed
* to be side-effect free.
*/
predicate isPure() { not isImpure() }

View File

@@ -415,7 +415,7 @@ module AccessPath {
pragma[inline]
DataFlow::SourceNode getAnAliasedSourceNode(DataFlow::Node node) {
exists(DataFlow::SourceNode root, string accessPath |
node = AccessPath::getAReferenceTo(root, accessPath) and
node = pragma[only_bind_into](AccessPath::getAReferenceTo(root, accessPath)) and
result = AccessPath::getAReferenceTo(root, accessPath)
)
or

View File

@@ -0,0 +1,129 @@
/**
* Provides classes and predicates for working with JSON schema libraries.
*/
import javascript
/**
* Provides classes and predicates for working with JSON schema libraries.
*/
module JsonSchema {
/** A call that validates an input against a JSON schema. */
abstract class ValidationCall extends DataFlow::CallNode {
/** Gets the data flow node whose value is being validated. */
abstract DataFlow::Node getInput();
/** Gets the return value that indicates successful validation. */
boolean getPolarity() { result = true }
}
/** A data flow node that is used a JSON schema. */
abstract class SchemaRoot extends DataFlow::Node { }
/** An object literal with a `$schema` property indicating it is the root of a JSON schema. */
private class SchemaNodeByTag extends SchemaRoot, DataFlow::ObjectLiteralNode {
SchemaNodeByTag() {
getAPropertyWrite("$schema").getRhs().getStringValue().matches("%//json-schema.org%")
}
}
/** Gets a data flow node that is part of a JSON schema. */
private DataFlow::SourceNode getAPartOfJsonSchema(DataFlow::TypeBackTracker t) {
t.start() and
result = any(SchemaRoot n).getALocalSource()
or
result = getAPartOfJsonSchema(t.continue()).getAPropertySource()
or
exists(DataFlow::TypeBackTracker t2 | result = getAPartOfJsonSchema(t2).backtrack(t2, t))
}
/** Gets a data flow node that is part of a JSON schema. */
DataFlow::SourceNode getAPartOfJsonSchema() {
result = getAPartOfJsonSchema(DataFlow::TypeBackTracker::end())
}
/** Provides a model of the `ajv` library. */
module Ajv {
/** A method on `Ajv` that returns `this`. */
private string chainedMethod() {
result =
["addSchema", "addMetaSchema", "removeSchema", "addFormat", "addKeyword", "removeKeyword"]
}
/** An instance of `ajv`. */
class Instance extends API::InvokeNode {
Instance() { this = API::moduleImport("ajv").getAnInstantiation() }
/** Gets the data flow node holding the options passed to this `Ajv` instance. */
DataFlow::Node getOptionsArg() { result = getArgument(0) }
/** Gets an API node that refers to this object. */
API::Node ref() {
result = getReturn()
or
result = ref().getMember(chainedMethod()).getReturn()
}
/**
* Gets an API node for a function produced by `new Ajv().compile()` or similar.
*
* Note that this does not include the instance method `new Ajv().validate` as its
* signature is different.
*/
API::Node getAValidationFunction() {
result = ref().getMember(["compile", "getSchema"]).getReturn()
or
result = ref().getMember("compileAsync").getPromised()
}
/**
* Gets an API node that refers to an error produced by this Ajv instance.
*/
API::Node getAValidationError() {
exists(API::Node base | base = [ref(), getAValidationFunction()] |
result = base.getMember("errors")
or
result = base.getMember("errorsText").getReturn()
)
}
}
/** A call to the `validate` method of `ajv`. */
class AjvValidationCall extends ValidationCall {
Instance instance;
int argIndex;
AjvValidationCall() {
this = instance.ref().getMember("validate").getACall() and argIndex = 1
or
this = instance.getAValidationFunction().getACall() and argIndex = 0
}
override DataFlow::Node getInput() { result = getArgument(argIndex) }
/** Gets the argument holding additional options to the call. */
DataFlow::Node getOwnOptionsArg() { result = getArgument(argIndex + 1) }
/** Gets a data flow passed as the extra options to this validation call or to the underlying `Ajv` instance. */
DataFlow::Node getAnOptionsArg() {
result = getOwnOptionsArg()
or
result = instance.getOptionsArg()
}
/** Gets the ajv instance doing the validation. */
Instance getAjvInstance() { result = instance }
}
private class AjvSchemaNode extends SchemaRoot {
AjvSchemaNode() {
this =
any(Instance i)
.ref()
.getMember(["addSchema", "validate", "compile", "compileAsync"])
.getParameter(0)
.getARhs()
}
}
}
}

View File

@@ -222,27 +222,27 @@ module MembershipCandidate {
*/
class ObjectPropertyNameMembershipCandidate extends MembershipCandidate::Range,
DataFlow::ValueNode {
DataFlow::ValueNode test;
DataFlow::ValueNode membersNode;
Expr test;
Expr membersNode;
ObjectPropertyNameMembershipCandidate() {
exists(InExpr inExpr |
this = inExpr.getLeftOperand().flow() and
test = inExpr.flow() and
membersNode = inExpr.getRightOperand().flow()
test = inExpr and
membersNode = inExpr.getRightOperand()
)
or
exists(DataFlow::MethodCallNode hasOwn |
this = hasOwn.getArgument(0) and
exists(MethodCallExpr hasOwn |
this = hasOwn.getArgument(0).flow() and
test = hasOwn and
hasOwn.calls(membersNode, "hasOwnProperty")
)
}
override DataFlow::Node getTest() { result = test }
override DataFlow::Node getTest() { result = test.flow() }
override string getAMemberString() {
exists(membersNode.getALocalSource().getAPropertyWrite(result))
exists(membersNode.flow().getALocalSource().getAPropertyWrite(result))
}
}

View File

@@ -107,6 +107,7 @@ abstract class Module extends TopLevel {
* Symbols defined in another module that are re-exported by
* this module are only sometimes considered.
*/
cached
abstract DataFlow::Node getAnExportedValue(string name);
/**

View File

@@ -865,6 +865,17 @@ predicate isInterpretedAsRegExp(DataFlow::Node source) {
// because `String.prototype.search` returns a number
not exists(PropAccess p | p.getBase() = mce.getEnclosingExpr())
)
or
exists(DataFlow::SourceNode schema | schema = JsonSchema::getAPartOfJsonSchema() |
source = schema.getAPropertyWrite("pattern").getRhs()
or
source =
schema
.getAPropertySource("patternProperties")
.getAPropertyWrite()
.getPropertyNameExpr()
.flow()
)
)
}

View File

@@ -520,7 +520,10 @@ class SsaExplicitDefinition extends SsaDefinition, TExplicitDef {
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
getDef().getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
exists(Location loc |
pragma[only_bind_into](loc) = pragma[only_bind_into](getDef()).getLocation() and
loc.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
)
}
/**
@@ -552,7 +555,10 @@ abstract class SsaImplicitDefinition extends SsaDefinition {
) {
endline = startline and
endcolumn = startcolumn and
getBasicBlock().getLocation().hasLocationInfo(filepath, startline, startcolumn, _, _)
exists(Location loc |
pragma[only_bind_into](loc) = pragma[only_bind_into](getBasicBlock()).getLocation() and
loc.hasLocationInfo(filepath, startline, startcolumn, _, _)
)
}
}
@@ -660,14 +666,6 @@ class SsaPhiNode extends SsaPseudoDefinition, TPhi {
override string prettyPrintDef() { result = getSourceVariable() + " = phi(" + ppInputs() + ")" }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
endline = startline and
endcolumn = startcolumn and
getBasicBlock().getLocation().hasLocationInfo(filepath, startline, startcolumn, _, _)
}
/**
* If all inputs to this phi node are (transitive) refinements of the same variable,
* gets that variable.

View File

@@ -95,7 +95,7 @@ class ControlStmt extends TControlStmt, Stmt {
}
/**
* A loop, that is, is a while loop, a do-while loop, a for loop, or a for-in loop.
* A loop, that is, a while loop, a do-while loop, a for loop, or a for-in loop.
*
* Examples:
*

View File

@@ -2149,18 +2149,23 @@ class TupleType extends ArrayType, @tuple_type {
int getMinimumLength() { tuple_type_min_length(this, result) }
/**
* Holds if this tuple type ends with a rest element, such as `[number, ...string[]]`.
* Gets the index of the rest element.
* For example, for a type `[number, ...string[]]` the result is 1,
* or for a type `[...number[], string]` the result is 0.
*/
predicate hasRestElement() { tuple_type_rest(this) }
int getRestElementIndex() { tuple_type_rest_index(this, result) }
/**
* Holds if this tuple type has a rest element, such as `[number, ...string[]]` or `[...number[], string]`.
*/
predicate hasRestElement() { exists(getRestElementIndex()) }
/**
* Gets the type of the rest element, if there is one.
*
* For example, the rest element of `[number, ...string[]]` is `string`.
*/
Type getRestElementType() {
hasRestElement() and result = getElementType(getNumElementType() - 1)
}
Type getRestElementType() { result = getElementType(getRestElementIndex()) }
}
/**
@@ -2789,6 +2794,11 @@ class CallSignatureType extends @signature_type {
* For example, for the signature `(...y: string[])`, this gets the type `string[]`.
*/
PlainArrayType getRestParameterArrayType() { signature_rest_parameter(this, result) }
/**
* Holds if this signature is abstract.
*/
predicate isAbstract() { is_abstract_signature(this) }
}
/**

View File

@@ -106,7 +106,11 @@ module DataFlow {
/** Holds if this node may evaluate to the Boolean value `b`. */
predicate mayHaveBooleanValue(boolean b) {
b = analyze().getAValue().(AbstractBoolean).getBooleanValue()
getAPredecessor().mayHaveBooleanValue(b)
or
b = true and asExpr().(BooleanLiteral).getValue() = "true"
or
b = false and asExpr().(BooleanLiteral).getValue() = "false"
}
/** Gets the integer value of this node, if it is an integer constant. */

View File

@@ -168,7 +168,13 @@ class InvokeNode extends DataFlow::SourceNode {
private ObjectLiteralNode getOptionsArgument(int i) { result.flowsTo(getArgument(i)) }
/** Gets an abstract value representing possible callees of this call site. */
final AbstractValue getACalleeValue() { result = getCalleeNode().analyze().getAValue() }
final AbstractValue getACalleeValue() {
exists(DataFlow::Node callee, DataFlow::AnalyzedNode analyzed |
pragma[only_bind_into](callee) = getCalleeNode() and
pragma[only_bind_into](analyzed) = callee.analyze() and
pragma[only_bind_into](result) = analyzed.getAValue()
)
}
/**
* Gets a potential callee of this call site.
@@ -1166,6 +1172,16 @@ module ClassNode {
result.getFile() = f
}
/**
* Gets a reference to the function `func`, where there exists a read/write of the "prototype" property on that reference.
*/
pragma[noinline]
private DataFlow::SourceNode getAFunctionValueWithPrototype(AbstractValue func) {
exists(result.getAPropertyReference("prototype")) and
result.analyze().getAValue() = pragma[only_bind_into](func) and
func instanceof AbstractFunction // the join-order goes bad if `func` has type `AbstractFunction`.
}
/**
* A function definition with prototype manipulation as a `ClassNode` instance.
*/
@@ -1176,10 +1192,7 @@ module ClassNode {
FunctionStyleClass() {
function.getFunction() = astNode and
(
exists(DataFlow::PropRef read |
read.getPropertyName() = "prototype" and
read.getBase().analyze().getAValue() = function
)
exists(getAFunctionValueWithPrototype(function))
or
exists(string name |
this = AccessPath::getAnAssignmentTo(name) and
@@ -1240,7 +1253,7 @@ module ClassNode {
* Gets a reference to the prototype of this class.
*/
DataFlow::SourceNode getAPrototypeReference() {
exists(DataFlow::SourceNode base | base.analyze().getAValue() = function |
exists(DataFlow::SourceNode base | base = getAFunctionValueWithPrototype(function) |
result = base.getAPropertyRead("prototype")
or
result = base.getAPropertySource("prototype")

View File

@@ -854,4 +854,24 @@ module ClientRequest {
override DataFlow::Node getADataNode() { none() }
}
}
/**
* A model of a URL request made using [form-data](https://www.npmjs.com/package/form-data).
*/
class FormDataRequest extends ClientRequest::Range, API::InvokeNode {
API::Node form;
FormDataRequest() {
form = API::moduleImport("form-data").getInstance() and
this = form.getMember("submit").getACall()
}
override DataFlow::Node getUrl() { result = getArgument(0) }
override DataFlow::Node getHost() { result = getParameter(0).getMember("host").getARhs() }
override DataFlow::Node getADataNode() {
result = form.getMember("append").getACall().getParameter(1).getARhs()
}
}
}

View File

@@ -3,175 +3,7 @@
*/
import javascript
/**
* Names of cryptographic algorithms, separated into strong and weak variants.
*
* The names are normalized: upper-case, no spaces, dashes or underscores.
*
* The names are inspired by the names used in real world crypto libraries.
*
* The classification into strong and weak are based on Wikipedia, OWASP and google (2017).
*/
private module AlgorithmNames {
predicate isStrongHashingAlgorithm(string name) {
name = "DSA" or
name = "ED25519" or
name = "ES256" or
name = "ECDSA256" or
name = "ES384" or
name = "ECDSA384" or
name = "ES512" or
name = "ECDSA512" or
name = "SHA2" or
name = "SHA224" or
name = "SHA256" or
name = "SHA384" or
name = "SHA512" or
name = "SHA3"
}
predicate isWeakHashingAlgorithm(string name) {
name = "HAVEL128" or
name = "MD2" or
name = "MD4" or
name = "MD5" or
name = "PANAMA" or
name = "RIPEMD" or
name = "RIPEMD128" or
name = "RIPEMD256" or
name = "RIPEMD160" or
name = "RIPEMD320" or
name = "SHA0" or
name = "SHA1"
}
predicate isStrongEncryptionAlgorithm(string name) {
name = "AES" or
name = "AES128" or
name = "AES192" or
name = "AES256" or
name = "AES512" or
name = "RSA" or
name = "RABBIT" or
name = "BLOWFISH"
}
predicate isWeakEncryptionAlgorithm(string name) {
name = "DES" or
name = "3DES" or
name = "TRIPLEDES" or
name = "TDEA" or
name = "TRIPLEDEA" or
name = "ARC2" or
name = "RC2" or
name = "ARC4" or
name = "RC4" or
name = "ARCFOUR" or
name = "ARC5" or
name = "RC5"
}
predicate isStrongPasswordHashingAlgorithm(string name) {
name = "ARGON2" or
name = "PBKDF2" or
name = "BCRYPT" or
name = "SCRYPT"
}
predicate isWeakPasswordHashingAlgorithm(string name) { none() }
}
private import AlgorithmNames
/**
* A cryptographic algorithm.
*/
private newtype TCryptographicAlgorithm =
MkHashingAlgorithm(string name, boolean isWeak) {
isStrongHashingAlgorithm(name) and isWeak = false
or
isWeakHashingAlgorithm(name) and isWeak = true
} or
MkEncryptionAlgorithm(string name, boolean isWeak) {
isStrongEncryptionAlgorithm(name) and isWeak = false
or
isWeakEncryptionAlgorithm(name) and isWeak = true
} or
MkPasswordHashingAlgorithm(string name, boolean isWeak) {
isStrongPasswordHashingAlgorithm(name) and isWeak = false
or
isWeakPasswordHashingAlgorithm(name) and isWeak = true
}
/**
* A cryptographic algorithm.
*/
abstract class CryptographicAlgorithm extends TCryptographicAlgorithm {
/** Gets a textual representation of this element. */
string toString() { result = getName() }
/**
* Gets the name of this algorithm.
*/
abstract string getName();
/**
* Holds if the name of this algorithm matches `name` modulo case,
* white space, dashes and underscores.
*/
bindingset[name]
predicate matchesName(string name) {
name.toUpperCase().regexpReplaceAll("[-_ ]", "") = getName()
}
/**
* Holds if this algorithm is weak.
*/
abstract predicate isWeak();
}
/**
* A hashing algorithm such as `MD5` or `SHA512`.
*/
class HashingAlgorithm extends MkHashingAlgorithm, CryptographicAlgorithm {
string name;
boolean isWeak;
HashingAlgorithm() { this = MkHashingAlgorithm(name, isWeak) }
override string getName() { result = name }
override predicate isWeak() { isWeak = true }
}
/**
* An encryption algorithm such as `DES` or `AES512`.
*/
class EncryptionAlgorithm extends MkEncryptionAlgorithm, CryptographicAlgorithm {
string name;
boolean isWeak;
EncryptionAlgorithm() { this = MkEncryptionAlgorithm(name, isWeak) }
override string getName() { result = name }
override predicate isWeak() { isWeak = true }
}
/**
* A password hashing algorithm such as `PBKDF2` or `SCRYPT`.
*/
class PasswordHashingAlgorithm extends MkPasswordHashingAlgorithm, CryptographicAlgorithm {
string name;
boolean isWeak;
PasswordHashingAlgorithm() { this = MkPasswordHashingAlgorithm(name, isWeak) }
override string getName() { result = name }
override predicate isWeak() { isWeak = true }
}
import semmle.javascript.security.CryptoAlgorithms
/**
* An application of a cryptographic algorithm.

View File

@@ -196,11 +196,14 @@ module Hapi {
private DataFlow::SourceNode getARouteHandler(DataFlow::TypeBackTracker t) {
t.start() and
result = handler.flow().getALocalSource()
result = getRouteHandler().getALocalSource()
or
exists(DataFlow::TypeBackTracker t2 | result = getARouteHandler(t2).backtrack(t2, t))
}
pragma[noinline]
private DataFlow::Node getRouteHandler() { result = handler.flow() }
Expr getRouteHandlerExpr() { result = handler }
override Expr getServer() { result = server }

View File

@@ -0,0 +1,97 @@
/**
* Provides classes and predicates for working with the [http-proxy](https://www.npmjs.com/package/http-proxy) library.
*/
import javascript
/**
* Provides classes and predicates modelling the [http-proxy](https://www.npmjs.com/package/http-proxy) library.
*/
private module HttpProxy {
/**
* A call that creates a http proxy.
*/
class CreateServerCall extends API::CallNode, ClientRequest::Range {
CreateServerCall() {
this =
API::moduleImport("http-proxy")
.getMember(["createServer", "createProxyServer", "createProxy"])
.getACall()
}
override DataFlow::Node getUrl() { result = getParameter(0).getMember("target").getARhs() }
override DataFlow::Node getHost() {
result = getParameter(0).getMember("target").getMember("host").getARhs()
}
override DataFlow::Node getADataNode() { none() }
}
/**
* A call that proxies a request to some target.
*/
class ProxyCall extends API::CallNode, ClientRequest::Range {
string method;
ProxyCall() {
method = ["ws", "web"] and
this = any(CreateServerCall server).getReturn().getMember(method).getACall()
}
private API::Node getOptionsObject() {
exists(int optionsIndex |
method = "web" and optionsIndex = 2
or
method = "ws" and optionsIndex = 3
|
result = getParameter(optionsIndex)
)
}
override DataFlow::Node getUrl() { result = getOptionsObject().getMember("target").getARhs() }
override DataFlow::Node getHost() {
result = getOptionsObject().getMember("target").getMember("host").getARhs()
}
override DataFlow::Node getADataNode() { none() }
}
/**
* Holds if an event handler for `event` has a HTTP request parameter at `req` and a HTTP response parameter at `res`.
*/
predicate routeHandlingEventHandler(string event, int req, int res) {
event = ["start", "end"] and req = 0 and res = 1
or
event = ["proxyReq", "proxyRes", "econnreset"] and req = 1 and res = 2
or
event = "proxyReqWs" and req = 1 and res = -10 // -10 for non-existent.
}
/**
* An http proxy event handler.
*/
class ProxyListenerCallback extends NodeJSLib::RouteHandler, DataFlow::FunctionNode {
string event;
API::CallNode call;
ProxyListenerCallback() {
call = any(CreateServerCall server).getReturn().getMember(["on", "once"]).getACall() and
call.getParameter(0).getARhs().mayHaveStringValue(event) and
this = call.getParameter(1).getARhs().getAFunctionValue()
}
override Parameter getRequestParameter() {
exists(int req | routeHandlingEventHandler(event, req, _) |
result = getFunction().getParameter(req)
)
}
override Parameter getResponseParameter() {
exists(int res | routeHandlingEventHandler(event, _, res) |
result = getFunction().getParameter(res)
)
}
}
}

View File

@@ -33,7 +33,7 @@ class BDDTest extends Test, @call_expr {
exists(CallExpr call | call = this |
call.getCallee().(VarAccess).getName() = "it" and
exists(call.getArgument(0).getStringValue()) and
call.getArgument(1).analyze().getAValue() instanceof AbstractFunction
exists(call.getArgument(1).flow().getAFunctionValue(0))
)
}
}
@@ -60,7 +60,7 @@ class JestTest extends Test, @call_expr {
exists(CallExpr call | call = this |
call.getCallee().(GlobalVarAccess).getName() = "test" and
exists(call.getArgument(0).getStringValue()) and
call.getArgument(1).analyze().getAValue() instanceof AbstractFunction
exists(call.getArgument(1).flow().getAFunctionValue(0))
) and
getFile() = getTestFile(any(File f), "test")
}
@@ -94,7 +94,7 @@ class CucumberTest extends Test, @call_expr {
exists(DataFlow::ModuleImportNode m, CallExpr call |
m.getPath() = "cucumber" and
call = m.getAnInvocation().asExpr() and
call.getArgument(0).analyze().getAValue() instanceof AbstractFunction and
exists(call.getArgument(0).flow().getAFunctionValue()) and
this = call
)
}

View File

@@ -544,17 +544,17 @@ module JQuery {
}
/** A source of jQuery objects from the AST-based `JQueryObject` class. */
private DataFlow::Node legacyObjectSource() { result = any(JQueryObjectInternal e).flow() }
private DataFlow::SourceNode legacyObjectSource() {
result = any(JQueryObjectInternal e).flow().getALocalSource()
}
/** Gets a source of jQuery objects. */
private DataFlow::SourceNode objectSource(DataFlow::TypeTracker t) {
t.start() and
result instanceof ObjectSource::Range
or
exists(DataFlow::TypeTracker init |
init.start() and
t = init.smallstep(legacyObjectSource(), result)
)
t.start() and
result = legacyObjectSource()
}
/** Gets a data flow node referring to a jQuery object. */
@@ -590,10 +590,6 @@ module JQuery {
read.getBase().getALocalSource() = [dollar(), objectRef()] and
read.mayHavePropertyName(name)
)
or
// Handle contributed JQuery objects that aren't source nodes (usually parameter uses)
getReceiver() = legacyObjectSource() and
this.(DataFlow::MethodCallNode).getMethodName() = name
}
/**

View File

@@ -0,0 +1,174 @@
/**
* Provides classes modeling cryptographic algorithms, separated into strong and weak variants.
*
* The classification into strong and weak are based on Wikipedia, OWASP and google (2017).
*/
/**
* Names of cryptographic algorithms, separated into strong and weak variants.
*
* The names are normalized: upper-case, no spaces, dashes or underscores.
*
* The names are inspired by the names used in real world crypto libraries.
*
* The classification into strong and weak are based on Wikipedia, OWASP and google (2017).
*/
private module AlgorithmNames {
predicate isStrongHashingAlgorithm(string name) {
name = "DSA" or
name = "ED25519" or
name = "ES256" or
name = "ECDSA256" or
name = "ES384" or
name = "ECDSA384" or
name = "ES512" or
name = "ECDSA512" or
name = "SHA2" or
name = "SHA224" or
name = "SHA256" or
name = "SHA384" or
name = "SHA512" or
name = "SHA3"
}
predicate isWeakHashingAlgorithm(string name) {
name = "HAVEL128" or
name = "MD2" or
name = "MD4" or
name = "MD5" or
name = "PANAMA" or
name = "RIPEMD" or
name = "RIPEMD128" or
name = "RIPEMD256" or
name = "RIPEMD160" or
name = "RIPEMD320" or
name = "SHA0" or
name = "SHA1"
}
predicate isStrongEncryptionAlgorithm(string name) {
name = "AES" or
name = "AES128" or
name = "AES192" or
name = "AES256" or
name = "AES512" or
name = "RSA" or
name = "RABBIT" or
name = "BLOWFISH"
}
predicate isWeakEncryptionAlgorithm(string name) {
name = "DES" or
name = "3DES" or
name = "TRIPLEDES" or
name = "TDEA" or
name = "TRIPLEDEA" or
name = "ARC2" or
name = "RC2" or
name = "ARC4" or
name = "RC4" or
name = "ARCFOUR" or
name = "ARC5" or
name = "RC5"
}
predicate isStrongPasswordHashingAlgorithm(string name) {
name = "ARGON2" or
name = "PBKDF2" or
name = "BCRYPT" or
name = "SCRYPT"
}
predicate isWeakPasswordHashingAlgorithm(string name) { none() }
}
private import AlgorithmNames
/**
* A cryptographic algorithm.
*/
private newtype TCryptographicAlgorithm =
MkHashingAlgorithm(string name, boolean isWeak) {
isStrongHashingAlgorithm(name) and isWeak = false
or
isWeakHashingAlgorithm(name) and isWeak = true
} or
MkEncryptionAlgorithm(string name, boolean isWeak) {
isStrongEncryptionAlgorithm(name) and isWeak = false
or
isWeakEncryptionAlgorithm(name) and isWeak = true
} or
MkPasswordHashingAlgorithm(string name, boolean isWeak) {
isStrongPasswordHashingAlgorithm(name) and isWeak = false
or
isWeakPasswordHashingAlgorithm(name) and isWeak = true
}
/**
* A cryptographic algorithm.
*/
abstract class CryptographicAlgorithm extends TCryptographicAlgorithm {
/** Gets a textual representation of this element. */
string toString() { result = getName() }
/**
* Gets the normalized name of this algorithm (upper-case, no spaces, dashes or underscores).
*/
abstract string getName();
/**
* Holds if the name of this algorithm matches `name` modulo case,
* white space, dashes, and underscores.
*/
bindingset[name]
predicate matchesName(string name) {
name.toUpperCase().regexpReplaceAll("[-_ ]", "") = getName()
}
/**
* Holds if this algorithm is weak.
*/
abstract predicate isWeak();
}
/**
* A hashing algorithm such as `MD5` or `SHA512`.
*/
class HashingAlgorithm extends MkHashingAlgorithm, CryptographicAlgorithm {
string name;
boolean isWeak;
HashingAlgorithm() { this = MkHashingAlgorithm(name, isWeak) }
override string getName() { result = name }
override predicate isWeak() { isWeak = true }
}
/**
* An encryption algorithm such as `DES` or `AES512`.
*/
class EncryptionAlgorithm extends MkEncryptionAlgorithm, CryptographicAlgorithm {
string name;
boolean isWeak;
EncryptionAlgorithm() { this = MkEncryptionAlgorithm(name, isWeak) }
override string getName() { result = name }
override predicate isWeak() { isWeak = true }
}
/**
* A password hashing algorithm such as `PBKDF2` or `SCRYPT`.
*/
class PasswordHashingAlgorithm extends MkPasswordHashingAlgorithm, CryptographicAlgorithm {
string name;
boolean isWeak;
PasswordHashingAlgorithm() { this = MkPasswordHashingAlgorithm(name, isWeak) }
override string getName() { result = name }
override predicate isWeak() { isWeak = true }
}

View File

@@ -16,22 +16,16 @@
import javascript
private import semmle.javascript.dataflow.InferredTypes
/** Provides classes and predicates for reasoning about deeply tainted objects. */
module TaintedObject {
private import DataFlow
import TaintedObjectCustomizations::TaintedObject
private class TaintedObjectLabel extends FlowLabel {
TaintedObjectLabel() { this = "tainted-object" }
// Materialize flow labels
private class ConcreteTaintedObjectLabel extends TaintedObjectLabel {
ConcreteTaintedObjectLabel() { this = this }
}
/**
* Gets the flow label representing a deeply tainted object.
*
* A "tainted object" is an array or object whose property values are all assumed to be tainted as well.
*
* Note that the presence of the this label generally implies the presence of the `taint` label as well.
*/
FlowLabel label() { result instanceof TaintedObjectLabel }
/**
* Holds for the flows steps that are relevant for tracking user-controlled JSON objects.
*/
@@ -79,11 +73,6 @@ module TaintedObject {
*/
predicate isSource(Node source, FlowLabel label) { source instanceof Source and label = label() }
/**
* A source of a user-controlled deep object.
*/
abstract class Source extends DataFlow::Node { }
/** Request input accesses as a JSON source. */
private class RequestInputAsSource extends Source {
RequestInputAsSource() { this.(HTTP::RequestInputAccess).isUserControlledObject() }
@@ -120,4 +109,19 @@ module TaintedObject {
label = label()
}
}
/**
* A sanitizer guard that validates an input against a JSON schema.
*/
private class JsonSchemaValidationGuard extends SanitizerGuard {
JsonSchema::ValidationCall call;
JsonSchemaValidationGuard() { this = call }
override predicate sanitizes(boolean outcome, Expr e, FlowLabel label) {
outcome = call.getPolarity() and
e = call.getInput().asExpr() and
label = label()
}
}
}

View File

@@ -0,0 +1,28 @@
/**
* Provides access to the "tainted object" flow label defined in `TaintedObject.qll`, without
* materializing that flow label.
*/
import javascript
/** Provides classes and predicates for reasoning about deeply tainted objects. */
module TaintedObject {
/** A flow label representing a deeply tainted object. */
abstract class TaintedObjectLabel extends DataFlow::FlowLabel {
TaintedObjectLabel() { this = "tainted-object" }
}
/**
* Gets the flow label representing a deeply tainted object.
*
* A "tainted object" is an array or object whose property values are all assumed to be tainted as well.
*
* Note that the presence of the this label generally implies the presence of the `taint` label as well.
*/
DataFlow::FlowLabel label() { result instanceof TaintedObjectLabel }
/**
* A source of a user-controlled deep object.
*/
abstract class Source extends DataFlow::Node { }
}

View File

@@ -229,6 +229,7 @@ private class PostMessageEventParameter extends RemoteFlowSource {
* even if the window is opened from a foreign domain.
*/
private class WindowNameAccess extends RemoteFlowSource {
pragma[nomagic, noinline]
WindowNameAccess() {
this = DataFlow::globalObjectRef().getAPropertyRead("name")
or

View File

@@ -0,0 +1,41 @@
/**
* Provides a taint tracking configuration for reasoning about DoS attacks
* due to inefficient handling of user-controlled objects.
*/
import javascript
import semmle.javascript.security.TaintedObject
/**
* Provides a taint tracking configuration for reasoning about DoS attacks
* due to inefficient handling of user-controlled objects.
*/
module DeepObjectResourceExhaustion {
import DeepObjectResourceExhaustionCustomizations::DeepObjectResourceExhaustion
/**
* A taint tracking configuration for reasoning about DoS attacks due to inefficient handling
* of user-controlled objects.
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "DeepObjectResourceExhaustion" }
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
source.(Source).getAFlowLabel() = label
}
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
sink instanceof Sink and label = TaintedObject::label()
}
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
guard instanceof TaintedObject::SanitizerGuard
}
override predicate isAdditionalFlowStep(
DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
) {
TaintedObject::step(src, trg, inlbl, outlbl)
}
}
}

View File

@@ -0,0 +1,94 @@
/**
* Provides sources, sinks and sanitizers for reasoning about
* DoS attacks due to inefficient handling of user-controlled objects.
*/
import javascript
private import semmle.javascript.security.TaintedObjectCustomizations
/**
* Provides sources, sinks and sanitizers for reasoning about
* DoS attacks due to inefficient handling of user-controlled objects.
*/
module DeepObjectResourceExhaustion {
/**
* A data flow source for inefficient handling of user-controlled objects.
*/
abstract class Source extends DataFlow::Node {
/** Gets a flow label to associate with this source. */
DataFlow::FlowLabel getAFlowLabel() { result = TaintedObject::label() }
}
private class TaintedObjectSourceAsSource extends Source {
TaintedObjectSourceAsSource() { this instanceof TaintedObject::Source }
override DataFlow::FlowLabel getAFlowLabel() { result = TaintedObject::label() }
}
private class RemoteFlowSourceAsSource extends Source {
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
override DataFlow::FlowLabel getAFlowLabel() { result.isTaint() }
}
/**
* A data flow sink for inefficient handling of user-controlled objects.
*/
abstract class Sink extends DataFlow::Node {
/**
* Holds if `link` and `text` should be included in the message to explain
* why the handling of the object is slow.
*/
abstract predicate hasReason(DataFlow::Node link, string text);
}
/**
* A sanitizer for inefficient handling of user-controlled objects.
*/
abstract class Sanitizer extends DataFlow::Node { }
/** Gets a node that may refer to an object with `allErrors` set to `true`. */
private DataFlow::SourceNode allErrorsObject(
DataFlow::TypeTracker t, DataFlow::PropWrite allErrors
) {
t.start() and
exists(JsonSchema::Ajv::AjvValidationCall call) and // only compute if `ajv` is used
allErrors.getPropertyName() = "allErrors" and
allErrors.getRhs().mayHaveBooleanValue(true) and
result = allErrors.getBase().getALocalSource()
or
exists(ExtendCall call |
allErrorsObject(t.continue(), allErrors).flowsTo(call.getAnOperand()) and
(result = call or result = call.getDestinationOperand().getALocalSource())
)
or
exists(DataFlow::ObjectLiteralNode obj |
allErrorsObject(t.continue(), allErrors).flowsTo(obj.getASpreadProperty()) and
result = obj
)
or
exists(DataFlow::TypeTracker t2 | result = allErrorsObject(t2, allErrors).track(t2, t))
}
/** Gets a node that may refer to an object with `allErrors` set to `true`. */
private DataFlow::SourceNode allErrorsObject(DataFlow::PropWrite allErrors) {
result = allErrorsObject(DataFlow::TypeTracker::end(), allErrors)
}
/** Argument to an `ajv` validation call configured with `allErrors: true`. */
private class AjvValidationSink extends Sink {
DataFlow::PropWrite allErrors;
AjvValidationSink() {
exists(JsonSchema::Ajv::AjvValidationCall call |
this = call.getInput() and
allErrorsObject(allErrors).flowsTo(call.getAnOptionsArg())
)
}
override predicate hasReason(DataFlow::Node link, string text) {
link = allErrors and
text = "allErrors: true"
}
}
}

View File

@@ -10,6 +10,7 @@ module ExceptionXss {
import DomBasedXssCustomizations::DomBasedXss as DomBasedXssCustom
import ReflectedXssCustomizations::ReflectedXss as ReflectedXssCustom
import Xss as Xss
import Xss::ExceptionXss
private import semmle.javascript.dataflow.InferredTypes
/**
@@ -71,14 +72,9 @@ module ExceptionXss {
)
}
/**
* A FlowLabel representing tainted data that has not been thrown in an exception.
* In the js/xss-through-exception query data-flow can only reach a sink after
* the data has been thrown as an exception, and data that has not been thrown
* as an exception therefore has this flow label, and only this flow label, associated with it.
*/
class NotYetThrown extends DataFlow::FlowLabel {
NotYetThrown() { this = "NotYetThrown" }
// Materialize flow labels
private class ConcreteNotYetThrown extends Xss::ExceptionXss::NotYetThrown {
ConcreteNotYetThrown() { this = this }
}
/**
@@ -139,7 +135,7 @@ module ExceptionXss {
Configuration() { this = "ExceptionXss" }
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
source instanceof Xss::Shared::Source and label instanceof NotYetThrown
source.(Xss::ExceptionXss::Source).getAFlowLabel() = label
}
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {

View File

@@ -14,7 +14,7 @@ module PrototypePollution {
* Label for wrappers around tainted objects, that is, objects that are
* not completely user-controlled, but contain a user-controlled object.
*
* For example, `options` below is is a tainted wrapper, but is not itself
* For example, `options` below is a tainted wrapper, but is not itself
* a tainted object:
* ```
* let options = {

View File

@@ -7,13 +7,16 @@ import semmle.javascript.frameworks.HTTP
import semmle.javascript.security.dataflow.DOM
/** A data flow source of remote user input. */
cached
abstract class RemoteFlowSource extends DataFlow::Node {
/** Gets a string that describes the type of this remote flow source. */
cached
abstract string getSourceType();
/**
* Holds if this can be a user-controlled object, such as a JSON object parsed from user-controlled data.
*/
cached
predicate isUserControlledObject() { none() }
}

View File

@@ -602,3 +602,59 @@ module XssThroughDom {
/** A data flow source for XSS through DOM vulnerabilities. */
abstract class Source extends Shared::Source { }
}
/** Provides classes for customizing the `ExceptionXss` query. */
module ExceptionXss {
/** A data flow source for XSS caused by interpreting exception or error text as HTML. */
abstract class Source extends DataFlow::Node {
/**
* Gets a flow label to associate with this source.
*
* For sources that should pass through a `throw/catch` before reaching the sink, use the
* `NotYetThrown` labe. Otherwise use `taint` (the default).
*/
DataFlow::FlowLabel getAFlowLabel() { result.isTaint() }
/**
* Gets a human-readable description of what type of error this refers to.
*
* The result should be capitalized and usable in the context of a noun.
*/
string getDescription() { result = "Error text" }
}
/**
* A FlowLabel representing tainted data that has not been thrown in an exception.
* In the js/xss-through-exception query data-flow can only reach a sink after
* the data has been thrown as an exception, and data that has not been thrown
* as an exception therefore has this flow label, and only this flow label, associated with it.
*/
abstract class NotYetThrown extends DataFlow::FlowLabel {
NotYetThrown() { this = "NotYetThrown" }
}
private class XssSourceAsSource extends Source {
XssSourceAsSource() { this instanceof Shared::Source }
override DataFlow::FlowLabel getAFlowLabel() { result instanceof NotYetThrown }
override string getDescription() { result = "Exception text" }
}
/**
* An error produced by validating using `ajv`.
*
* Such an error can contain property names from the input if the
* underlying schema uses `additionalProperties` or `propertyPatterns`.
*
* For example, an input of form `{"<img src=x onerror=alert(1)>": 45}` might produce the error
* `data/<img src=x onerror=alert(1)> should be string`.
*/
private class JsonSchemaValidationError extends Source {
JsonSchemaValidationError() {
this = any(JsonSchema::Ajv::Instance i).getAValidationError().getAnImmediateUse()
}
override string getDescription() { result = "JSON schema validation error" }
}
}

View File

@@ -742,6 +742,10 @@ signature_types (
int required_params: int ref
);
is_abstract_signature(
unique int sig: @signature_type ref
);
signature_rest_parameter(
unique int sig: @signature_type ref,
int rest_param_arra_type: @type ref
@@ -799,8 +803,9 @@ tuple_type_min_length(
int minLength: int ref
);
tuple_type_rest(
unique int typ: @type ref
tuple_type_rest_index(
unique int typ: @type ref,
int index: int ref
);
// comments

View File

@@ -14480,6 +14480,17 @@
</dependencies>
</relation>
<relation>
<name>is_abstract_signature</name>
<cardinality>12</cardinality>
<columnsizes>
<e>
<k>sig</k>
<v>12</v>
</e>
</columnsizes>
<dependencies/>
</relation>
<relation>
<name>signature_rest_parameter</name>
<cardinality>19521</cardinality>
<columnsizes>
@@ -15891,15 +15902,57 @@
</dependencies>
</relation>
<relation>
<name>tuple_type_rest</name>
<cardinality>100</cardinality>
<name>tuple_type_rest_index</name>
<cardinality>6</cardinality>
<columnsizes>
<e>
<k>typ</k>
<v>100</v>
<v>6</v>
</e>
<e>
<k>index</k>
<v>2</v>
</e>
</columnsizes>
<dependencies/>
<dependencies>
<dep>
<src>typ</src>
<trg>index</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>6</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>index</src>
<trg>typ</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>1</v>
</b>
<b>
<a>5</a>
<b>6</b>
<v>1</v>
</b>
</bs>
</hist>
</val>
</dep>
</dependencies>
</relation>
<relation>
<name>comments</name>

View File

@@ -3,7 +3,8 @@ exprType
| tst.ts:2:5:2:21 | stringOrUndefined | string \| undefined |
| tst.ts:3:5:3:27 | stringO ... defined | string \| null \| undefined |
| tst.ts:4:5:4:16 | stringOrVoid | string \| void |
| tst.ts:7:5:7:21 | stringOrNullAlias | string \| null |
| tst.ts:7:5:7:21 | stringOrNullAlias | StringOrNullAlias |
| tst.ts:8:5:8:32 | stringO ... defined | string \| null \| undefined |
| tst.ts:10:5:10:23 | arrayOfStringOrNull | (string \| null)[] |
unaliasedType
| StringOrNullAlias | string \| null |

View File

@@ -3,16 +3,16 @@ rightHandSide
| tst.ts:2:1:2:16 | type B<T> = T[]; | T[] |
| tst.ts:8:10:8:20 | type C = A; | number |
| tst.ts:15:1:15:23 | type Un ... \| Two; | One \| Two |
| tst.ts:17:1:17:36 | type Un ... mber }; | (One & { x: number; }) \| (Two & { x: number; }) |
| tst.ts:18:1:18:21 | type Un ... Union2; | (One & { x: number; }) \| (Two & { x: number; }) |
| tst.ts:19:1:19:21 | type Un ... Union3; | (One & { x: number; }) \| (Two & { x: number; }) |
| tst.ts:20:1:20:30 | type Un ... number; | number \| (One & { x: number; }) \| (Two & { x: n... |
| tst.ts:17:1:17:36 | type Un ... mber }; | Union & { x: number; } |
| tst.ts:18:1:18:21 | type Un ... Union2; | Union & { x: number; } |
| tst.ts:19:1:19:21 | type Un ... Union3; | Union & { x: number; } |
| tst.ts:20:1:20:30 | type Un ... number; | number \| Union2 |
getAliasedType
| B<T> | T[] |
| B<number> | number[] |
| Union | One \| Two |
| Union2 | (One & { x: number; }) \| (Two & { x: number; }) |
| Union5 | number \| (One & { x: number; }) \| (Two & { x: n... |
| Union2 | Union & { x: number; } |
| Union5 | number \| Union2 |
getTypeArgument
| B<T> | 0 | T |
| B<number> | 0 | number |

View File

@@ -0,0 +1,3 @@
let foo: [boolean, ...string[], number];
foo = [true, "hello", 123];

View File

@@ -84,50 +84,68 @@ nodes
| file://:0:0:0:0 | (TypeParameters) | semmle.label | (TypeParameters) |
| file://:0:0:0:0 | (TypeParameters) | semmle.label | (TypeParameters) |
| file://:0:0:0:0 | (TypeParameters) | semmle.label | (TypeParameters) |
| middle-rest.ts:1:1:1:40 | [DeclStmt] let foo = ... | semmle.label | [DeclStmt] let foo = ... |
| middle-rest.ts:1:1:1:40 | [DeclStmt] let foo = ... | semmle.order | 13 |
| middle-rest.ts:1:5:1:7 | [VarDecl] foo | semmle.label | [VarDecl] foo |
| middle-rest.ts:1:5:1:39 | [VariableDeclarator] foo: [b ... number] | semmle.label | [VariableDeclarator] foo: [b ... number] |
| middle-rest.ts:1:10:1:39 | [TupleTypeExpr] [boolea ... number] | semmle.label | [TupleTypeExpr] [boolea ... number] |
| middle-rest.ts:1:11:1:17 | [KeywordTypeExpr] boolean | semmle.label | [KeywordTypeExpr] boolean |
| middle-rest.ts:1:20:1:30 | [RestTypeExpr] ...string[] | semmle.label | [RestTypeExpr] ...string[] |
| middle-rest.ts:1:23:1:28 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
| middle-rest.ts:1:23:1:30 | [ArrayTypeExpr] string[] | semmle.label | [ArrayTypeExpr] string[] |
| middle-rest.ts:1:33:1:38 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| middle-rest.ts:3:1:3:3 | [VarRef] foo | semmle.label | [VarRef] foo |
| middle-rest.ts:3:1:3:26 | [AssignExpr] foo = [ ... ", 123] | semmle.label | [AssignExpr] foo = [ ... ", 123] |
| middle-rest.ts:3:1:3:27 | [ExprStmt] foo = [ ... , 123]; | semmle.label | [ExprStmt] foo = [ ... , 123]; |
| middle-rest.ts:3:1:3:27 | [ExprStmt] foo = [ ... , 123]; | semmle.order | 14 |
| middle-rest.ts:3:7:3:26 | [ArrayExpr] [true, "hello", 123] | semmle.label | [ArrayExpr] [true, "hello", 123] |
| middle-rest.ts:3:8:3:11 | [Literal] true | semmle.label | [Literal] true |
| middle-rest.ts:3:14:3:20 | [Literal] "hello" | semmle.label | [Literal] "hello" |
| middle-rest.ts:3:23:3:25 | [Literal] 123 | semmle.label | [Literal] 123 |
| tst.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; |
| tst.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 13 |
| tst.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 15 |
| tst.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy |
| tst.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy |
| tst.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" |
| tst.ts:3:1:3:19 | [DeclStmt] var numVar = ... | semmle.label | [DeclStmt] var numVar = ... |
| tst.ts:3:1:3:19 | [DeclStmt] var numVar = ... | semmle.order | 14 |
| tst.ts:3:1:3:19 | [DeclStmt] var numVar = ... | semmle.order | 16 |
| tst.ts:3:5:3:10 | [VarDecl] numVar | semmle.label | [VarDecl] numVar |
| tst.ts:3:5:3:18 | [VariableDeclarator] numVar: number | semmle.label | [VariableDeclarator] numVar: number |
| tst.ts:3:13:3:18 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| tst.ts:5:1:5:18 | [DeclStmt] var num1 = ... | semmle.label | [DeclStmt] var num1 = ... |
| tst.ts:5:1:5:18 | [DeclStmt] var num1 = ... | semmle.order | 15 |
| tst.ts:5:1:5:18 | [DeclStmt] var num1 = ... | semmle.order | 17 |
| tst.ts:5:5:5:8 | [VarDecl] num1 | semmle.label | [VarDecl] num1 |
| tst.ts:5:5:5:17 | [VariableDeclarator] num1 = numVar | semmle.label | [VariableDeclarator] num1 = numVar |
| tst.ts:5:12:5:17 | [VarRef] numVar | semmle.label | [VarRef] numVar |
| tst.ts:6:1:6:13 | [DeclStmt] var num2 = ... | semmle.label | [DeclStmt] var num2 = ... |
| tst.ts:6:1:6:13 | [DeclStmt] var num2 = ... | semmle.order | 16 |
| tst.ts:6:1:6:13 | [DeclStmt] var num2 = ... | semmle.order | 18 |
| tst.ts:6:5:6:8 | [VarDecl] num2 | semmle.label | [VarDecl] num2 |
| tst.ts:6:5:6:12 | [VariableDeclarator] num2 = 5 | semmle.label | [VariableDeclarator] num2 = 5 |
| tst.ts:6:12:6:12 | [Literal] 5 | semmle.label | [Literal] 5 |
| tst.ts:7:1:7:23 | [DeclStmt] var num3 = ... | semmle.label | [DeclStmt] var num3 = ... |
| tst.ts:7:1:7:23 | [DeclStmt] var num3 = ... | semmle.order | 17 |
| tst.ts:7:1:7:23 | [DeclStmt] var num3 = ... | semmle.order | 19 |
| tst.ts:7:5:7:8 | [VarDecl] num3 | semmle.label | [VarDecl] num3 |
| tst.ts:7:5:7:22 | [VariableDeclarator] num3 = num1 + num2 | semmle.label | [VariableDeclarator] num3 = num1 + num2 |
| tst.ts:7:12:7:15 | [VarRef] num1 | semmle.label | [VarRef] num1 |
| tst.ts:7:12:7:22 | [BinaryExpr] num1 + num2 | semmle.label | [BinaryExpr] num1 + num2 |
| tst.ts:7:19:7:22 | [VarRef] num2 | semmle.label | [VarRef] num2 |
| tst.ts:9:1:9:19 | [DeclStmt] var strVar = ... | semmle.label | [DeclStmt] var strVar = ... |
| tst.ts:9:1:9:19 | [DeclStmt] var strVar = ... | semmle.order | 18 |
| tst.ts:9:1:9:19 | [DeclStmt] var strVar = ... | semmle.order | 20 |
| tst.ts:9:5:9:10 | [VarDecl] strVar | semmle.label | [VarDecl] strVar |
| tst.ts:9:5:9:18 | [VariableDeclarator] strVar: string | semmle.label | [VariableDeclarator] strVar: string |
| tst.ts:9:13:9:18 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
| tst.ts:10:1:10:20 | [DeclStmt] var hello = ... | semmle.label | [DeclStmt] var hello = ... |
| tst.ts:10:1:10:20 | [DeclStmt] var hello = ... | semmle.order | 19 |
| tst.ts:10:1:10:20 | [DeclStmt] var hello = ... | semmle.order | 21 |
| tst.ts:10:5:10:9 | [VarDecl] hello | semmle.label | [VarDecl] hello |
| tst.ts:10:5:10:19 | [VariableDeclarator] hello = "hello" | semmle.label | [VariableDeclarator] hello = "hello" |
| tst.ts:10:13:10:19 | [Literal] "hello" | semmle.label | [Literal] "hello" |
| tst.ts:11:1:11:20 | [DeclStmt] var world = ... | semmle.label | [DeclStmt] var world = ... |
| tst.ts:11:1:11:20 | [DeclStmt] var world = ... | semmle.order | 20 |
| tst.ts:11:1:11:20 | [DeclStmt] var world = ... | semmle.order | 22 |
| tst.ts:11:5:11:9 | [VarDecl] world | semmle.label | [VarDecl] world |
| tst.ts:11:5:11:19 | [VariableDeclarator] world = "world" | semmle.label | [VariableDeclarator] world = "world" |
| tst.ts:11:13:11:19 | [Literal] "world" | semmle.label | [Literal] "world" |
| tst.ts:12:1:12:30 | [DeclStmt] var msg = ... | semmle.label | [DeclStmt] var msg = ... |
| tst.ts:12:1:12:30 | [DeclStmt] var msg = ... | semmle.order | 21 |
| tst.ts:12:1:12:30 | [DeclStmt] var msg = ... | semmle.order | 23 |
| tst.ts:12:5:12:7 | [VarDecl] msg | semmle.label | [VarDecl] msg |
| tst.ts:12:5:12:29 | [VariableDeclarator] msg = h ... + world | semmle.label | [VariableDeclarator] msg = h ... + world |
| tst.ts:12:11:12:15 | [VarRef] hello | semmle.label | [VarRef] hello |
@@ -136,7 +154,7 @@ nodes
| tst.ts:12:19:12:21 | [Literal] " " | semmle.label | [Literal] " " |
| tst.ts:12:25:12:29 | [VarRef] world | semmle.label | [VarRef] world |
| tst.ts:14:1:14:63 | [FunctionDeclStmt] functio ... + y; } | semmle.label | [FunctionDeclStmt] functio ... + y; } |
| tst.ts:14:1:14:63 | [FunctionDeclStmt] functio ... + y; } | semmle.order | 22 |
| tst.ts:14:1:14:63 | [FunctionDeclStmt] functio ... + y; } | semmle.order | 24 |
| tst.ts:14:10:14:15 | [VarDecl] concat | semmle.label | [VarDecl] concat |
| tst.ts:14:17:14:17 | [SimpleParameter] x | semmle.label | [SimpleParameter] x |
| tst.ts:14:20:14:25 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
@@ -149,7 +167,7 @@ nodes
| tst.ts:14:56:14:60 | [BinaryExpr] x + y | semmle.label | [BinaryExpr] x + y |
| tst.ts:14:60:14:60 | [VarRef] y | semmle.label | [VarRef] y |
| tst.ts:16:1:16:60 | [FunctionDeclStmt] functio ... + y; } | semmle.label | [FunctionDeclStmt] functio ... + y; } |
| tst.ts:16:1:16:60 | [FunctionDeclStmt] functio ... + y; } | semmle.order | 23 |
| tst.ts:16:1:16:60 | [FunctionDeclStmt] functio ... + y; } | semmle.order | 25 |
| tst.ts:16:10:16:12 | [VarDecl] add | semmle.label | [VarDecl] add |
| tst.ts:16:14:16:14 | [SimpleParameter] x | semmle.label | [SimpleParameter] x |
| tst.ts:16:17:16:22 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
@@ -162,7 +180,7 @@ nodes
| tst.ts:16:53:16:57 | [BinaryExpr] x + y | semmle.label | [BinaryExpr] x + y |
| tst.ts:16:57:16:57 | [VarRef] y | semmle.label | [VarRef] y |
| tst.ts:18:1:18:40 | [FunctionDeclStmt] functio ... + y; } | semmle.label | [FunctionDeclStmt] functio ... + y; } |
| tst.ts:18:1:18:40 | [FunctionDeclStmt] functio ... + y; } | semmle.order | 24 |
| tst.ts:18:1:18:40 | [FunctionDeclStmt] functio ... + y; } | semmle.order | 26 |
| tst.ts:18:10:18:16 | [VarDecl] untyped | semmle.label | [VarDecl] untyped |
| tst.ts:18:18:18:18 | [SimpleParameter] x | semmle.label | [SimpleParameter] x |
| tst.ts:18:21:18:21 | [SimpleParameter] y | semmle.label | [SimpleParameter] y |
@@ -172,7 +190,7 @@ nodes
| tst.ts:18:33:18:37 | [BinaryExpr] x + y | semmle.label | [BinaryExpr] x + y |
| tst.ts:18:37:18:37 | [VarRef] y | semmle.label | [VarRef] y |
| tst.ts:20:1:20:53 | [FunctionDeclStmt] functio ... + y; } | semmle.label | [FunctionDeclStmt] functio ... + y; } |
| tst.ts:20:1:20:53 | [FunctionDeclStmt] functio ... + y; } | semmle.order | 25 |
| tst.ts:20:1:20:53 | [FunctionDeclStmt] functio ... + y; } | semmle.order | 27 |
| tst.ts:20:10:20:21 | [VarDecl] partialTyped | semmle.label | [VarDecl] partialTyped |
| tst.ts:20:23:20:23 | [SimpleParameter] x | semmle.label | [SimpleParameter] x |
| tst.ts:20:26:20:26 | [SimpleParameter] y | semmle.label | [SimpleParameter] y |
@@ -183,7 +201,7 @@ nodes
| tst.ts:20:46:20:50 | [BinaryExpr] x + y | semmle.label | [BinaryExpr] x + y |
| tst.ts:20:50:20:50 | [VarRef] y | semmle.label | [VarRef] y |
| tst.ts:22:1:22:34 | [ForOfStmt] for (le ... 2]) {} | semmle.label | [ForOfStmt] for (le ... 2]) {} |
| tst.ts:22:1:22:34 | [ForOfStmt] for (le ... 2]) {} | semmle.order | 26 |
| tst.ts:22:1:22:34 | [ForOfStmt] for (le ... 2]) {} | semmle.order | 28 |
| tst.ts:22:6:22:20 | [DeclStmt] let numFromLoop = ... | semmle.label | [DeclStmt] let numFromLoop = ... |
| tst.ts:22:10:22:20 | [VarDecl] numFromLoop | semmle.label | [VarDecl] numFromLoop |
| tst.ts:22:10:22:20 | [VariableDeclarator] numFromLoop | semmle.label | [VariableDeclarator] numFromLoop |
@@ -192,54 +210,54 @@ nodes
| tst.ts:22:29:22:29 | [Literal] 2 | semmle.label | [Literal] 2 |
| tst.ts:22:33:22:34 | [BlockStmt] {} | semmle.label | [BlockStmt] {} |
| tst.ts:24:1:24:20 | [DeclStmt] let array = ... | semmle.label | [DeclStmt] let array = ... |
| tst.ts:24:1:24:20 | [DeclStmt] let array = ... | semmle.order | 27 |
| tst.ts:24:1:24:20 | [DeclStmt] let array = ... | semmle.order | 29 |
| tst.ts:24:5:24:9 | [VarDecl] array | semmle.label | [VarDecl] array |
| tst.ts:24:5:24:19 | [VariableDeclarator] array: number[] | semmle.label | [VariableDeclarator] array: number[] |
| tst.ts:24:12:24:17 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| tst.ts:24:12:24:19 | [ArrayTypeExpr] number[] | semmle.label | [ArrayTypeExpr] number[] |
| tst.ts:26:1:26:25 | [DeclStmt] let voidType = ... | semmle.label | [DeclStmt] let voidType = ... |
| tst.ts:26:1:26:25 | [DeclStmt] let voidType = ... | semmle.order | 28 |
| tst.ts:26:1:26:25 | [DeclStmt] let voidType = ... | semmle.order | 30 |
| tst.ts:26:5:26:12 | [VarDecl] voidType | semmle.label | [VarDecl] voidType |
| tst.ts:26:5:26:24 | [VariableDeclarator] voidType: () => void | semmle.label | [VariableDeclarator] voidType: () => void |
| tst.ts:26:15:26:24 | [FunctionExpr] () => void | semmle.label | [FunctionExpr] () => void |
| tst.ts:26:15:26:24 | [FunctionTypeExpr] () => void | semmle.label | [FunctionTypeExpr] () => void |
| tst.ts:26:21:26:24 | [KeywordTypeExpr] void | semmle.label | [KeywordTypeExpr] void |
| tst.ts:27:1:27:29 | [DeclStmt] let undefinedType = ... | semmle.label | [DeclStmt] let undefinedType = ... |
| tst.ts:27:1:27:29 | [DeclStmt] let undefinedType = ... | semmle.order | 29 |
| tst.ts:27:1:27:29 | [DeclStmt] let undefinedType = ... | semmle.order | 31 |
| tst.ts:27:5:27:17 | [VarDecl] undefinedType | semmle.label | [VarDecl] undefinedType |
| tst.ts:27:5:27:28 | [VariableDeclarator] undefin ... defined | semmle.label | [VariableDeclarator] undefin ... defined |
| tst.ts:27:20:27:28 | [KeywordTypeExpr] undefined | semmle.label | [KeywordTypeExpr] undefined |
| tst.ts:28:1:28:26 | [DeclStmt] let nullType = ... | semmle.label | [DeclStmt] let nullType = ... |
| tst.ts:28:1:28:26 | [DeclStmt] let nullType = ... | semmle.order | 30 |
| tst.ts:28:1:28:26 | [DeclStmt] let nullType = ... | semmle.order | 32 |
| tst.ts:28:5:28:12 | [VarDecl] nullType | semmle.label | [VarDecl] nullType |
| tst.ts:28:5:28:25 | [VariableDeclarator] nullTyp ... = null | semmle.label | [VariableDeclarator] nullTyp ... = null |
| tst.ts:28:15:28:18 | [KeywordTypeExpr] null | semmle.label | [KeywordTypeExpr] null |
| tst.ts:28:22:28:25 | [Literal] null | semmle.label | [Literal] null |
| tst.ts:29:1:29:27 | [DeclStmt] let neverType = ... | semmle.label | [DeclStmt] let neverType = ... |
| tst.ts:29:1:29:27 | [DeclStmt] let neverType = ... | semmle.order | 31 |
| tst.ts:29:1:29:27 | [DeclStmt] let neverType = ... | semmle.order | 33 |
| tst.ts:29:5:29:13 | [VarDecl] neverType | semmle.label | [VarDecl] neverType |
| tst.ts:29:5:29:26 | [VariableDeclarator] neverTy ... > never | semmle.label | [VariableDeclarator] neverTy ... > never |
| tst.ts:29:16:29:26 | [FunctionExpr] () => never | semmle.label | [FunctionExpr] () => never |
| tst.ts:29:16:29:26 | [FunctionTypeExpr] () => never | semmle.label | [FunctionTypeExpr] () => never |
| tst.ts:29:22:29:26 | [KeywordTypeExpr] never | semmle.label | [KeywordTypeExpr] never |
| tst.ts:30:1:30:23 | [DeclStmt] let symbolType = ... | semmle.label | [DeclStmt] let symbolType = ... |
| tst.ts:30:1:30:23 | [DeclStmt] let symbolType = ... | semmle.order | 32 |
| tst.ts:30:1:30:23 | [DeclStmt] let symbolType = ... | semmle.order | 34 |
| tst.ts:30:5:30:14 | [VarDecl] symbolType | semmle.label | [VarDecl] symbolType |
| tst.ts:30:5:30:22 | [VariableDeclarator] symbolType: symbol | semmle.label | [VariableDeclarator] symbolType: symbol |
| tst.ts:30:17:30:22 | [KeywordTypeExpr] symbol | semmle.label | [KeywordTypeExpr] symbol |
| tst.ts:31:1:31:45 | [DeclStmt] const uniqueSymbolType = ... | semmle.label | [DeclStmt] const uniqueSymbolType = ... |
| tst.ts:31:1:31:45 | [DeclStmt] const uniqueSymbolType = ... | semmle.order | 33 |
| tst.ts:31:1:31:45 | [DeclStmt] const uniqueSymbolType = ... | semmle.order | 35 |
| tst.ts:31:7:31:22 | [VarDecl] uniqueSymbolType | semmle.label | [VarDecl] uniqueSymbolType |
| tst.ts:31:7:31:44 | [VariableDeclarator] uniqueS ... = null | semmle.label | [VariableDeclarator] uniqueS ... = null |
| tst.ts:31:25:31:37 | [KeywordTypeExpr] unique symbol | semmle.label | [KeywordTypeExpr] unique symbol |
| tst.ts:31:41:31:44 | [Literal] null | semmle.label | [Literal] null |
| tst.ts:32:1:32:23 | [DeclStmt] let objectType = ... | semmle.label | [DeclStmt] let objectType = ... |
| tst.ts:32:1:32:23 | [DeclStmt] let objectType = ... | semmle.order | 34 |
| tst.ts:32:1:32:23 | [DeclStmt] let objectType = ... | semmle.order | 36 |
| tst.ts:32:5:32:14 | [VarDecl] objectType | semmle.label | [VarDecl] objectType |
| tst.ts:32:5:32:22 | [VariableDeclarator] objectType: object | semmle.label | [VariableDeclarator] objectType: object |
| tst.ts:32:17:32:22 | [KeywordTypeExpr] object | semmle.label | [KeywordTypeExpr] object |
| tst.ts:33:1:33:39 | [DeclStmt] let intersection = ... | semmle.label | [DeclStmt] let intersection = ... |
| tst.ts:33:1:33:39 | [DeclStmt] let intersection = ... | semmle.order | 35 |
| tst.ts:33:1:33:39 | [DeclStmt] let intersection = ... | semmle.order | 37 |
| tst.ts:33:5:33:16 | [VarDecl] intersection | semmle.label | [VarDecl] intersection |
| tst.ts:33:5:33:38 | [VariableDeclarator] interse ... string} | semmle.label | [VariableDeclarator] interse ... string} |
| tst.ts:33:19:33:24 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
@@ -249,14 +267,14 @@ nodes
| tst.ts:33:29:33:37 | [FieldDeclaration] x: string | semmle.label | [FieldDeclaration] x: string |
| tst.ts:33:32:33:37 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
| tst.ts:34:1:34:28 | [DeclStmt] let tuple = ... | semmle.label | [DeclStmt] let tuple = ... |
| tst.ts:34:1:34:28 | [DeclStmt] let tuple = ... | semmle.order | 36 |
| tst.ts:34:1:34:28 | [DeclStmt] let tuple = ... | semmle.order | 38 |
| tst.ts:34:5:34:9 | [VarDecl] tuple | semmle.label | [VarDecl] tuple |
| tst.ts:34:5:34:27 | [VariableDeclarator] tuple: ... string] | semmle.label | [VariableDeclarator] tuple: ... string] |
| tst.ts:34:12:34:27 | [TupleTypeExpr] [number, string] | semmle.label | [TupleTypeExpr] [number, string] |
| tst.ts:34:13:34:18 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| tst.ts:34:21:34:26 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
| tst.ts:36:1:36:56 | [DeclStmt] let tupleWithOptionalElement = ... | semmle.label | [DeclStmt] let tupleWithOptionalElement = ... |
| tst.ts:36:1:36:56 | [DeclStmt] let tupleWithOptionalElement = ... | semmle.order | 37 |
| tst.ts:36:1:36:56 | [DeclStmt] let tupleWithOptionalElement = ... | semmle.order | 39 |
| tst.ts:36:5:36:28 | [VarDecl] tupleWithOptionalElement | semmle.label | [VarDecl] tupleWithOptionalElement |
| tst.ts:36:5:36:55 | [VariableDeclarator] tupleWi ... umber?] | semmle.label | [VariableDeclarator] tupleWi ... umber?] |
| tst.ts:36:31:36:55 | [TupleTypeExpr] [number ... umber?] | semmle.label | [TupleTypeExpr] [number ... umber?] |
@@ -265,12 +283,12 @@ nodes
| tst.ts:36:48:36:53 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| tst.ts:36:48:36:54 | [OptionalTypeExpr] number? | semmle.label | [OptionalTypeExpr] number? |
| tst.ts:37:1:37:19 | [DeclStmt] let emptyTuple = ... | semmle.label | [DeclStmt] let emptyTuple = ... |
| tst.ts:37:1:37:19 | [DeclStmt] let emptyTuple = ... | semmle.order | 38 |
| tst.ts:37:1:37:19 | [DeclStmt] let emptyTuple = ... | semmle.order | 40 |
| tst.ts:37:5:37:14 | [VarDecl] emptyTuple | semmle.label | [VarDecl] emptyTuple |
| tst.ts:37:5:37:18 | [VariableDeclarator] emptyTuple: [] | semmle.label | [VariableDeclarator] emptyTuple: [] |
| tst.ts:37:17:37:18 | [TupleTypeExpr] [] | semmle.label | [TupleTypeExpr] [] |
| tst.ts:38:1:38:48 | [DeclStmt] let tupleWithRestElement = ... | semmle.label | [DeclStmt] let tupleWithRestElement = ... |
| tst.ts:38:1:38:48 | [DeclStmt] let tupleWithRestElement = ... | semmle.order | 39 |
| tst.ts:38:1:38:48 | [DeclStmt] let tupleWithRestElement = ... | semmle.order | 41 |
| tst.ts:38:5:38:24 | [VarDecl] tupleWithRestElement | semmle.label | [VarDecl] tupleWithRestElement |
| tst.ts:38:5:38:47 | [VariableDeclarator] tupleWi ... ring[]] | semmle.label | [VariableDeclarator] tupleWi ... ring[]] |
| tst.ts:38:27:38:47 | [TupleTypeExpr] [number ... ring[]] | semmle.label | [TupleTypeExpr] [number ... ring[]] |
@@ -279,7 +297,7 @@ nodes
| tst.ts:38:39:38:44 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
| tst.ts:38:39:38:46 | [ArrayTypeExpr] string[] | semmle.label | [ArrayTypeExpr] string[] |
| tst.ts:39:1:39:69 | [DeclStmt] let tupleWithOptionalAndRestElements = ... | semmle.label | [DeclStmt] let tupleWithOptionalAndRestElements = ... |
| tst.ts:39:1:39:69 | [DeclStmt] let tupleWithOptionalAndRestElements = ... | semmle.order | 40 |
| tst.ts:39:1:39:69 | [DeclStmt] let tupleWithOptionalAndRestElements = ... | semmle.order | 42 |
| tst.ts:39:5:39:36 | [VarDecl] tupleWithOptionalAndRestElements | semmle.label | [VarDecl] tupleWithOptionalAndRestElements |
| tst.ts:39:5:39:68 | [VariableDeclarator] tupleWi ... mber[]] | semmle.label | [VariableDeclarator] tupleWi ... mber[]] |
| tst.ts:39:39:39:68 | [TupleTypeExpr] [number ... mber[]] | semmle.label | [TupleTypeExpr] [number ... mber[]] |
@@ -290,12 +308,12 @@ nodes
| tst.ts:39:60:39:65 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| tst.ts:39:60:39:67 | [ArrayTypeExpr] number[] | semmle.label | [ArrayTypeExpr] number[] |
| tst.ts:40:1:40:25 | [DeclStmt] let unknownType = ... | semmle.label | [DeclStmt] let unknownType = ... |
| tst.ts:40:1:40:25 | [DeclStmt] let unknownType = ... | semmle.order | 41 |
| tst.ts:40:1:40:25 | [DeclStmt] let unknownType = ... | semmle.order | 43 |
| tst.ts:40:5:40:15 | [VarDecl] unknownType | semmle.label | [VarDecl] unknownType |
| tst.ts:40:5:40:24 | [VariableDeclarator] unknownType: unknown | semmle.label | [VariableDeclarator] unknownType: unknown |
| tst.ts:40:18:40:24 | [KeywordTypeExpr] unknown | semmle.label | [KeywordTypeExpr] unknown |
| tst.ts:42:1:42:40 | [DeclStmt] let constArrayLiteral = ... | semmle.label | [DeclStmt] let constArrayLiteral = ... |
| tst.ts:42:1:42:40 | [DeclStmt] let constArrayLiteral = ... | semmle.order | 42 |
| tst.ts:42:1:42:40 | [DeclStmt] let constArrayLiteral = ... | semmle.order | 44 |
| tst.ts:42:5:42:21 | [VarDecl] constArrayLiteral | semmle.label | [VarDecl] constArrayLiteral |
| tst.ts:42:5:42:39 | [VariableDeclarator] constAr ... s const | semmle.label | [VariableDeclarator] constAr ... s const |
| tst.ts:42:25:42:30 | [ArrayExpr] [1, 2] | semmle.label | [ArrayExpr] [1, 2] |
@@ -304,7 +322,7 @@ nodes
| tst.ts:42:29:42:29 | [Literal] 2 | semmle.label | [Literal] 2 |
| tst.ts:42:35:42:39 | [KeywordTypeExpr] const | semmle.label | [KeywordTypeExpr] const |
| tst.ts:43:1:43:49 | [DeclStmt] let constObjectLiteral = ... | semmle.label | [DeclStmt] let constObjectLiteral = ... |
| tst.ts:43:1:43:49 | [DeclStmt] let constObjectLiteral = ... | semmle.order | 43 |
| tst.ts:43:1:43:49 | [DeclStmt] let constObjectLiteral = ... | semmle.order | 45 |
| tst.ts:43:5:43:22 | [VarDecl] constObjectLiteral | semmle.label | [VarDecl] constObjectLiteral |
| tst.ts:43:5:43:48 | [VariableDeclarator] constOb ... s const | semmle.label | [VariableDeclarator] constOb ... s const |
| tst.ts:43:26:43:39 | [ObjectExpr] {foo: ...} | semmle.label | [ObjectExpr] {foo: ...} |
@@ -314,7 +332,7 @@ nodes
| tst.ts:43:33:43:37 | [Literal] "foo" | semmle.label | [Literal] "foo" |
| tst.ts:43:44:43:48 | [KeywordTypeExpr] const | semmle.label | [KeywordTypeExpr] const |
| tst.ts:46:1:51:1 | [TryStmt] try { } ... ; } } | semmle.label | [TryStmt] try { } ... ; } } |
| tst.ts:46:1:51:1 | [TryStmt] try { } ... ; } } | semmle.order | 44 |
| tst.ts:46:1:51:1 | [TryStmt] try { } ... ; } } | semmle.order | 46 |
| tst.ts:46:5:46:7 | [BlockStmt] { } | semmle.label | [BlockStmt] { } |
| tst.ts:47:1:51:1 | [CatchClause] catch ( ... ; } } | semmle.label | [CatchClause] catch ( ... ; } } |
| tst.ts:47:8:47:8 | [SimpleParameter] e | semmle.label | [SimpleParameter] e |
@@ -330,17 +348,78 @@ nodes
| tst.ts:49:11:49:24 | [VariableDeclarator] b : string = e | semmle.label | [VariableDeclarator] b : string = e |
| tst.ts:49:15:49:20 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
| tst.ts:49:24:49:24 | [VarRef] e | semmle.label | [VarRef] e |
| tst.ts:54:1:56:1 | [InterfaceDeclaration,TypeDefinition] interfa ... mber; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... mber; } |
| tst.ts:54:1:56:1 | [InterfaceDeclaration,TypeDefinition] interfa ... mber; } | semmle.order | 47 |
| tst.ts:54:11:54:26 | [Identifier] NonAbstractDummy | semmle.label | [Identifier] NonAbstractDummy |
| tst.ts:55:3:55:9 | [Label] getArea | semmle.label | [Label] getArea |
| tst.ts:55:3:55:20 | [FunctionExpr] getArea(): number; | semmle.label | [FunctionExpr] getArea(): number; |
| tst.ts:55:3:55:20 | [MethodSignature] getArea(): number; | semmle.label | [MethodSignature] getArea(): number; |
| tst.ts:55:14:55:19 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| tst.ts:58:1:60:1 | [InterfaceDeclaration,TypeDefinition] interfa ... mber; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... mber; } |
| tst.ts:58:1:60:1 | [InterfaceDeclaration,TypeDefinition] interfa ... mber; } | semmle.order | 48 |
| tst.ts:58:11:58:17 | [Identifier] HasArea | semmle.label | [Identifier] HasArea |
| tst.ts:59:3:59:9 | [Label] getArea | semmle.label | [Label] getArea |
| tst.ts:59:3:59:20 | [FunctionExpr] getArea(): number; | semmle.label | [FunctionExpr] getArea(): number; |
| tst.ts:59:3:59:20 | [MethodSignature] getArea(): number; | semmle.label | [MethodSignature] getArea(): number; |
| tst.ts:59:14:59:19 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| tst.ts:63:1:63:45 | [DeclStmt] let Ctor = ... | semmle.label | [DeclStmt] let Ctor = ... |
| tst.ts:63:1:63:45 | [DeclStmt] let Ctor = ... | semmle.order | 49 |
| tst.ts:63:5:63:8 | [VarDecl] Ctor | semmle.label | [VarDecl] Ctor |
| tst.ts:63:5:63:44 | [VariableDeclarator] Ctor: a ... = Shape | semmle.label | [VariableDeclarator] Ctor: a ... = Shape |
| tst.ts:63:11:63:36 | [FunctionExpr] abstrac ... HasArea | semmle.label | [FunctionExpr] abstrac ... HasArea |
| tst.ts:63:11:63:36 | [FunctionTypeExpr] abstrac ... HasArea | semmle.label | [FunctionTypeExpr] abstrac ... HasArea |
| tst.ts:63:30:63:36 | [LocalTypeAccess] HasArea | semmle.label | [LocalTypeAccess] HasArea |
| tst.ts:63:40:63:44 | [VarRef] Shape | semmle.label | [VarRef] Shape |
| tst.ts:65:1:65:54 | [TypeAliasDeclaration,TypeDefinition] type My ... true}; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type My ... true}; |
| tst.ts:65:1:65:54 | [TypeAliasDeclaration,TypeDefinition] type My ... true}; | semmle.order | 50 |
| tst.ts:65:6:65:12 | [Identifier] MyUnion | semmle.label | [Identifier] MyUnion |
| tst.ts:65:16:65:30 | [InterfaceTypeExpr] {myUnion: true} | semmle.label | [InterfaceTypeExpr] {myUnion: true} |
| tst.ts:65:16:65:53 | [UnionTypeExpr] {myUnio ... : true} | semmle.label | [UnionTypeExpr] {myUnio ... : true} |
| tst.ts:65:17:65:23 | [Label] myUnion | semmle.label | [Label] myUnion |
| tst.ts:65:17:65:29 | [FieldDeclaration] myUnion: true | semmle.label | [FieldDeclaration] myUnion: true |
| tst.ts:65:26:65:29 | [LiteralTypeExpr] true | semmle.label | [LiteralTypeExpr] true |
| tst.ts:65:34:65:53 | [InterfaceTypeExpr] {stillMyUnion: true} | semmle.label | [InterfaceTypeExpr] {stillMyUnion: true} |
| tst.ts:65:35:65:46 | [Label] stillMyUnion | semmle.label | [Label] stillMyUnion |
| tst.ts:65:35:65:52 | [FieldDeclaration] stillMyUnion: true | semmle.label | [FieldDeclaration] stillMyUnion: true |
| tst.ts:65:49:65:52 | [LiteralTypeExpr] true | semmle.label | [LiteralTypeExpr] true |
| tst.ts:66:1:66:38 | [DeclStmt] let union1 = ... | semmle.label | [DeclStmt] let union1 = ... |
| tst.ts:66:1:66:38 | [DeclStmt] let union1 = ... | semmle.order | 51 |
| tst.ts:66:5:66:10 | [VarDecl] union1 | semmle.label | [VarDecl] union1 |
| tst.ts:66:5:66:37 | [VariableDeclarator] union1: ... : true} | semmle.label | [VariableDeclarator] union1: ... : true} |
| tst.ts:66:13:66:19 | [LocalTypeAccess] MyUnion | semmle.label | [LocalTypeAccess] MyUnion |
| tst.ts:66:23:66:37 | [ObjectExpr] {myUnion: ...} | semmle.label | [ObjectExpr] {myUnion: ...} |
| tst.ts:66:24:66:30 | [Label] myUnion | semmle.label | [Label] myUnion |
| tst.ts:66:24:66:36 | [Property] myUnion: true | semmle.label | [Property] myUnion: true |
| tst.ts:66:33:66:36 | [Literal] true | semmle.label | [Literal] true |
| tst.ts:68:1:68:49 | [TypeAliasDeclaration,TypeDefinition] type My ... true}; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type My ... true}; |
| tst.ts:68:1:68:49 | [TypeAliasDeclaration,TypeDefinition] type My ... true}; | semmle.order | 52 |
| tst.ts:68:6:68:13 | [Identifier] MyUnion2 | semmle.label | [Identifier] MyUnion2 |
| tst.ts:68:17:68:23 | [LocalTypeAccess] MyUnion | semmle.label | [LocalTypeAccess] MyUnion |
| tst.ts:68:17:68:48 | [UnionTypeExpr] MyUnion ... : true} | semmle.label | [UnionTypeExpr] MyUnion ... : true} |
| tst.ts:68:27:68:48 | [InterfaceTypeExpr] {yetAno ... : true} | semmle.label | [InterfaceTypeExpr] {yetAno ... : true} |
| tst.ts:68:28:68:41 | [Label] yetAnotherType | semmle.label | [Label] yetAnotherType |
| tst.ts:68:28:68:47 | [FieldDeclaration] yetAnotherType: true | semmle.label | [FieldDeclaration] yetAnotherType: true |
| tst.ts:68:44:68:47 | [LiteralTypeExpr] true | semmle.label | [LiteralTypeExpr] true |
| tst.ts:69:1:69:46 | [DeclStmt] let union2 = ... | semmle.label | [DeclStmt] let union2 = ... |
| tst.ts:69:1:69:46 | [DeclStmt] let union2 = ... | semmle.order | 53 |
| tst.ts:69:5:69:10 | [VarDecl] union2 | semmle.label | [VarDecl] union2 |
| tst.ts:69:5:69:45 | [VariableDeclarator] union2: ... : true} | semmle.label | [VariableDeclarator] union2: ... : true} |
| tst.ts:69:13:69:20 | [LocalTypeAccess] MyUnion2 | semmle.label | [LocalTypeAccess] MyUnion2 |
| tst.ts:69:24:69:45 | [ObjectExpr] {yetAnotherType: ...} | semmle.label | [ObjectExpr] {yetAnotherType: ...} |
| tst.ts:69:25:69:38 | [Label] yetAnotherType | semmle.label | [Label] yetAnotherType |
| tst.ts:69:25:69:44 | [Property] yetAnotherType: true | semmle.label | [Property] yetAnotherType: true |
| tst.ts:69:41:69:44 | [Literal] true | semmle.label | [Literal] true |
| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type B = boolean; |
| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 45 |
| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 54 |
| type_alias.ts:1:6:1:6 | [Identifier] B | semmle.label | [Identifier] B |
| type_alias.ts:1:10:1:16 | [KeywordTypeExpr] boolean | semmle.label | [KeywordTypeExpr] boolean |
| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.label | [DeclStmt] var b = ... |
| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 46 |
| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 55 |
| type_alias.ts:3:5:3:5 | [VarDecl] b | semmle.label | [VarDecl] b |
| type_alias.ts:3:5:3:8 | [VariableDeclarator] b: B | semmle.label | [VariableDeclarator] b: B |
| type_alias.ts:3:8:3:8 | [LocalTypeAccess] B | semmle.label | [LocalTypeAccess] B |
| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay<T>>; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Va ... ay<T>>; |
| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay<T>>; | semmle.order | 47 |
| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay<T>>; | semmle.order | 56 |
| type_alias.ts:5:6:5:17 | [Identifier] ValueOrArray | semmle.label | [Identifier] ValueOrArray |
| type_alias.ts:5:19:5:19 | [Identifier] T | semmle.label | [Identifier] T |
| type_alias.ts:5:19:5:19 | [TypeParameter] T | semmle.label | [TypeParameter] T |
@@ -352,14 +431,14 @@ nodes
| type_alias.ts:5:34:5:48 | [GenericTypeExpr] ValueOrArray<T> | semmle.label | [GenericTypeExpr] ValueOrArray<T> |
| type_alias.ts:5:47:5:47 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.label | [DeclStmt] var c = ... |
| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 48 |
| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 57 |
| type_alias.ts:7:5:7:5 | [VarDecl] c | semmle.label | [VarDecl] c |
| type_alias.ts:7:5:7:27 | [VariableDeclarator] c: Valu ... number> | semmle.label | [VariableDeclarator] c: Valu ... number> |
| type_alias.ts:7:8:7:19 | [LocalTypeAccess] ValueOrArray | semmle.label | [LocalTypeAccess] ValueOrArray |
| type_alias.ts:7:8:7:27 | [GenericTypeExpr] ValueOrArray<number> | semmle.label | [GenericTypeExpr] ValueOrArray<number> |
| type_alias.ts:7:21:7:26 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; |
| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 49 |
| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 58 |
| type_alias.ts:9:6:9:9 | [Identifier] Json | semmle.label | [Identifier] Json |
| type_alias.ts:10:5:15:12 | [UnionTypeExpr] \| strin ... Json[] | semmle.label | [UnionTypeExpr] \| strin ... Json[] |
| type_alias.ts:10:7:10:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
@@ -375,12 +454,12 @@ nodes
| type_alias.ts:15:7:15:10 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json |
| type_alias.ts:15:7:15:12 | [ArrayTypeExpr] Json[] | semmle.label | [ArrayTypeExpr] Json[] |
| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.label | [DeclStmt] var json = ... |
| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 50 |
| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 59 |
| type_alias.ts:17:5:17:8 | [VarDecl] json | semmle.label | [VarDecl] json |
| type_alias.ts:17:5:17:14 | [VariableDeclarator] json: Json | semmle.label | [VariableDeclarator] json: Json |
| type_alias.ts:17:11:17:14 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json |
| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; |
| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 51 |
| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 60 |
| type_alias.ts:19:6:19:16 | [Identifier] VirtualNode | semmle.label | [Identifier] VirtualNode |
| type_alias.ts:20:5:21:56 | [UnionTypeExpr] \| strin ... Node[]] | semmle.label | [UnionTypeExpr] \| strin ... Node[]] |
| type_alias.ts:20:7:20:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string |
@@ -396,7 +475,7 @@ nodes
| type_alias.ts:21:43:21:53 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode |
| type_alias.ts:21:43:21:55 | [ArrayTypeExpr] VirtualNode[] | semmle.label | [ArrayTypeExpr] VirtualNode[] |
| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.label | [DeclStmt] const myNode = ... |
| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 52 |
| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 61 |
| type_alias.ts:23:7:23:12 | [VarDecl] myNode | semmle.label | [VarDecl] myNode |
| type_alias.ts:23:7:27:5 | [VariableDeclarator] myNode: ... ] ] | semmle.label | [VariableDeclarator] myNode: ... ] ] |
| type_alias.ts:23:15:23:25 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode |
@@ -421,12 +500,12 @@ nodes
| type_alias.ts:26:23:26:36 | [Literal] "second-child" | semmle.label | [Literal] "second-child" |
| type_alias.ts:26:41:26:62 | [Literal] "I'm the second child" | semmle.label | [Literal] "I'm the second child" |
| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; |
| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 53 |
| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 62 |
| type_definition_objects.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy |
| type_definition_objects.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy |
| type_definition_objects.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" |
| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.label | [ExportDeclaration] export class C {} |
| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 54 |
| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 63 |
| type_definition_objects.ts:3:8:3:17 | [ClassDefinition,TypeDefinition] class C {} | semmle.label | [ClassDefinition,TypeDefinition] class C {} |
| type_definition_objects.ts:3:14:3:14 | [VarDecl] C | semmle.label | [VarDecl] C |
| type_definition_objects.ts:3:16:3:15 | [BlockStmt] {} | semmle.label | [BlockStmt] {} |
@@ -434,36 +513,36 @@ nodes
| type_definition_objects.ts:3:16:3:15 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} |
| type_definition_objects.ts:3:16:3:15 | [Label] constructor | semmle.label | [Label] constructor |
| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.label | [DeclStmt] let classObj = ... |
| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 55 |
| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 64 |
| type_definition_objects.ts:4:5:4:12 | [VarDecl] classObj | semmle.label | [VarDecl] classObj |
| type_definition_objects.ts:4:5:4:16 | [VariableDeclarator] classObj = C | semmle.label | [VariableDeclarator] classObj = C |
| type_definition_objects.ts:4:16:4:16 | [VarRef] C | semmle.label | [VarRef] C |
| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.label | [ExportDeclaration] export enum E {} |
| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 56 |
| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 65 |
| type_definition_objects.ts:6:8:6:16 | [EnumDeclaration,TypeDefinition] enum E {} | semmle.label | [EnumDeclaration,TypeDefinition] enum E {} |
| type_definition_objects.ts:6:13:6:13 | [VarDecl] E | semmle.label | [VarDecl] E |
| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.label | [DeclStmt] let enumObj = ... |
| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 57 |
| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 66 |
| type_definition_objects.ts:7:5:7:11 | [VarDecl] enumObj | semmle.label | [VarDecl] enumObj |
| type_definition_objects.ts:7:5:7:15 | [VariableDeclarator] enumObj = E | semmle.label | [VariableDeclarator] enumObj = E |
| type_definition_objects.ts:7:15:7:15 | [VarRef] E | semmle.label | [VarRef] E |
| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.label | [ExportDeclaration] export ... e N {;} |
| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 58 |
| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 67 |
| type_definition_objects.ts:9:8:9:22 | [NamespaceDeclaration] namespace N {;} | semmle.label | [NamespaceDeclaration] namespace N {;} |
| type_definition_objects.ts:9:18:9:18 | [VarDecl] N | semmle.label | [VarDecl] N |
| type_definition_objects.ts:9:21:9:21 | [EmptyStmt] ; | semmle.label | [EmptyStmt] ; |
| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.label | [DeclStmt] let namespaceObj = ... |
| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 59 |
| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 68 |
| type_definition_objects.ts:10:5:10:16 | [VarDecl] namespaceObj | semmle.label | [VarDecl] namespaceObj |
| type_definition_objects.ts:10:5:10:20 | [VariableDeclarator] namespaceObj = N | semmle.label | [VariableDeclarator] namespaceObj = N |
| type_definition_objects.ts:10:20:10:20 | [VarRef] N | semmle.label | [VarRef] N |
| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; |
| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 60 |
| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 69 |
| type_definitions.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy |
| type_definitions.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy |
| type_definitions.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" |
| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } |
| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 61 |
| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 70 |
| type_definitions.ts:3:11:3:11 | [Identifier] I | semmle.label | [Identifier] I |
| type_definitions.ts:3:13:3:13 | [Identifier] S | semmle.label | [Identifier] S |
| type_definitions.ts:3:13:3:13 | [TypeParameter] S | semmle.label | [TypeParameter] S |
@@ -471,14 +550,14 @@ nodes
| type_definitions.ts:4:3:4:7 | [FieldDeclaration] x: S; | semmle.label | [FieldDeclaration] x: S; |
| type_definitions.ts:4:6:4:6 | [LocalTypeAccess] S | semmle.label | [LocalTypeAccess] S |
| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.label | [DeclStmt] let i = ... |
| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 62 |
| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 71 |
| type_definitions.ts:6:5:6:5 | [VarDecl] i | semmle.label | [VarDecl] i |
| type_definitions.ts:6:5:6:16 | [VariableDeclarator] i: I<number> | semmle.label | [VariableDeclarator] i: I<number> |
| type_definitions.ts:6:8:6:8 | [LocalTypeAccess] I | semmle.label | [LocalTypeAccess] I |
| type_definitions.ts:6:8:6:16 | [GenericTypeExpr] I<number> | semmle.label | [GenericTypeExpr] I<number> |
| type_definitions.ts:6:10:6:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.label | [ClassDefinition,TypeDefinition] class C ... x: T } |
| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 63 |
| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 72 |
| type_definitions.ts:8:7:8:7 | [VarDecl] C | semmle.label | [VarDecl] C |
| type_definitions.ts:8:8:8:7 | [BlockStmt] {} | semmle.label | [BlockStmt] {} |
| type_definitions.ts:8:8:8:7 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} |
@@ -490,14 +569,14 @@ nodes
| type_definitions.ts:9:3:9:6 | [FieldDeclaration] x: T | semmle.label | [FieldDeclaration] x: T |
| type_definitions.ts:9:6:9:6 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.label | [DeclStmt] let c = ... |
| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 64 |
| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 73 |
| type_definitions.ts:11:5:11:5 | [VarDecl] c | semmle.label | [VarDecl] c |
| type_definitions.ts:11:5:11:16 | [VariableDeclarator] c: C<number> | semmle.label | [VariableDeclarator] c: C<number> |
| type_definitions.ts:11:8:11:8 | [LocalTypeAccess] C | semmle.label | [LocalTypeAccess] C |
| type_definitions.ts:11:8:11:16 | [GenericTypeExpr] C<number> | semmle.label | [GenericTypeExpr] C<number> |
| type_definitions.ts:11:10:11:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.label | [EnumDeclaration,TypeDefinition] enum Co ... blue } |
| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 65 |
| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 74 |
| type_definitions.ts:13:6:13:10 | [VarDecl] Color | semmle.label | [VarDecl] Color |
| type_definitions.ts:14:3:14:5 | [EnumMember,TypeDefinition] red | semmle.label | [EnumMember,TypeDefinition] red |
| type_definitions.ts:14:3:14:5 | [VarDecl] red | semmle.label | [VarDecl] red |
@@ -506,29 +585,29 @@ nodes
| type_definitions.ts:14:15:14:18 | [EnumMember,TypeDefinition] blue | semmle.label | [EnumMember,TypeDefinition] blue |
| type_definitions.ts:14:15:14:18 | [VarDecl] blue | semmle.label | [VarDecl] blue |
| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.label | [DeclStmt] let color = ... |
| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 66 |
| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 75 |
| type_definitions.ts:16:5:16:9 | [VarDecl] color | semmle.label | [VarDecl] color |
| type_definitions.ts:16:5:16:16 | [VariableDeclarator] color: Color | semmle.label | [VariableDeclarator] color: Color |
| type_definitions.ts:16:12:16:16 | [LocalTypeAccess] Color | semmle.label | [LocalTypeAccess] Color |
| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.label | [EnumDeclaration,TypeDefinition] enum En ... ember } |
| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 67 |
| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 76 |
| type_definitions.ts:18:6:18:22 | [VarDecl] EnumWithOneMember | semmle.label | [VarDecl] EnumWithOneMember |
| type_definitions.ts:18:26:18:31 | [EnumMember,TypeDefinition] member | semmle.label | [EnumMember,TypeDefinition] member |
| type_definitions.ts:18:26:18:31 | [VarDecl] member | semmle.label | [VarDecl] member |
| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.label | [DeclStmt] let e = ... |
| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 68 |
| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 77 |
| type_definitions.ts:19:5:19:5 | [VarDecl] e | semmle.label | [VarDecl] e |
| type_definitions.ts:19:5:19:24 | [VariableDeclarator] e: EnumWithOneMember | semmle.label | [VariableDeclarator] e: EnumWithOneMember |
| type_definitions.ts:19:8:19:24 | [LocalTypeAccess] EnumWithOneMember | semmle.label | [LocalTypeAccess] EnumWithOneMember |
| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias<T> = T[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Alias<T> = T[]; |
| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias<T> = T[]; | semmle.order | 69 |
| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias<T> = T[]; | semmle.order | 78 |
| type_definitions.ts:21:6:21:10 | [Identifier] Alias | semmle.label | [Identifier] Alias |
| type_definitions.ts:21:12:21:12 | [Identifier] T | semmle.label | [Identifier] T |
| type_definitions.ts:21:12:21:12 | [TypeParameter] T | semmle.label | [TypeParameter] T |
| type_definitions.ts:21:17:21:17 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
| type_definitions.ts:21:17:21:19 | [ArrayTypeExpr] T[] | semmle.label | [ArrayTypeExpr] T[] |
| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.label | [DeclStmt] let aliasForNumberArray = ... |
| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 70 |
| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 79 |
| type_definitions.ts:22:5:22:23 | [VarDecl] aliasForNumberArray | semmle.label | [VarDecl] aliasForNumberArray |
| type_definitions.ts:22:5:22:38 | [VariableDeclarator] aliasFo ... number> | semmle.label | [VariableDeclarator] aliasFo ... number> |
| type_definitions.ts:22:26:22:30 | [LocalTypeAccess] Alias | semmle.label | [LocalTypeAccess] Alias |
@@ -665,6 +744,34 @@ edges
| file://:0:0:0:0 | (TypeParameters) | type_definitions.ts:8:9:8:9 | [TypeParameter] T | semmle.order | 0 |
| file://:0:0:0:0 | (TypeParameters) | type_definitions.ts:21:12:21:12 | [TypeParameter] T | semmle.label | 0 |
| file://:0:0:0:0 | (TypeParameters) | type_definitions.ts:21:12:21:12 | [TypeParameter] T | semmle.order | 0 |
| middle-rest.ts:1:1:1:40 | [DeclStmt] let foo = ... | middle-rest.ts:1:5:1:39 | [VariableDeclarator] foo: [b ... number] | semmle.label | 1 |
| middle-rest.ts:1:1:1:40 | [DeclStmt] let foo = ... | middle-rest.ts:1:5:1:39 | [VariableDeclarator] foo: [b ... number] | semmle.order | 1 |
| middle-rest.ts:1:5:1:39 | [VariableDeclarator] foo: [b ... number] | middle-rest.ts:1:5:1:7 | [VarDecl] foo | semmle.label | 1 |
| middle-rest.ts:1:5:1:39 | [VariableDeclarator] foo: [b ... number] | middle-rest.ts:1:5:1:7 | [VarDecl] foo | semmle.order | 1 |
| middle-rest.ts:1:5:1:39 | [VariableDeclarator] foo: [b ... number] | middle-rest.ts:1:10:1:39 | [TupleTypeExpr] [boolea ... number] | semmle.label | 2 |
| middle-rest.ts:1:5:1:39 | [VariableDeclarator] foo: [b ... number] | middle-rest.ts:1:10:1:39 | [TupleTypeExpr] [boolea ... number] | semmle.order | 2 |
| middle-rest.ts:1:10:1:39 | [TupleTypeExpr] [boolea ... number] | middle-rest.ts:1:11:1:17 | [KeywordTypeExpr] boolean | semmle.label | 1 |
| middle-rest.ts:1:10:1:39 | [TupleTypeExpr] [boolea ... number] | middle-rest.ts:1:11:1:17 | [KeywordTypeExpr] boolean | semmle.order | 1 |
| middle-rest.ts:1:10:1:39 | [TupleTypeExpr] [boolea ... number] | middle-rest.ts:1:20:1:30 | [RestTypeExpr] ...string[] | semmle.label | 2 |
| middle-rest.ts:1:10:1:39 | [TupleTypeExpr] [boolea ... number] | middle-rest.ts:1:20:1:30 | [RestTypeExpr] ...string[] | semmle.order | 2 |
| middle-rest.ts:1:10:1:39 | [TupleTypeExpr] [boolea ... number] | middle-rest.ts:1:33:1:38 | [KeywordTypeExpr] number | semmle.label | 3 |
| middle-rest.ts:1:10:1:39 | [TupleTypeExpr] [boolea ... number] | middle-rest.ts:1:33:1:38 | [KeywordTypeExpr] number | semmle.order | 3 |
| middle-rest.ts:1:20:1:30 | [RestTypeExpr] ...string[] | middle-rest.ts:1:23:1:30 | [ArrayTypeExpr] string[] | semmle.label | 1 |
| middle-rest.ts:1:20:1:30 | [RestTypeExpr] ...string[] | middle-rest.ts:1:23:1:30 | [ArrayTypeExpr] string[] | semmle.order | 1 |
| middle-rest.ts:1:23:1:30 | [ArrayTypeExpr] string[] | middle-rest.ts:1:23:1:28 | [KeywordTypeExpr] string | semmle.label | 1 |
| middle-rest.ts:1:23:1:30 | [ArrayTypeExpr] string[] | middle-rest.ts:1:23:1:28 | [KeywordTypeExpr] string | semmle.order | 1 |
| middle-rest.ts:3:1:3:26 | [AssignExpr] foo = [ ... ", 123] | middle-rest.ts:3:1:3:3 | [VarRef] foo | semmle.label | 1 |
| middle-rest.ts:3:1:3:26 | [AssignExpr] foo = [ ... ", 123] | middle-rest.ts:3:1:3:3 | [VarRef] foo | semmle.order | 1 |
| middle-rest.ts:3:1:3:26 | [AssignExpr] foo = [ ... ", 123] | middle-rest.ts:3:7:3:26 | [ArrayExpr] [true, "hello", 123] | semmle.label | 2 |
| middle-rest.ts:3:1:3:26 | [AssignExpr] foo = [ ... ", 123] | middle-rest.ts:3:7:3:26 | [ArrayExpr] [true, "hello", 123] | semmle.order | 2 |
| middle-rest.ts:3:1:3:27 | [ExprStmt] foo = [ ... , 123]; | middle-rest.ts:3:1:3:26 | [AssignExpr] foo = [ ... ", 123] | semmle.label | 1 |
| middle-rest.ts:3:1:3:27 | [ExprStmt] foo = [ ... , 123]; | middle-rest.ts:3:1:3:26 | [AssignExpr] foo = [ ... ", 123] | semmle.order | 1 |
| middle-rest.ts:3:7:3:26 | [ArrayExpr] [true, "hello", 123] | middle-rest.ts:3:8:3:11 | [Literal] true | semmle.label | 1 |
| middle-rest.ts:3:7:3:26 | [ArrayExpr] [true, "hello", 123] | middle-rest.ts:3:8:3:11 | [Literal] true | semmle.order | 1 |
| middle-rest.ts:3:7:3:26 | [ArrayExpr] [true, "hello", 123] | middle-rest.ts:3:14:3:20 | [Literal] "hello" | semmle.label | 2 |
| middle-rest.ts:3:7:3:26 | [ArrayExpr] [true, "hello", 123] | middle-rest.ts:3:14:3:20 | [Literal] "hello" | semmle.order | 2 |
| middle-rest.ts:3:7:3:26 | [ArrayExpr] [true, "hello", 123] | middle-rest.ts:3:23:3:25 | [Literal] 123 | semmle.label | 3 |
| middle-rest.ts:3:7:3:26 | [ArrayExpr] [true, "hello", 123] | middle-rest.ts:3:23:3:25 | [Literal] 123 | semmle.order | 3 |
| tst.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | tst.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | 1 |
| tst.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | tst.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.order | 1 |
| tst.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | tst.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | 2 |
@@ -1021,6 +1128,100 @@ edges
| tst.ts:49:11:49:24 | [VariableDeclarator] b : string = e | tst.ts:49:15:49:20 | [KeywordTypeExpr] string | semmle.order | 2 |
| tst.ts:49:11:49:24 | [VariableDeclarator] b : string = e | tst.ts:49:24:49:24 | [VarRef] e | semmle.label | 3 |
| tst.ts:49:11:49:24 | [VariableDeclarator] b : string = e | tst.ts:49:24:49:24 | [VarRef] e | semmle.order | 3 |
| tst.ts:54:1:56:1 | [InterfaceDeclaration,TypeDefinition] interfa ... mber; } | tst.ts:54:11:54:26 | [Identifier] NonAbstractDummy | semmle.label | 1 |
| tst.ts:54:1:56:1 | [InterfaceDeclaration,TypeDefinition] interfa ... mber; } | tst.ts:54:11:54:26 | [Identifier] NonAbstractDummy | semmle.order | 1 |
| tst.ts:54:1:56:1 | [InterfaceDeclaration,TypeDefinition] interfa ... mber; } | tst.ts:55:3:55:20 | [MethodSignature] getArea(): number; | semmle.label | 2 |
| tst.ts:54:1:56:1 | [InterfaceDeclaration,TypeDefinition] interfa ... mber; } | tst.ts:55:3:55:20 | [MethodSignature] getArea(): number; | semmle.order | 2 |
| tst.ts:55:3:55:20 | [FunctionExpr] getArea(): number; | tst.ts:55:14:55:19 | [KeywordTypeExpr] number | semmle.label | 4 |
| tst.ts:55:3:55:20 | [FunctionExpr] getArea(): number; | tst.ts:55:14:55:19 | [KeywordTypeExpr] number | semmle.order | 4 |
| tst.ts:55:3:55:20 | [MethodSignature] getArea(): number; | tst.ts:55:3:55:9 | [Label] getArea | semmle.label | 1 |
| tst.ts:55:3:55:20 | [MethodSignature] getArea(): number; | tst.ts:55:3:55:9 | [Label] getArea | semmle.order | 1 |
| tst.ts:55:3:55:20 | [MethodSignature] getArea(): number; | tst.ts:55:3:55:20 | [FunctionExpr] getArea(): number; | semmle.label | 2 |
| tst.ts:55:3:55:20 | [MethodSignature] getArea(): number; | tst.ts:55:3:55:20 | [FunctionExpr] getArea(): number; | semmle.order | 2 |
| tst.ts:58:1:60:1 | [InterfaceDeclaration,TypeDefinition] interfa ... mber; } | tst.ts:58:11:58:17 | [Identifier] HasArea | semmle.label | 1 |
| tst.ts:58:1:60:1 | [InterfaceDeclaration,TypeDefinition] interfa ... mber; } | tst.ts:58:11:58:17 | [Identifier] HasArea | semmle.order | 1 |
| tst.ts:58:1:60:1 | [InterfaceDeclaration,TypeDefinition] interfa ... mber; } | tst.ts:59:3:59:20 | [MethodSignature] getArea(): number; | semmle.label | 2 |
| tst.ts:58:1:60:1 | [InterfaceDeclaration,TypeDefinition] interfa ... mber; } | tst.ts:59:3:59:20 | [MethodSignature] getArea(): number; | semmle.order | 2 |
| tst.ts:59:3:59:20 | [FunctionExpr] getArea(): number; | tst.ts:59:14:59:19 | [KeywordTypeExpr] number | semmle.label | 4 |
| tst.ts:59:3:59:20 | [FunctionExpr] getArea(): number; | tst.ts:59:14:59:19 | [KeywordTypeExpr] number | semmle.order | 4 |
| tst.ts:59:3:59:20 | [MethodSignature] getArea(): number; | tst.ts:59:3:59:9 | [Label] getArea | semmle.label | 1 |
| tst.ts:59:3:59:20 | [MethodSignature] getArea(): number; | tst.ts:59:3:59:9 | [Label] getArea | semmle.order | 1 |
| tst.ts:59:3:59:20 | [MethodSignature] getArea(): number; | tst.ts:59:3:59:20 | [FunctionExpr] getArea(): number; | semmle.label | 2 |
| tst.ts:59:3:59:20 | [MethodSignature] getArea(): number; | tst.ts:59:3:59:20 | [FunctionExpr] getArea(): number; | semmle.order | 2 |
| tst.ts:63:1:63:45 | [DeclStmt] let Ctor = ... | tst.ts:63:5:63:44 | [VariableDeclarator] Ctor: a ... = Shape | semmle.label | 1 |
| tst.ts:63:1:63:45 | [DeclStmt] let Ctor = ... | tst.ts:63:5:63:44 | [VariableDeclarator] Ctor: a ... = Shape | semmle.order | 1 |
| tst.ts:63:5:63:44 | [VariableDeclarator] Ctor: a ... = Shape | tst.ts:63:5:63:8 | [VarDecl] Ctor | semmle.label | 1 |
| tst.ts:63:5:63:44 | [VariableDeclarator] Ctor: a ... = Shape | tst.ts:63:5:63:8 | [VarDecl] Ctor | semmle.order | 1 |
| tst.ts:63:5:63:44 | [VariableDeclarator] Ctor: a ... = Shape | tst.ts:63:11:63:36 | [FunctionTypeExpr] abstrac ... HasArea | semmle.label | 2 |
| tst.ts:63:5:63:44 | [VariableDeclarator] Ctor: a ... = Shape | tst.ts:63:11:63:36 | [FunctionTypeExpr] abstrac ... HasArea | semmle.order | 2 |
| tst.ts:63:5:63:44 | [VariableDeclarator] Ctor: a ... = Shape | tst.ts:63:40:63:44 | [VarRef] Shape | semmle.label | 3 |
| tst.ts:63:5:63:44 | [VariableDeclarator] Ctor: a ... = Shape | tst.ts:63:40:63:44 | [VarRef] Shape | semmle.order | 3 |
| tst.ts:63:11:63:36 | [FunctionExpr] abstrac ... HasArea | tst.ts:63:30:63:36 | [LocalTypeAccess] HasArea | semmle.label | 4 |
| tst.ts:63:11:63:36 | [FunctionExpr] abstrac ... HasArea | tst.ts:63:30:63:36 | [LocalTypeAccess] HasArea | semmle.order | 4 |
| tst.ts:63:11:63:36 | [FunctionTypeExpr] abstrac ... HasArea | tst.ts:63:11:63:36 | [FunctionExpr] abstrac ... HasArea | semmle.label | 1 |
| tst.ts:63:11:63:36 | [FunctionTypeExpr] abstrac ... HasArea | tst.ts:63:11:63:36 | [FunctionExpr] abstrac ... HasArea | semmle.order | 1 |
| tst.ts:65:1:65:54 | [TypeAliasDeclaration,TypeDefinition] type My ... true}; | tst.ts:65:6:65:12 | [Identifier] MyUnion | semmle.label | 1 |
| tst.ts:65:1:65:54 | [TypeAliasDeclaration,TypeDefinition] type My ... true}; | tst.ts:65:6:65:12 | [Identifier] MyUnion | semmle.order | 1 |
| tst.ts:65:1:65:54 | [TypeAliasDeclaration,TypeDefinition] type My ... true}; | tst.ts:65:16:65:53 | [UnionTypeExpr] {myUnio ... : true} | semmle.label | 2 |
| tst.ts:65:1:65:54 | [TypeAliasDeclaration,TypeDefinition] type My ... true}; | tst.ts:65:16:65:53 | [UnionTypeExpr] {myUnio ... : true} | semmle.order | 2 |
| tst.ts:65:16:65:30 | [InterfaceTypeExpr] {myUnion: true} | tst.ts:65:17:65:29 | [FieldDeclaration] myUnion: true | semmle.label | 1 |
| tst.ts:65:16:65:30 | [InterfaceTypeExpr] {myUnion: true} | tst.ts:65:17:65:29 | [FieldDeclaration] myUnion: true | semmle.order | 1 |
| tst.ts:65:16:65:53 | [UnionTypeExpr] {myUnio ... : true} | tst.ts:65:16:65:30 | [InterfaceTypeExpr] {myUnion: true} | semmle.label | 1 |
| tst.ts:65:16:65:53 | [UnionTypeExpr] {myUnio ... : true} | tst.ts:65:16:65:30 | [InterfaceTypeExpr] {myUnion: true} | semmle.order | 1 |
| tst.ts:65:16:65:53 | [UnionTypeExpr] {myUnio ... : true} | tst.ts:65:34:65:53 | [InterfaceTypeExpr] {stillMyUnion: true} | semmle.label | 2 |
| tst.ts:65:16:65:53 | [UnionTypeExpr] {myUnio ... : true} | tst.ts:65:34:65:53 | [InterfaceTypeExpr] {stillMyUnion: true} | semmle.order | 2 |
| tst.ts:65:17:65:29 | [FieldDeclaration] myUnion: true | tst.ts:65:17:65:23 | [Label] myUnion | semmle.label | 1 |
| tst.ts:65:17:65:29 | [FieldDeclaration] myUnion: true | tst.ts:65:17:65:23 | [Label] myUnion | semmle.order | 1 |
| tst.ts:65:17:65:29 | [FieldDeclaration] myUnion: true | tst.ts:65:26:65:29 | [LiteralTypeExpr] true | semmle.label | 2 |
| tst.ts:65:17:65:29 | [FieldDeclaration] myUnion: true | tst.ts:65:26:65:29 | [LiteralTypeExpr] true | semmle.order | 2 |
| tst.ts:65:34:65:53 | [InterfaceTypeExpr] {stillMyUnion: true} | tst.ts:65:35:65:52 | [FieldDeclaration] stillMyUnion: true | semmle.label | 1 |
| tst.ts:65:34:65:53 | [InterfaceTypeExpr] {stillMyUnion: true} | tst.ts:65:35:65:52 | [FieldDeclaration] stillMyUnion: true | semmle.order | 1 |
| tst.ts:65:35:65:52 | [FieldDeclaration] stillMyUnion: true | tst.ts:65:35:65:46 | [Label] stillMyUnion | semmle.label | 1 |
| tst.ts:65:35:65:52 | [FieldDeclaration] stillMyUnion: true | tst.ts:65:35:65:46 | [Label] stillMyUnion | semmle.order | 1 |
| tst.ts:65:35:65:52 | [FieldDeclaration] stillMyUnion: true | tst.ts:65:49:65:52 | [LiteralTypeExpr] true | semmle.label | 2 |
| tst.ts:65:35:65:52 | [FieldDeclaration] stillMyUnion: true | tst.ts:65:49:65:52 | [LiteralTypeExpr] true | semmle.order | 2 |
| tst.ts:66:1:66:38 | [DeclStmt] let union1 = ... | tst.ts:66:5:66:37 | [VariableDeclarator] union1: ... : true} | semmle.label | 1 |
| tst.ts:66:1:66:38 | [DeclStmt] let union1 = ... | tst.ts:66:5:66:37 | [VariableDeclarator] union1: ... : true} | semmle.order | 1 |
| tst.ts:66:5:66:37 | [VariableDeclarator] union1: ... : true} | tst.ts:66:5:66:10 | [VarDecl] union1 | semmle.label | 1 |
| tst.ts:66:5:66:37 | [VariableDeclarator] union1: ... : true} | tst.ts:66:5:66:10 | [VarDecl] union1 | semmle.order | 1 |
| tst.ts:66:5:66:37 | [VariableDeclarator] union1: ... : true} | tst.ts:66:13:66:19 | [LocalTypeAccess] MyUnion | semmle.label | 2 |
| tst.ts:66:5:66:37 | [VariableDeclarator] union1: ... : true} | tst.ts:66:13:66:19 | [LocalTypeAccess] MyUnion | semmle.order | 2 |
| tst.ts:66:5:66:37 | [VariableDeclarator] union1: ... : true} | tst.ts:66:23:66:37 | [ObjectExpr] {myUnion: ...} | semmle.label | 3 |
| tst.ts:66:5:66:37 | [VariableDeclarator] union1: ... : true} | tst.ts:66:23:66:37 | [ObjectExpr] {myUnion: ...} | semmle.order | 3 |
| tst.ts:66:23:66:37 | [ObjectExpr] {myUnion: ...} | tst.ts:66:24:66:36 | [Property] myUnion: true | semmle.label | 1 |
| tst.ts:66:23:66:37 | [ObjectExpr] {myUnion: ...} | tst.ts:66:24:66:36 | [Property] myUnion: true | semmle.order | 1 |
| tst.ts:66:24:66:36 | [Property] myUnion: true | tst.ts:66:24:66:30 | [Label] myUnion | semmle.label | 1 |
| tst.ts:66:24:66:36 | [Property] myUnion: true | tst.ts:66:24:66:30 | [Label] myUnion | semmle.order | 1 |
| tst.ts:66:24:66:36 | [Property] myUnion: true | tst.ts:66:33:66:36 | [Literal] true | semmle.label | 2 |
| tst.ts:66:24:66:36 | [Property] myUnion: true | tst.ts:66:33:66:36 | [Literal] true | semmle.order | 2 |
| tst.ts:68:1:68:49 | [TypeAliasDeclaration,TypeDefinition] type My ... true}; | tst.ts:68:6:68:13 | [Identifier] MyUnion2 | semmle.label | 1 |
| tst.ts:68:1:68:49 | [TypeAliasDeclaration,TypeDefinition] type My ... true}; | tst.ts:68:6:68:13 | [Identifier] MyUnion2 | semmle.order | 1 |
| tst.ts:68:1:68:49 | [TypeAliasDeclaration,TypeDefinition] type My ... true}; | tst.ts:68:17:68:48 | [UnionTypeExpr] MyUnion ... : true} | semmle.label | 2 |
| tst.ts:68:1:68:49 | [TypeAliasDeclaration,TypeDefinition] type My ... true}; | tst.ts:68:17:68:48 | [UnionTypeExpr] MyUnion ... : true} | semmle.order | 2 |
| tst.ts:68:17:68:48 | [UnionTypeExpr] MyUnion ... : true} | tst.ts:68:17:68:23 | [LocalTypeAccess] MyUnion | semmle.label | 1 |
| tst.ts:68:17:68:48 | [UnionTypeExpr] MyUnion ... : true} | tst.ts:68:17:68:23 | [LocalTypeAccess] MyUnion | semmle.order | 1 |
| tst.ts:68:17:68:48 | [UnionTypeExpr] MyUnion ... : true} | tst.ts:68:27:68:48 | [InterfaceTypeExpr] {yetAno ... : true} | semmle.label | 2 |
| tst.ts:68:17:68:48 | [UnionTypeExpr] MyUnion ... : true} | tst.ts:68:27:68:48 | [InterfaceTypeExpr] {yetAno ... : true} | semmle.order | 2 |
| tst.ts:68:27:68:48 | [InterfaceTypeExpr] {yetAno ... : true} | tst.ts:68:28:68:47 | [FieldDeclaration] yetAnotherType: true | semmle.label | 1 |
| tst.ts:68:27:68:48 | [InterfaceTypeExpr] {yetAno ... : true} | tst.ts:68:28:68:47 | [FieldDeclaration] yetAnotherType: true | semmle.order | 1 |
| tst.ts:68:28:68:47 | [FieldDeclaration] yetAnotherType: true | tst.ts:68:28:68:41 | [Label] yetAnotherType | semmle.label | 1 |
| tst.ts:68:28:68:47 | [FieldDeclaration] yetAnotherType: true | tst.ts:68:28:68:41 | [Label] yetAnotherType | semmle.order | 1 |
| tst.ts:68:28:68:47 | [FieldDeclaration] yetAnotherType: true | tst.ts:68:44:68:47 | [LiteralTypeExpr] true | semmle.label | 2 |
| tst.ts:68:28:68:47 | [FieldDeclaration] yetAnotherType: true | tst.ts:68:44:68:47 | [LiteralTypeExpr] true | semmle.order | 2 |
| tst.ts:69:1:69:46 | [DeclStmt] let union2 = ... | tst.ts:69:5:69:45 | [VariableDeclarator] union2: ... : true} | semmle.label | 1 |
| tst.ts:69:1:69:46 | [DeclStmt] let union2 = ... | tst.ts:69:5:69:45 | [VariableDeclarator] union2: ... : true} | semmle.order | 1 |
| tst.ts:69:5:69:45 | [VariableDeclarator] union2: ... : true} | tst.ts:69:5:69:10 | [VarDecl] union2 | semmle.label | 1 |
| tst.ts:69:5:69:45 | [VariableDeclarator] union2: ... : true} | tst.ts:69:5:69:10 | [VarDecl] union2 | semmle.order | 1 |
| tst.ts:69:5:69:45 | [VariableDeclarator] union2: ... : true} | tst.ts:69:13:69:20 | [LocalTypeAccess] MyUnion2 | semmle.label | 2 |
| tst.ts:69:5:69:45 | [VariableDeclarator] union2: ... : true} | tst.ts:69:13:69:20 | [LocalTypeAccess] MyUnion2 | semmle.order | 2 |
| tst.ts:69:5:69:45 | [VariableDeclarator] union2: ... : true} | tst.ts:69:24:69:45 | [ObjectExpr] {yetAnotherType: ...} | semmle.label | 3 |
| tst.ts:69:5:69:45 | [VariableDeclarator] union2: ... : true} | tst.ts:69:24:69:45 | [ObjectExpr] {yetAnotherType: ...} | semmle.order | 3 |
| tst.ts:69:24:69:45 | [ObjectExpr] {yetAnotherType: ...} | tst.ts:69:25:69:44 | [Property] yetAnotherType: true | semmle.label | 1 |
| tst.ts:69:24:69:45 | [ObjectExpr] {yetAnotherType: ...} | tst.ts:69:25:69:44 | [Property] yetAnotherType: true | semmle.order | 1 |
| tst.ts:69:25:69:44 | [Property] yetAnotherType: true | tst.ts:69:25:69:38 | [Label] yetAnotherType | semmle.label | 1 |
| tst.ts:69:25:69:44 | [Property] yetAnotherType: true | tst.ts:69:25:69:38 | [Label] yetAnotherType | semmle.order | 1 |
| tst.ts:69:25:69:44 | [Property] yetAnotherType: true | tst.ts:69:41:69:44 | [Literal] true | semmle.label | 2 |
| tst.ts:69:25:69:44 | [Property] yetAnotherType: true | tst.ts:69:41:69:44 | [Literal] true | semmle.order | 2 |
| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | type_alias.ts:1:6:1:6 | [Identifier] B | semmle.label | 1 |
| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | type_alias.ts:1:6:1:6 | [Identifier] B | semmle.order | 1 |
| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | type_alias.ts:1:10:1:16 | [KeywordTypeExpr] boolean | semmle.label | 2 |

View File

@@ -15,6 +15,13 @@ getExprType
| boolean-type.ts:15:5:15:12 | boolean6 | boolean |
| dummy.ts:2:12:2:12 | x | number |
| dummy.ts:2:16:2:16 | 5 | 5 |
| middle-rest.ts:1:5:1:7 | foo | [boolean, ...string[], number] |
| middle-rest.ts:3:1:3:3 | foo | [boolean, ...string[], number] |
| middle-rest.ts:3:1:3:26 | foo = [ ... ", 123] | [true, string, number] |
| middle-rest.ts:3:7:3:26 | [true, "hello", 123] | [boolean, ...string[], number] |
| middle-rest.ts:3:8:3:11 | true | true |
| middle-rest.ts:3:14:3:20 | "hello" | "hello" |
| middle-rest.ts:3:23:3:25 | 123 | 123 |
| tst.ts:1:13:1:17 | dummy | typeof library-tests/TypeScript/Types/dummy.ts |
| tst.ts:1:24:1:32 | "./dummy" | any |
| tst.ts:3:5:3:10 | numVar | number |
@@ -100,6 +107,24 @@ getExprType
| tst.ts:48:20:48:27 | "string" | "string" |
| tst.ts:49:11:49:11 | b | string |
| tst.ts:49:24:49:24 | e | string |
| tst.ts:55:3:55:9 | getArea | () => number |
| tst.ts:55:3:55:20 | getArea(): number; | () => number |
| tst.ts:59:3:59:9 | getArea | () => number |
| tst.ts:59:3:59:20 | getArea(): number; | () => number |
| tst.ts:63:5:63:8 | Ctor | abstract new () => HasArea |
| tst.ts:63:11:63:36 | abstrac ... HasArea | abstract new () => HasArea |
| tst.ts:63:40:63:44 | Shape | any |
| tst.ts:65:17:65:23 | myUnion | true |
| tst.ts:65:35:65:46 | stillMyUnion | true |
| tst.ts:66:5:66:10 | union1 | MyUnion |
| tst.ts:66:23:66:37 | {myUnion: true} | MyUnion |
| tst.ts:66:24:66:30 | myUnion | true |
| tst.ts:66:33:66:36 | true | true |
| tst.ts:68:28:68:41 | yetAnotherType | true |
| tst.ts:69:5:69:10 | union2 | MyUnion2 |
| tst.ts:69:24:69:45 | {yetAno ... : true} | MyUnion2 |
| tst.ts:69:25:69:38 | yetAnotherType | true |
| tst.ts:69:41:69:44 | true | true |
| type_alias.ts:3:5:3:5 | b | boolean |
| type_alias.ts:7:5:7:5 | c | ValueOrArray<number> |
| type_alias.ts:14:9:14:32 | [proper ... ]: Json | any |
@@ -149,6 +174,10 @@ getExprType
| type_definitions.ts:19:5:19:5 | e | EnumWithOneMember |
| type_definitions.ts:22:5:22:23 | aliasForNumberArray | Alias<number> |
getTypeDefinitionType
| tst.ts:54:1:56:1 | interfa ... mber;\\n} | NonAbstractDummy |
| tst.ts:58:1:60:1 | interfa ... mber;\\n} | HasArea |
| tst.ts:65:1:65:54 | type My ... true}; | MyUnion |
| tst.ts:68:1:68:49 | type My ... true}; | MyUnion2 |
| type_alias.ts:1:1:1:17 | type B = boolean; | boolean |
| type_alias.ts:5:1:5:50 | type Va ... ay<T>>; | ValueOrArray<T> |
| type_alias.ts:9:1:15:13 | type Js ... Json[]; | Json |
@@ -185,6 +214,12 @@ getTypeExprType
| boolean-type.ts:15:15:15:19 | false | false |
| boolean-type.ts:15:15:15:29 | false \| boolean | boolean |
| boolean-type.ts:15:23:15:29 | boolean | boolean |
| middle-rest.ts:1:10:1:39 | [boolea ... number] | [boolean, ...string[], number] |
| middle-rest.ts:1:11:1:17 | boolean | boolean |
| middle-rest.ts:1:20:1:30 | ...string[] | string |
| middle-rest.ts:1:23:1:28 | string | string |
| middle-rest.ts:1:23:1:30 | string[] | string[] |
| middle-rest.ts:1:33:1:38 | number | number |
| tst.ts:3:13:3:18 | number | number |
| tst.ts:9:13:9:18 | string | string |
| tst.ts:14:20:14:25 | string | string |
@@ -232,6 +267,25 @@ getTypeExprType
| tst.ts:39:60:39:67 | number[] | number[] |
| tst.ts:40:18:40:24 | unknown | unknown |
| tst.ts:49:15:49:20 | string | string |
| tst.ts:54:11:54:26 | NonAbstractDummy | NonAbstractDummy |
| tst.ts:55:14:55:19 | number | number |
| tst.ts:58:11:58:17 | HasArea | HasArea |
| tst.ts:59:14:59:19 | number | number |
| tst.ts:63:11:63:36 | abstrac ... HasArea | abstract new () => HasArea |
| tst.ts:63:30:63:36 | HasArea | HasArea |
| tst.ts:65:6:65:12 | MyUnion | MyUnion |
| tst.ts:65:16:65:30 | {myUnion: true} | { myUnion: true; } |
| tst.ts:65:16:65:53 | {myUnio ... : true} | { myUnion: true; } \| { stillMyUnion: true; } |
| tst.ts:65:26:65:29 | true | true |
| tst.ts:65:34:65:53 | {stillMyUnion: true} | { stillMyUnion: true; } |
| tst.ts:65:49:65:52 | true | true |
| tst.ts:66:13:66:19 | MyUnion | MyUnion |
| tst.ts:68:6:68:13 | MyUnion2 | MyUnion2 |
| tst.ts:68:17:68:23 | MyUnion | MyUnion |
| tst.ts:68:17:68:48 | MyUnion ... : true} | MyUnion \| { yetAnotherType: true; } |
| tst.ts:68:27:68:48 | {yetAno ... : true} | { yetAnotherType: true; } |
| tst.ts:68:44:68:47 | true | true |
| tst.ts:69:13:69:20 | MyUnion2 | MyUnion2 |
| type_alias.ts:1:6:1:6 | B | boolean |
| type_alias.ts:1:10:1:16 | boolean | boolean |
| type_alias.ts:3:8:3:8 | B | boolean |
@@ -304,13 +358,29 @@ referenceDefinition
| Color.red | type_definitions.ts:14:3:14:5 | red |
| E | type_definition_objects.ts:6:8:6:16 | enum E {} |
| EnumWithOneMember | type_definitions.ts:18:26:18:31 | member |
| HasArea | tst.ts:58:1:60:1 | interfa ... mber;\\n} |
| I<S> | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} |
| I<number> | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} |
| Json | type_alias.ts:9:1:15:13 | type Js ... Json[]; |
| MyUnion | tst.ts:65:1:65:54 | type My ... true}; |
| MyUnion2 | tst.ts:68:1:68:49 | type My ... true}; |
| NonAbstractDummy | tst.ts:54:1:56:1 | interfa ... mber;\\n} |
| ValueOrArray<T> | type_alias.ts:5:1:5:50 | type Va ... ay<T>>; |
| ValueOrArray<number> | type_alias.ts:5:1:5:50 | type Va ... ay<T>>; |
| VirtualNode | type_alias.ts:19:1:21:57 | type Vi ... ode[]]; |
tupleTypes
| middle-rest.ts:1:5:1:7 | foo | [boolean, ...string[], number] | 0 | boolean | 2 | string |
| middle-rest.ts:1:5:1:7 | foo | [boolean, ...string[], number] | 1 | string | 2 | string |
| middle-rest.ts:1:5:1:7 | foo | [boolean, ...string[], number] | 2 | number | 2 | string |
| middle-rest.ts:3:1:3:3 | foo | [boolean, ...string[], number] | 0 | boolean | 2 | string |
| middle-rest.ts:3:1:3:3 | foo | [boolean, ...string[], number] | 1 | string | 2 | string |
| middle-rest.ts:3:1:3:3 | foo | [boolean, ...string[], number] | 2 | number | 2 | string |
| middle-rest.ts:3:1:3:26 | foo = [ ... ", 123] | [true, string, number] | 0 | true | 3 | no-rest |
| middle-rest.ts:3:1:3:26 | foo = [ ... ", 123] | [true, string, number] | 1 | string | 3 | no-rest |
| middle-rest.ts:3:1:3:26 | foo = [ ... ", 123] | [true, string, number] | 2 | number | 3 | no-rest |
| middle-rest.ts:3:7:3:26 | [true, "hello", 123] | [boolean, ...string[], number] | 0 | boolean | 2 | string |
| middle-rest.ts:3:7:3:26 | [true, "hello", 123] | [boolean, ...string[], number] | 1 | string | 2 | string |
| middle-rest.ts:3:7:3:26 | [true, "hello", 123] | [boolean, ...string[], number] | 2 | number | 2 | string |
| tst.ts:34:5:34:9 | tuple | [number, string] | 0 | number | 2 | no-rest |
| tst.ts:34:5:34:9 | tuple | [number, string] | 1 | string | 2 | no-rest |
| tst.ts:36:5:36:28 | tupleWi ... Element | [number, string, number?] | 0 | number | 2 | no-rest |
@@ -331,3 +401,50 @@ unknownType
| tst.ts:40:5:40:15 | unknownType | unknown |
| tst.ts:47:8:47:8 | e | unknown |
| tst.ts:48:14:48:14 | e | unknown |
abstractSignature
| (): HasArea |
| new (): HasArea |
unionIndex
| 1 | 0 | 1 \| 2 |
| 2 | 1 | 1 \| 2 |
| "bigint" | 2 | "string" \| "number" \| "bigint" \| "boolean" \| "s... |
| "boolean" | 3 | "string" \| "number" \| "bigint" \| "boolean" \| "s... |
| "function" | 7 | "string" \| "number" \| "bigint" \| "boolean" \| "s... |
| "number" | 1 | "string" \| "number" \| "bigint" \| "boolean" \| "s... |
| "object" | 6 | "string" \| "number" \| "bigint" \| "boolean" \| "s... |
| "string" | 0 | "string" \| "number" \| "bigint" \| "boolean" \| "s... |
| "symbol" | 4 | "string" \| "number" \| "bigint" \| "boolean" \| "s... |
| "undefined" | 5 | "string" \| "number" \| "bigint" \| "boolean" \| "s... |
| Json[] | 5 | string \| number \| boolean \| { [property: string... |
| T | 0 | T \| ValueOrArray<T>[] |
| ValueOrArray<T>[] | 1 | T \| ValueOrArray<T>[] |
| ValueOrArray<number>[] | 1 | number \| ValueOrArray<number>[] |
| [string, { [key: string]: any; }, ...VirtualNod... | 1 | VirtualNode \| { [key: string]: any; } |
| [string, { [key: string]: any; }, ...VirtualNod... | 1 | string \| [string, { [key: string]: any; }, ...V... |
| false | 0 | boolean |
| false | 2 | string \| number \| boolean |
| false | 2 | string \| number \| boolean \| { [property: string... |
| number | 0 | number \| ValueOrArray<number>[] |
| number | 1 | string \| number |
| number | 1 | string \| number \| boolean |
| number | 1 | string \| number \| boolean \| { [property: string... |
| number | 1 | string \| number \| true |
| string | 0 | VirtualNode \| { [key: string]: any; } |
| string | 0 | string \| [string, { [key: string]: any; }, ...V... |
| string | 0 | string \| number |
| string | 0 | string \| number \| boolean |
| string | 0 | string \| number \| boolean \| { [property: string... |
| string | 0 | string \| number \| true |
| string | 0 | string \| { [key: string]: any; } |
| true | 1 | boolean |
| true | 2 | string \| number \| true |
| true | 3 | string \| number \| boolean |
| true | 3 | string \| number \| boolean \| { [property: string... |
| { [key: string]: any; } | 1 | string \| { [key: string]: any; } |
| { [key: string]: any; } | 2 | VirtualNode \| { [key: string]: any; } |
| { [property: string]: Json; } | 4 | string \| number \| boolean \| { [property: string... |
| { myUnion: true; } | 0 | MyUnion \| { yetAnotherType: true; } |
| { myUnion: true; } | 0 | { myUnion: true; } \| { stillMyUnion: true; } |
| { stillMyUnion: true; } | 1 | MyUnion \| { yetAnotherType: true; } |
| { stillMyUnion: true; } | 1 | { myUnion: true; } \| { stillMyUnion: true; } |
| { yetAnotherType: true; } | 2 | MyUnion \| { yetAnotherType: true; } |

View File

@@ -35,3 +35,7 @@ query predicate unknownType(Expr e, Type type) {
type = e.getType() and
e.getType() instanceof UnknownType
}
query CallSignatureType abstractSignature() { result.isAbstract() }
query UnionType unionIndex(Type element, int i) { result.getElementType(i) = element }

View File

@@ -48,4 +48,22 @@ catch (e: unknown) {
if (typeof e === "string") {
let b : string = e;
}
}
}
interface NonAbstractDummy {
getArea(): number;
}
interface HasArea {
getArea(): number;
}
// abstract construct signature!
let Ctor: abstract new () => HasArea = Shape;
type MyUnion = {myUnion: true} | {stillMyUnion: true};
let union1: MyUnion = {myUnion: true};
type MyUnion2 = MyUnion | {yetAnotherType: true};
let union2: MyUnion2 = {yetAnotherType: true};

View File

@@ -76,6 +76,13 @@ test_ClientRequest
| tst.js:229:5:229:67 | needle( ... ptions) |
| tst.js:231:5:233:6 | needle. ... \\n }) |
| tst.js:235:5:237:6 | needle. ... \\n }) |
| tst.js:247:24:247:68 | request ... o.png') |
| tst.js:249:1:251:2 | form.su ... e();\\n}) |
| tst.js:257:1:262:2 | form.su ... rs()\\n}) |
| tst.js:267:1:267:61 | httpPro ... 9000'}) |
| tst.js:269:13:269:48 | httpPro ... ptions) |
| tst.js:271:3:271:61 | proxy.w ... 080' }) |
| tst.js:274:1:283:2 | httpPro ... true\\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 |
@@ -110,12 +117,18 @@ test_getADataNode
| 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" |
| tst.js:249:1:251:2 | form.su ... e();\\n}) | tst.js:245:25:245:34 | 'my value' |
| tst.js:249:1:251:2 | form.su ... e();\\n}) | tst.js:246:26:246:43 | Buffer.from("foo") |
| tst.js:249:1:251:2 | form.su ... e();\\n}) | tst.js:247:24:247:68 | request ... o.png') |
| tst.js:257:1:262:2 | form.su ... rs()\\n}) | tst.js:255:25:255:35 | 'new_value' |
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" |
| tst.js:257:1:262:2 | form.su ... rs()\\n}) | tst.js:259:11:259:23 | 'example.org' |
| tst.js:274:1:283:2 | httpPro ... true\\n}) | tst.js:277:15:277:30 | 'my-domain-name' |
test_getUrl
| apollo.js:5:18:5:78 | new cre ... hql' }) | apollo.js:5:44:5:75 | 'https: ... raphql' |
| apollo.js:10:1:10:54 | new Htt ... hql' }) | apollo.js:10:21:10:51 | 'http:/ ... raphql' |
@@ -199,6 +212,12 @@ test_getUrl
| 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" |
| tst.js:247:24:247:68 | request ... o.png') | tst.js:247:32:247:67 | 'http:/ ... go.png' |
| tst.js:249:1:251:2 | form.su ... e();\\n}) | tst.js:249:13:249:33 | 'http:/ ... e.org/' |
| tst.js:257:1:262:2 | form.su ... rs()\\n}) | tst.js:257:13:262:1 | {\\n m ... ers()\\n} |
| tst.js:267:1:267:61 | httpPro ... 9000'}) | tst.js:267:37:267:59 | 'http:/ ... t:9000' |
| tst.js:271:3:271:61 | proxy.w ... 080' }) | tst.js:271:33:271:58 | 'http:/ ... m:8080' |
| tst.js:274:1:283:2 | httpPro ... true\\n}) | tst.js:275:13:281:5 | {\\n ... ,\\n } |
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 |

View File

@@ -235,4 +235,49 @@ const needle = require("needle");
needle.post("http://example.org/post", "data", options, (err, resp, body) => {
});
})();
})();
var FormData = require('form-data');
var request = require('request');
var form = new FormData();
form.append('my_field', 'my value');
form.append('my_buffer', Buffer.from("foo"));
form.append('my_logo', request('http://example.org/images/logo.png'));
form.submit('http://example.org/', (err, res) => {
res.resume();
});
var form = new FormData();
form.append('new_form', 'new_value');
form.submit({
method: 'post',
host: 'example.org',
path: '/upload',
headers: form.getHeaders()
});
var httpProxy = require('http-proxy');
var http = require("http");
httpProxy.createProxyServer({target:'http://localhost:9000'}).listen(8000);
var proxy = httpProxy.createProxyServer(options);
http.createServer(function(req, res) {
proxy.web(req, res, { target: 'http://mytarget.com:8080' });
});
httpProxy.createProxyServer({
target: {
protocol: 'https:',
host: 'my-domain-name',
port: 443,
pfx: fs.readFileSync('path/to/certificate.p12'),
passphrase: 'password',
},
changeOrigin: true
}).listen(8000);

View File

@@ -73,4 +73,14 @@ http.createServer(function (req, res) {
req.on("data", chunk => { // RemoteFlowSource
res.send(chunk);
})
});
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({});
proxy.on('proxyReq', function(proxyReq, req, res, options) {
req.on("data", chunk => { // RemoteFlowSource
res.send(chunk);
});
res.end("bla");
});

View File

@@ -56,6 +56,9 @@ test_ResponseExpr
| 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/http.js:81:46:81:48 | res | src/http.js:81:22:86:1 | functio ... la");\\n} |
| src/http.js:83:5:83:7 | res | src/http.js:81:22:86:1 | functio ... la");\\n} |
| src/http.js:85:3:85:5 | res | src/http.js:81:22:86:1 | functio ... la");\\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} |
@@ -150,6 +153,9 @@ test_RouteHandler_getAResponseExpr
| 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/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:46:81:48 | res |
| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:83:5:83:7 | res |
| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:85:3:85:5 | 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 |
@@ -189,6 +195,7 @@ 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/http.js:85:11:85:15 | "bla" | src/http.js:81:22:86:1 | functio ... la");\\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 } |
@@ -235,6 +242,7 @@ test_RemoteFlowSources
| 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/http.js:82:18:82: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 |
@@ -273,6 +281,8 @@ test_RequestExpr
| 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/http.js:81:41:81:43 | req | src/http.js:81:22:86:1 | functio ... la");\\n} |
| src/http.js:82:3:82:5 | req | src/http.js:81:22:86:1 | functio ... la");\\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} |
@@ -312,6 +322,8 @@ test_RouteHandler_getARequestExpr
| 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/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:41:81:43 | req |
| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:82:3:82: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 |

View File

@@ -24,6 +24,9 @@
| highlight.js:38:54:38:59 | [^()]* | Strings starting with 'A((' and with many repetitions of ''' can start matching anywhere after the start of the preceeding [^()]* |
| highlight.js:38:64:38:69 | [^()]* | Strings starting with 'A(' and with many repetitions of ''' can start matching anywhere after the start of the preceeding [^()]* |
| highlight.js:39:22:39:24 | \\w* | Strings starting with 'A' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding [a-zA-Z_]\\w*\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{ |
| jsonschema.js:5:15:5:21 | (a?a?)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a?a?)*b |
| jsonschema.js:15:23:15:29 | (a?a?)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a?a?)*b |
| jsonschema.js:20:18:20:24 | (a?a?)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a?a?)*b |
| lib/closure.js:4:6:4:7 | u* | Strings with many repetitions of 'u' can start matching anywhere after the start of the preceeding u*o |
| lib/lib.js:1:15:1:16 | a* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding a*b |
| lib/lib.js:8:3:8:4 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g |

View File

@@ -12,6 +12,9 @@
| highlight.js:30:13:30:25 | (?:\\\\.\|[^`])+ | This part of the regular expression may cause exponential backtracking on strings starting with '`' and containing many repetitions of '\\\\_'. |
| highlight.js:34:25:34:27 | \\w* | This part of the regular expression may cause exponential backtracking on strings starting with '?A' and containing many repetitions of 'A'. |
| highlight.js:38:35:38:40 | [^()]* | This part of the regular expression may cause exponential backtracking on strings starting with 'A((' and containing many repetitions of '')('. |
| jsonschema.js:5:15:5:21 | (a?a?)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'a'. |
| jsonschema.js:15:23:15:29 | (a?a?)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'a'. |
| jsonschema.js:20:18:20:24 | (a?a?)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'a'. |
| polynomial-redos.js:17:5:17:6 | .* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of ','. |
| polynomial-redos.js:41:52:41:63 | [\\x21-\\x7E]* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '?'. |
| polynomial-redos.js:46:33:46:45 | [a-zA-Z_0-9]* | This part of the regular expression may cause exponential backtracking on strings starting with 'A' and containing many repetitions of 'A'. |

View File

@@ -0,0 +1,26 @@
import Ajv from 'ajv';
let thing = {
type: 'string',
pattern: '(a?a?)*b' // NOT OK
}
new Ajv().addSchema(thing, 'thing');
export default {
$schema: "http://json-schema.org/draft-07/schema#",
type: "object",
properties: {
foo: {
type: "string",
pattern: "(a?a?)*b" // NOT OK
},
bar: {
type: "object",
patternProperties: {
"(a?a?)*b": { // NOT OK
type: "number"
}
}
}
}
};

View File

@@ -1,4 +1,7 @@
nodes
| ajv.js:11:18:11:33 | ajv.errorsText() |
| ajv.js:11:18:11:33 | ajv.errorsText() |
| ajv.js:11:18:11:33 | ajv.errorsText() |
| exception-xss.js:2:6:2:28 | foo |
| exception-xss.js:2:12:2:28 | document.location |
| exception-xss.js:2:12:2:28 | document.location |
@@ -87,6 +90,7 @@ nodes
| exception-xss.js:182:19:182:23 | error |
| exception-xss.js:182:19:182:23 | error |
edges
| ajv.js:11:18:11:33 | ajv.errorsText() | ajv.js:11:18:11:33 | ajv.errorsText() |
| exception-xss.js:2:6:2:28 | foo | exception-xss.js:9:11:9:13 | foo |
| exception-xss.js:2:6:2:28 | foo | exception-xss.js:15:9:15:11 | foo |
| exception-xss.js:2:6:2:28 | foo | exception-xss.js:21:11:21:13 | foo |
@@ -169,6 +173,7 @@ edges
| exception-xss.js:180:26:180:30 | error | exception-xss.js:182:19:182:23 | error |
| exception-xss.js:180:26:180:30 | error | exception-xss.js:182:19:182:23 | error |
#select
| ajv.js:11:18:11:33 | ajv.errorsText() | ajv.js:11:18:11:33 | ajv.errorsText() | ajv.js:11:18:11:33 | ajv.errorsText() | $@ is reinterpreted as HTML without escaping meta-characters. | ajv.js:11:18:11:33 | ajv.errorsText() | JSON schema validation error |
| exception-xss.js:11:18:11:18 | e | exception-xss.js:2:12:2:28 | document.location | exception-xss.js:11:18:11:18 | e | $@ is reinterpreted as HTML without escaping meta-characters. | exception-xss.js:2:12:2:28 | document.location | Exception text |
| exception-xss.js:17:18:17:18 | e | exception-xss.js:2:12:2:28 | document.location | exception-xss.js:17:18:17:18 | e | $@ is reinterpreted as HTML without escaping meta-characters. | exception-xss.js:2:12:2:28 | document.location | Exception text |
| exception-xss.js:23:18:23:18 | e | exception-xss.js:2:12:2:28 | document.location | exception-xss.js:23:18:23:18 | e | $@ is reinterpreted as HTML without escaping meta-characters. | exception-xss.js:2:12:2:28 | document.location | Exception text |

View File

@@ -0,0 +1,13 @@
import express from 'express';
import Ajv from 'ajv';
let app = express();
let ajv = new Ajv();
ajv.addSchema({type: 'object', additionalProperties: {type: 'number'}}, 'pollData');
app.post('/polldata', (req, res) => {
if (!ajv.validate('pollData', req.body)) {
res.send(ajv.errorsText()); // NOT OK
}
});

View File

@@ -1,3 +1,7 @@
| json-schema-validator.js:27:13:27:27 | doc.find(query) |
| json-schema-validator.js:30:13:30:27 | doc.find(query) |
| json-schema-validator.js:33:13:33:27 | doc.find(query) |
| json-schema-validator.js:35:9:35:23 | doc.find(query) |
| marsdb-flow-to.js:14:3:14:22 | db.myDoc.find(query) |
| marsdb.js:16:3:16:17 | doc.find(query) |
| minimongo.js:18:3:18:17 | doc.find(query) |

View File

@@ -1,4 +1,12 @@
nodes
| json-schema-validator.js:25:15:25:48 | query |
| json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) |
| json-schema-validator.js:25:34:25:47 | req.query.data |
| json-schema-validator.js:25:34:25:47 | req.query.data |
| json-schema-validator.js:33:22:33:26 | query |
| json-schema-validator.js:33:22:33:26 | query |
| json-schema-validator.js:35:18:35:22 | query |
| json-schema-validator.js:35:18:35:22 | query |
| marsdb-flow-to.js:10:9:10:18 | query |
| marsdb-flow-to.js:10:17:10:18 | {} |
| marsdb-flow-to.js:11:17:11:24 | req.body |
@@ -250,6 +258,13 @@ nodes
| tst.js:10:46:10:58 | req.params.id |
| tst.js:10:46:10:58 | req.params.id |
edges
| json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:33:22:33:26 | query |
| json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:33:22:33:26 | query |
| json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:35:18:35:22 | query |
| json-schema-validator.js:25:15:25:48 | query | json-schema-validator.js:35:18:35:22 | query |
| json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) | json-schema-validator.js:25:15:25:48 | query |
| json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) |
| json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:25:23:25:48 | JSON.pa ... y.data) |
| marsdb-flow-to.js:10:9:10:18 | query | marsdb-flow-to.js:14:17:14:21 | query |
| marsdb-flow-to.js:10:9:10:18 | query | marsdb-flow-to.js:14:17:14:21 | query |
| marsdb-flow-to.js:10:17:10:18 | {} | marsdb-flow-to.js:10:9:10:18 | query |
@@ -586,6 +601,8 @@ edges
| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' |
| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' |
#select
| json-schema-validator.js:33:22:33:26 | query | json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:33:22:33:26 | query | This query depends on $@. | json-schema-validator.js:25:34:25:47 | req.query.data | a user-provided value |
| json-schema-validator.js:35:18:35:22 | query | json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:35:18:35:22 | query | This query depends on $@. | json-schema-validator.js:25:34:25:47 | req.query.data | a user-provided value |
| marsdb-flow-to.js:14:17:14:21 | query | marsdb-flow-to.js:11:17:11:24 | req.body | marsdb-flow-to.js:14:17:14:21 | query | This query depends on $@. | marsdb-flow-to.js:11:17:11:24 | req.body | a user-provided value |
| marsdb.js:16:12:16:16 | query | marsdb.js:13:17:13:24 | req.body | marsdb.js:16:12:16:16 | query | This query depends on $@. | marsdb.js:13:17:13:24 | req.body | a user-provided value |
| minimongo.js:18:12:18:16 | query | minimongo.js:15:17:15:24 | req.body | minimongo.js:18:12:18:16 | query | This query depends on $@. | minimongo.js:15:17:15:24 | req.body | a user-provided value |

View File

@@ -0,0 +1,37 @@
import Ajv from 'ajv';
import express from 'express';
import { MongoClient } from 'mongodb';
const app = express();
const schema = {
type: 'object',
properties: {
date: { type: 'string' },
title: { type: 'string' },
},
};
const ajv = new Ajv();
const checkSchema = ajv.compile(schema);
function validate(x) {
return x != null;
}
app.post('/documents/find', (req, res) => {
MongoClient.connect('mongodb://localhost:27017/test', (err, db) => {
let doc = db.collection('doc');
const query = JSON.parse(req.query.data);
if (checkSchema(query)) {
doc.find(query); // OK
}
if (ajv.validate(schema, query)) {
doc.find(query); // OK
}
if (validate(query)) {
doc.find(query); // NOT OK - validate() doesn't sanitize
}
doc.find(query); // NOT OK
});
});

View File

@@ -0,0 +1,8 @@
nodes
| tst.js:9:29:9:36 | req.body |
| tst.js:9:29:9:36 | req.body |
| tst.js:9:29:9:36 | req.body |
edges
| tst.js:9:29:9:36 | req.body | tst.js:9:29:9:36 | req.body |
#select
| tst.js:9:29:9:36 | req.body | tst.js:9:29:9:36 | req.body | tst.js:9:29:9:36 | req.body | Denial of service caused by processing user input from $@ with $@. | tst.js:9:29:9:36 | req.body | here | tst.js:4:21:4:35 | allErrors: true | allErrors: true |

View File

@@ -0,0 +1 @@
Security/CWE-400/DeepObjectResourceExhaustion.ql

View File

@@ -0,0 +1,12 @@
import express from 'express';
import Ajv from 'ajv';
let ajv = new Ajv({ allErrors: true });
ajv.addSchema(require('./input-schema'), 'input');
var app = express();
app.get('/user/:id', function(req, res) {
if (!ajv.validate('input', req.body)) { // NOT OK
return;
}
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
class TupleType extends @tuple_type {
predicate hasChild(int i) { type_child(_, this, i) }
string toString() { result = "" }
}
from TupleType tuple, int index
where index = max(int i | tuple.hasChild(i))
select tuple, index

View File

@@ -0,0 +1,4 @@
description: add support for TypeScript 4.2
compatibility: backwards
tuple_type_rest_index.rel: run tuple_type_rest_index.qlo
tuple_type_rest.rel: delete