Merge branch 'main' into shared-http-client-request

This commit is contained in:
Rasmus Wriedt Larsen
2022-09-06 10:52:27 +02:00
1425 changed files with 125800 additions and 17882 deletions

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-experimental-atm-lib
version: 0.3.1
version: 0.3.3
extractor: javascript
library: true
groups:

View File

@@ -15,16 +15,16 @@ import extraction.ExtractEndpointData
string getAReasonSinkExcluded(DataFlow::Node sinkCandidate, Query query) {
query instanceof NosqlInjectionQuery and
result = NosqlInjectionATM::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)
result = NosqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)
or
query instanceof SqlInjectionQuery and
result = SqlInjectionATM::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)
result = SqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)
or
query instanceof TaintedPathQuery and
result = TaintedPathATM::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)
result = TaintedPathAtm::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)
or
query instanceof XssQuery and
result = XssATM::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)
result = XssAtm::SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate)
}
pragma[inline]

View File

@@ -5,7 +5,8 @@
* evaluation pipeline.
*/
import semmle.javascript.security.dataflow.NosqlInjection
import javascript
import semmle.javascript.security.dataflow.NosqlInjectionQuery as NosqlInjection
import EndToEndEvaluation as EndToEndEvaluation
from

View File

@@ -5,7 +5,8 @@
* evaluation pipeline.
*/
import semmle.javascript.security.dataflow.SqlInjection
import javascript
import semmle.javascript.security.dataflow.SqlInjectionQuery as SqlInjection
import EndToEndEvaluation as EndToEndEvaluation
from

View File

@@ -5,7 +5,8 @@
* evaluation pipeline.
*/
import semmle.javascript.security.dataflow.TaintedPath
import javascript
import semmle.javascript.security.dataflow.TaintedPathQuery as TaintedPath
import EndToEndEvaluation as EndToEndEvaluation
from

View File

@@ -5,7 +5,8 @@
* pipeline.
*/
import semmle.javascript.security.dataflow.DomBasedXss
import javascript
import semmle.javascript.security.dataflow.DomBasedXssQuery as DomBasedXss
import EndToEndEvaluation as EndToEndEvaluation
from

View File

@@ -14,10 +14,26 @@ import experimental.adaptivethreatmodeling.EndpointFeatures as EndpointFeatures
import experimental.adaptivethreatmodeling.EndpointScoring as EndpointScoring
import experimental.adaptivethreatmodeling.EndpointTypes
import experimental.adaptivethreatmodeling.FilteringReasons
import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionATM
import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionATM
import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathATM
import experimental.adaptivethreatmodeling.XssATM as XssATM
import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm
/** DEPRECATED: Alias for NosqlInjectionAtm */
deprecated module NosqlInjectionATM = NosqlInjectionAtm;
import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm
/** DEPRECATED: Alias for SqlInjectionAtm */
deprecated module SqlInjectionATM = SqlInjectionAtm;
import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm
/** DEPRECATED: Alias for TaintedPathAtm */
deprecated module TaintedPathATM = TaintedPathAtm;
import experimental.adaptivethreatmodeling.XssATM as XssAtm
/** DEPRECATED: Alias for XssAtm */
deprecated module XssATM = XssAtm;
import Labels
import NoFeaturizationRestrictionsConfig
import Queries
@@ -25,13 +41,13 @@ import Queries
/** Gets the ATM configuration object for the specified query. */
AtmConfig getAtmCfg(Query query) {
query instanceof NosqlInjectionQuery and
result instanceof NosqlInjectionATM::NosqlInjectionAtmConfig
result instanceof NosqlInjectionAtm::NosqlInjectionAtmConfig
or
query instanceof SqlInjectionQuery and result instanceof SqlInjectionATM::SqlInjectionAtmConfig
query instanceof SqlInjectionQuery and result instanceof SqlInjectionAtm::SqlInjectionAtmConfig
or
query instanceof TaintedPathQuery and result instanceof TaintedPathATM::TaintedPathAtmConfig
query instanceof TaintedPathQuery and result instanceof TaintedPathAtm::TaintedPathAtmConfig
or
query instanceof XssQuery and result instanceof XssATM::DomBasedXssAtmConfig
query instanceof XssQuery and result instanceof XssAtm::DomBasedXssAtmConfig
}
/** DEPRECATED: Alias for getAtmCfg */
@@ -39,13 +55,13 @@ deprecated ATMConfig getATMCfg(Query query) { result = getAtmCfg(query) }
/** Gets the ATM data flow configuration for the specified query. */
DataFlow::Configuration getDataFlowCfg(Query query) {
query instanceof NosqlInjectionQuery and result instanceof NosqlInjectionATM::Configuration
query instanceof NosqlInjectionQuery and result instanceof NosqlInjectionAtm::Configuration
or
query instanceof SqlInjectionQuery and result instanceof SqlInjectionATM::Configuration
query instanceof SqlInjectionQuery and result instanceof SqlInjectionAtm::Configuration
or
query instanceof TaintedPathQuery and result instanceof TaintedPathATM::Configuration
query instanceof TaintedPathQuery and result instanceof TaintedPathAtm::Configuration
or
query instanceof XssQuery and result instanceof XssATM::Configuration
query instanceof XssQuery and result instanceof XssAtm::Configuration
}
/** Gets a known sink for the specified query. */

View File

@@ -4,25 +4,25 @@
* Maps ML-powered queries to their `EndpointType` for clearer labelling while evaluating ML model during training.
*/
import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionATM
import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionATM
import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathATM
import experimental.adaptivethreatmodeling.XssATM as XssATM
import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm
import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm
import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm
import experimental.adaptivethreatmodeling.XssATM as XssAtm
import experimental.adaptivethreatmodeling.AdaptiveThreatModeling
from string queryName, AtmConfig c, EndpointType e
where
(
queryName = "SqlInjection" and
c instanceof SqlInjectionATM::SqlInjectionAtmConfig
c instanceof SqlInjectionAtm::SqlInjectionAtmConfig
or
queryName = "NosqlInjection" and
c instanceof NosqlInjectionATM::NosqlInjectionAtmConfig
c instanceof NosqlInjectionAtm::NosqlInjectionAtmConfig
or
queryName = "TaintedPath" and
c instanceof TaintedPathATM::TaintedPathAtmConfig
c instanceof TaintedPathAtm::TaintedPathAtmConfig
or
queryName = "Xss" and c instanceof XssATM::DomBasedXssAtmConfig
queryName = "Xss" and c instanceof XssAtm::DomBasedXssAtmConfig
) and
e = c.getASinkEndpointType()
select queryName, e.getEncoding() as label

View File

@@ -1,6 +1,6 @@
name: codeql/javascript-experimental-atm-queries
language: javascript
version: 0.3.1
version: 0.3.3
suites: codeql-suites
defaultSuiteFile: codeql-suites/javascript-atm-code-scanning.qls
groups:

View File

@@ -7,20 +7,20 @@
*/
import javascript
import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionATM
import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionATM
import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathATM
import experimental.adaptivethreatmodeling.XssATM as XssATM
import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm
import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm
import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm
import experimental.adaptivethreatmodeling.XssATM as XssAtm
import experimental.adaptivethreatmodeling.EndpointFeatures as EndpointFeatures
import experimental.adaptivethreatmodeling.StandardEndpointFilters as StandardEndpointFilters
import extraction.NoFeaturizationRestrictionsConfig
query predicate tokenFeatures(DataFlow::Node endpoint, string featureName, string featureValue) {
(
not exists(NosqlInjectionATM::SinkEndpointFilter::getAReasonSinkExcluded(endpoint)) or
not exists(SqlInjectionATM::SinkEndpointFilter::getAReasonSinkExcluded(endpoint)) or
not exists(TaintedPathATM::SinkEndpointFilter::getAReasonSinkExcluded(endpoint)) or
not exists(XssATM::SinkEndpointFilter::getAReasonSinkExcluded(endpoint)) or
not exists(NosqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint)) or
not exists(SqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint)) or
not exists(TaintedPathAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint)) or
not exists(XssAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint)) or
StandardEndpointFilters::isArgumentToModeledFunction(endpoint)
) and
EndpointFeatures::tokenFeatures(endpoint, featureName, featureValue)

View File

@@ -17,31 +17,31 @@ import semmle.javascript.security.dataflow.SqlInjectionCustomizations
import semmle.javascript.security.dataflow.TaintedPathCustomizations
import semmle.javascript.security.dataflow.DomBasedXssCustomizations
import experimental.adaptivethreatmodeling.StandardEndpointFilters as StandardEndpointFilters
import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionATM
import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionATM
import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathATM
import experimental.adaptivethreatmodeling.XssATM as XssATM
import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm
import experimental.adaptivethreatmodeling.SqlInjectionATM as SqlInjectionAtm
import experimental.adaptivethreatmodeling.TaintedPathATM as TaintedPathAtm
import experimental.adaptivethreatmodeling.XssATM as XssAtm
query predicate nosqlFilteredTruePositives(DataFlow::Node endpoint, string reason) {
endpoint instanceof NosqlInjection::Sink and
reason = NosqlInjectionATM::SinkEndpointFilter::getAReasonSinkExcluded(endpoint) and
reason = NosqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint) and
not reason = ["argument to modeled function", "modeled sink", "modeled database access"]
}
query predicate sqlFilteredTruePositives(DataFlow::Node endpoint, string reason) {
endpoint instanceof SqlInjection::Sink and
reason = SqlInjectionATM::SinkEndpointFilter::getAReasonSinkExcluded(endpoint) and
reason = SqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint) and
reason != "argument to modeled function"
}
query predicate taintedPathFilteredTruePositives(DataFlow::Node endpoint, string reason) {
endpoint instanceof TaintedPath::Sink and
reason = TaintedPathATM::SinkEndpointFilter::getAReasonSinkExcluded(endpoint) and
reason = TaintedPathAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint) and
reason != "argument to modeled function"
}
query predicate xssFilteredTruePositives(DataFlow::Node endpoint, string reason) {
endpoint instanceof DomBasedXss::Sink and
reason = XssATM::SinkEndpointFilter::getAReasonSinkExcluded(endpoint) and
reason = XssAtm::SinkEndpointFilter::getAReasonSinkExcluded(endpoint) and
reason != "argument to modeled function"
}

View File

@@ -1,6 +1,6 @@
import javascript
import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionATM
import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm
query predicate effectiveSinks(DataFlow::Node node) {
not exists(NosqlInjectionATM::SinkEndpointFilter::getAReasonSinkExcluded(node))
not exists(NosqlInjectionAtm::SinkEndpointFilter::getAReasonSinkExcluded(node))
}

View File

@@ -1,3 +1,20 @@
## 0.2.4
### Deprecated APIs
* Many classes/predicates/modules with upper-case acronyms in their name have been renamed to follow our style-guide.
The old name still exists as a deprecated alias.
* The utility files previously in the `semmle.javascript.security.performance` package have been moved to the `semmle.javascript.security.regexp` package.
The previous files still exist as deprecated aliases.
### Minor Analysis Improvements
* Most deprecated predicates/classes/modules that have been deprecated for over a year have been deleted.
### Bug Fixes
* Fixed that top-level `for await` statements would produce a syntax error. These statements are now parsed correctly.
## 0.2.3
## 0.2.2

View File

@@ -0,0 +1,4 @@
---
category: majorAnalysis
---
* Added support for TypeScript 4.8.

View File

@@ -1,5 +0,0 @@
---
category: deprecated
---
* The utility files previously in the `semmle.javascript.security.performance` package have been moved to the `semmle.javascript.security.regexp` package.
The previous files still exist as deprecated aliases.

View File

@@ -1,4 +0,0 @@
---
category: fix
---
* Fixed that top-level `for await` statements would produce a syntax error. These statements are now parsed correctly.

View File

@@ -1,6 +0,0 @@
---
category: minorAnalysis
---
* Most deprecated predicates/classes/modules that have been deprecated for over a year have been
deleted.

View File

@@ -0,0 +1,16 @@
## 0.2.4
### Deprecated APIs
* Many classes/predicates/modules with upper-case acronyms in their name have been renamed to follow our style-guide.
The old name still exists as a deprecated alias.
* The utility files previously in the `semmle.javascript.security.performance` package have been moved to the `semmle.javascript.security.regexp` package.
The previous files still exist as deprecated aliases.
### Minor Analysis Improvements
* Most deprecated predicates/classes/modules that have been deprecated for over a year have been deleted.
### Bug Fixes
* Fixed that top-level `for await` statements would produce a syntax error. These statements are now parsed correctly.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.3
lastReleaseVersion: 0.2.4

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-all
version: 0.2.4-dev
version: 0.2.5-dev
groups: javascript
dbscheme: semmlecode.javascript.dbscheme
extractor: javascript

View File

@@ -11,7 +11,7 @@ import javascript
*/
module Actions {
/** A YAML node in a GitHub Actions workflow file. */
private class Node extends YAMLNode {
private class Node extends YamlNode {
Node() {
this.getLocation()
.getFile()
@@ -24,12 +24,12 @@ module Actions {
* An Actions workflow. This is a mapping at the top level of an Actions YAML workflow file.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions.
*/
class Workflow extends Node, YAMLDocument, YAMLMapping {
class Workflow extends Node, YamlDocument, YamlMapping {
/** Gets the `jobs` mapping from job IDs to job definitions in this workflow. */
YAMLMapping getJobs() { result = this.lookup("jobs") }
YamlMapping getJobs() { result = this.lookup("jobs") }
/** Gets the name of the workflow. */
string getName() { result = this.lookup("name").(YAMLString).getValue() }
string getName() { result = this.lookup("name").(YamlString).getValue() }
/** Gets the name of the workflow file. */
string getFileName() { result = this.getFile().getBaseName() }
@@ -45,7 +45,7 @@ module Actions {
* An Actions On trigger within a workflow.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#on.
*/
class On extends YAMLNode, YAMLMappingLikeNode {
class On extends YamlNode, YamlMappingLikeNode {
Workflow workflow;
On() { workflow.lookup("on") = this }
@@ -58,7 +58,7 @@ module Actions {
* An Actions job within a workflow.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobs.
*/
class Job extends YAMLNode, YAMLMapping {
class Job extends YamlNode, YamlMapping {
string jobId;
Workflow workflow;
@@ -74,19 +74,19 @@ module Actions {
* Gets the ID of this job, as a YAML scalar node.
* This is the job's key within the `jobs` mapping.
*/
YAMLString getIdNode() { workflow.getJobs().maps(result, this) }
YamlString getIdNode() { workflow.getJobs().maps(result, this) }
/** Gets the human-readable name of this job, if any, as a string. */
string getName() { result = this.getNameNode().getValue() }
/** Gets the human-readable name of this job, if any, as a YAML scalar node. */
YAMLString getNameNode() { result = this.lookup("name") }
YamlString getNameNode() { result = this.lookup("name") }
/** Gets the step at the given index within this job. */
Step getStep(int index) { result.getJob() = this and result.getIndex() = index }
/** Gets the sequence of `steps` within this job. */
YAMLSequence getSteps() { result = this.lookup("steps") }
YamlSequence getSteps() { result = this.lookup("steps") }
/** Gets the workflow this job belongs to. */
Workflow getWorkflow() { result = workflow }
@@ -99,7 +99,7 @@ module Actions {
* An `if` within a job.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idif.
*/
class JobIf extends YAMLNode, YAMLScalar {
class JobIf extends YamlNode, YamlScalar {
Job job;
JobIf() { job.lookup("if") = this }
@@ -112,7 +112,7 @@ module Actions {
* A step within an Actions job.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idsteps.
*/
class Step extends YAMLNode, YAMLMapping {
class Step extends YamlNode, YamlMapping {
int index;
Job job;
@@ -134,14 +134,14 @@ module Actions {
StepIf getIf() { result.getStep() = this }
/** Gets the ID of this step, if any. */
string getId() { result = this.lookup("id").(YAMLString).getValue() }
string getId() { result = this.lookup("id").(YamlString).getValue() }
}
/**
* An `if` within a step.
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsif.
*/
class StepIf extends YAMLNode, YAMLScalar {
class StepIf extends YamlNode, YamlScalar {
Step step;
StepIf() { step.lookup("if") = this }
@@ -170,7 +170,7 @@ module Actions {
*
* Does not handle local repository references, e.g. `.github/actions/action-name`.
*/
class Uses extends YAMLNode, YAMLScalar {
class Uses extends YamlNode, YamlScalar {
Step step;
Uses() { step.lookup("uses") = this }
@@ -200,7 +200,7 @@ module Actions {
* arg2: abc
* ```
*/
class With extends YAMLNode, YAMLMapping {
class With extends YamlNode, YamlMapping {
Step step;
With() { step.lookup("with") = this }
@@ -219,7 +219,7 @@ module Actions {
* ref: ${{ github.event.pull_request.head.sha }}
* ```
*/
class Ref extends YAMLNode, YAMLString {
class Ref extends YamlNode, YamlString {
With with;
Ref() { with.lookup("ref") = this }
@@ -232,7 +232,7 @@ module Actions {
* A `run` field within an Actions job step, which runs command-line programs using an operating system shell.
* See https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsrun.
*/
class Run extends YAMLNode, YAMLString {
class Run extends YamlNode, YamlString {
Step step;
Run() { step.lookup("run") = this }

View File

@@ -533,8 +533,9 @@ module API {
/** Gets a node corresponding to an import of module `m`. */
Node moduleImport(string m) {
result = Impl::MkModuleImport(m) or
result = Impl::MkModuleImport(m).(Node).getMember("default")
result = Internal::getAModuleImportRaw(m)
or
result = ModelOutput::getATypeNode(m, "")
}
/** Gets a node corresponding to an export of module `m`. */
@@ -544,6 +545,22 @@ module API {
module Node {
/** Gets a node whose type has the given qualified name. */
Node ofType(string moduleName, string exportedName) {
result = Internal::getANodeOfTypeRaw(moduleName, exportedName)
or
result = ModelOutput::getATypeNode(moduleName, exportedName)
}
}
/** Provides access to API graph nodes without taking into account types from models. */
module Internal {
/** Gets a node corresponding to an import of module `m` without taking into account types from models. */
Node getAModuleImportRaw(string m) {
result = Impl::MkModuleImport(m) or
result = Impl::MkModuleImport(m).(Node).getMember("default")
}
/** Gets a node whose type has the given qualified name, not including types from models. */
Node getANodeOfTypeRaw(string moduleName, string exportedName) {
result = Impl::MkTypeUse(moduleName, exportedName).(Node).getInstance()
}
}
@@ -646,7 +663,14 @@ module API {
or
any(Type t).hasUnderlyingType(m, _)
} or
MkClassInstance(DataFlow::ClassNode cls) { cls = trackDefNode(_) and hasSemantics(cls) } or
MkClassInstance(DataFlow::ClassNode cls) {
hasSemantics(cls) and
(
cls = trackDefNode(_)
or
cls.getAnInstanceReference() = trackDefNode(_)
)
} or
MkAsyncFuncResult(DataFlow::FunctionNode f) {
f = trackDefNode(_) and f.getFunction().isAsync() and hasSemantics(f)
} or
@@ -738,16 +762,6 @@ module API {
.getStaticMember(name, DataFlow::MemberKind::getter())
.getAReturn()
)
or
// If `new C()` escapes, generate edges to its instance members
exists(DataFlow::ClassNode cls, string name |
pred = cls.getAClassReference().getAnInstantiation() and
lbl = Label::member(name)
|
rhs = cls.getInstanceMethod(name)
or
rhs = cls.getInstanceMember(name, DataFlow::MemberKind::getter()).getAReturn()
)
)
or
exists(DataFlow::ClassNode cls, string name |
@@ -1236,9 +1250,13 @@ module API {
succ = MkUse(ref)
)
or
exists(DataFlow::Node rhs |
rhs(pred, lbl, rhs) and
exists(DataFlow::Node rhs | rhs(pred, lbl, rhs) |
succ = MkDef(rhs)
or
exists(DataFlow::ClassNode cls |
cls.getAnInstanceReference() = rhs and
succ = MkClassInstance(cls)
)
)
or
exists(DataFlow::Node def |

View File

@@ -261,14 +261,12 @@ private module ArrayDataFlow {
/**
* A step for creating an array and storing the elements in the array.
*/
private class ArrayCreationStep extends DataFlow::SharedFlowStep {
private class ArrayCreationStep extends PreCallGraphStep {
override predicate storeStep(DataFlow::Node element, DataFlow::SourceNode obj, string prop) {
exists(DataFlow::ArrayCreationNode array, int i |
element = array.getElement(i) and
obj = array and
if array = any(PromiseAllCreation c).getArrayNode()
then prop = arrayElement(i)
else prop = arrayElement()
prop = arrayElement(i)
)
}
}
@@ -346,6 +344,14 @@ private module ArrayLibraries {
result = DataFlow::globalVarRef("Array").getAMemberCall("from")
or
result = DataFlow::moduleImport("array-from").getACall()
or
// Array.prototype.slice.call acts the same as Array.from, and is sometimes used with e.g. the arguments object.
result =
DataFlow::globalVarRef("Array")
.getAPropertyRead("prototype")
.getAPropertyRead("slice")
.getAMethodCall("call") and
result.getNumArgument() = 1
}
/**

View File

@@ -493,6 +493,9 @@ class MemberDeclaration extends @property, Documentable {
*/
predicate isStatic() { is_static(this) }
/** Gets a boolean indicating if this member is static. */
boolean getStaticAsBool() { if this.isStatic() then result = true else result = false }
/**
* Holds if this member is abstract.
*
@@ -694,10 +697,10 @@ class MethodDeclaration extends MemberDeclaration {
* the overload index is defined as if only one of them was concrete.
*/
int getOverloadIndex() {
exists(ClassOrInterface type, string name |
exists(ClassOrInterface type, string name, boolean static |
this =
rank[result + 1](MethodDeclaration method, int i |
methodDeclaredInType(type, name, i, method)
methodDeclaredInType(type, name, static, i, method)
|
method order by i
)
@@ -718,10 +721,11 @@ class MethodDeclaration extends MemberDeclaration {
* Holds if the `index`th member of `type` is `method`, which has the given `name`.
*/
private predicate methodDeclaredInType(
ClassOrInterface type, string name, int index, MethodDeclaration method
ClassOrInterface type, string name, boolean static, int index, MethodDeclaration method
) {
not method instanceof ConstructorDeclaration and // distinguish methods named "constructor" from the constructor
type.getMemberByIndex(index) = method and
static = method.getStaticAsBool() and
method.getName() = name
}

View File

@@ -178,7 +178,7 @@ predicate isGeneratedFileName(File f) {
predicate isGenerated(TopLevel tl) {
tl.isMinified() or
isBundle(tl) or
tl instanceof GWTGeneratedTopLevel or
tl instanceof GwtGeneratedTopLevel or
tl instanceof DartGeneratedTopLevel or
exists(GeneratedCodeMarkerComment gcmc | tl = gcmc.getTopLevel()) or
hasManyInvocations(tl) or

View File

@@ -43,7 +43,7 @@ class JsonStringifyCall extends DataFlow::CallNode {
/**
* A taint step through the [`json2csv`](https://www.npmjs.com/package/json2csv) library.
*/
class JSON2CSVTaintStep extends TaintTracking::SharedTaintStep {
class Json2CsvTaintStep extends TaintTracking::SharedTaintStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(API::CallNode call |
call =
@@ -59,6 +59,9 @@ class JSON2CSVTaintStep extends TaintTracking::SharedTaintStep {
}
}
/** DEPRECATED: Alias for Json2CsvTaintStep */
deprecated class JSON2CSVTaintStep = Json2CsvTaintStep;
/**
* A step through the [`prettyjson`](https://www.npmjs.com/package/prettyjson) library.
* This is not quite a `JSON.stringify` call, as it e.g. does not wrap keys in double quotes.

View File

@@ -168,18 +168,24 @@ class PackageJson extends JsonObject {
JsonArray getCPUs() { result = this.getPropValue("cpu") }
/** Gets a platform supported by this package. */
string getWhitelistedCPU() {
string getWhitelistedCpu() {
result = this.getCPUs().getElementStringValue(_) and
not result.matches("!%")
}
/** DEPRECATED: Alias for getWhitelistedCpu */
deprecated string getWhitelistedCPU() { result = this.getWhitelistedCpu() }
/** Gets a platform not supported by this package. */
string getBlacklistedCPU() {
string getBlacklistedCpu() {
exists(string str | str = this.getCPUs().getElementStringValue(_) |
result = str.regexpCapture("!(.*)", 1)
)
}
/** DEPRECATED: Alias for getBlacklistedCpu */
deprecated string getBlacklistedCPU() { result = this.getBlacklistedCpu() }
/** Holds if this package prefers to be installed globally. */
predicate isPreferGlobal() { this.getPropValue("preferGlobal").(JsonBoolean).getValue() = "true" }

View File

@@ -11,36 +11,14 @@ private import semmle.javascript.internal.CachedStages
* Gets a parameter that is a library input to a top-level package.
*/
cached
DataFlow::SourceNode getALibraryInputParameter() {
DataFlow::Node getALibraryInputParameter() {
Stages::Taint::ref() and
exists(int bound, DataFlow::FunctionNode func |
func = getAValueExportedByPackage().getABoundFunctionValue(bound)
|
result = func.getParameter(any(int arg | arg >= bound))
or
result = getAnArgumentsRead(func.getFunction())
)
}
private DataFlow::SourceNode getAnArgumentsRead(Function func) {
exists(DataFlow::PropRead read |
not read.getPropertyName() = "length" and
result = read
|
read.getBase() = func.getArgumentsVariable().getAnAccess().flow()
or
exists(DataFlow::MethodCallNode call |
call =
DataFlow::globalVarRef("Array")
.getAPropertyRead("prototype")
.getAPropertyRead("slice")
.getAMethodCall("call")
or
call = DataFlow::globalVarRef("Array").getAMethodCall("from")
|
call.getArgument(0) = func.getArgumentsVariable().getAnAccess().flow() and
call.flowsTo(read.getBase())
)
result = func.getFunction().getArgumentsVariable().getAnAccess().flow()
)
}

View File

@@ -64,8 +64,8 @@ private newtype TPrintAstNode =
// JSON
TJsonNode(JsonValue value) { shouldPrint(value, _) and not isNotNeeded(value) } or
// YAML
TYamlNode(YAMLNode n) { shouldPrint(n, _) and not isNotNeeded(n) } or
TYamlMappingNode(YAMLMapping mapping, int i) {
TYamlNode(YamlNode n) { shouldPrint(n, _) and not isNotNeeded(n) } or
TYamlMappingNode(YamlMapping mapping, int i) {
shouldPrint(mapping, _) and not isNotNeeded(mapping) and exists(mapping.getKeyNode(i))
} or
// HTML
@@ -628,7 +628,7 @@ module PrintYaml {
* A print node representing a YAML value in a .yml file.
*/
class YamlNodeNode extends PrintAstNode, TYamlNode {
YAMLNode node;
YamlNode node;
YamlNodeNode() { this = TYamlNode(node) }
@@ -639,10 +639,10 @@ module PrintYaml {
/**
* Gets the `YAMLNode` represented by this node.
*/
final YAMLNode getValue() { result = node }
final YamlNode getValue() { result = node }
override PrintAstNode getChild(int childIndex) {
exists(YAMLNode child | result.(YamlNodeNode).getValue() = child |
exists(YamlNode child | result.(YamlNodeNode).getValue() = child |
child = node.getChildNode(childIndex)
)
}
@@ -657,7 +657,7 @@ module PrintYaml {
* Each child of this node aggregates the key and value of a mapping.
*/
class YamlMappingNode extends YamlNodeNode {
override YAMLMapping node;
override YamlMapping node;
override PrintAstNode getChild(int childIndex) {
exists(YamlMappingMapNode map | map = result | map.maps(node, childIndex))
@@ -671,21 +671,21 @@ module PrintYaml {
* A print node representing the `i`th mapping in `mapping`.
*/
class YamlMappingMapNode extends PrintAstNode, TYamlMappingNode {
YAMLMapping mapping;
YamlMapping mapping;
int i;
YamlMappingMapNode() { this = TYamlMappingNode(mapping, i) }
override string toString() {
result = "(Mapping " + i + ")" and not exists(mapping.getKeyNode(i).(YAMLScalar).getValue())
result = "(Mapping " + i + ")" and not exists(mapping.getKeyNode(i).(YamlScalar).getValue())
or
result = "(Mapping " + i + ") " + mapping.getKeyNode(i).(YAMLScalar).getValue() + ":"
result = "(Mapping " + i + ") " + mapping.getKeyNode(i).(YamlScalar).getValue() + ":"
}
/**
* Holds if this print node represents the `index`th mapping of `m`.
*/
predicate maps(YAMLMapping m, int index) {
predicate maps(YamlMapping m, int index) {
m = mapping and
index = i
}

View File

@@ -1005,7 +1005,10 @@ module RegExpPatterns {
* Gets a pattern that matches common top-level domain names in lower case.
* DEPRECATED: use `getACommonTld` instead
*/
deprecated predicate commonTLD = getACommonTld/0;
deprecated predicate commonTld = getACommonTld/0;
/** DEPRECATED: Alias for commonTld */
deprecated predicate commonTLD = commonTld/0;
}
/**

View File

@@ -291,10 +291,13 @@ class StrictModeDecl extends KnownDirective {
* "use asm";
* ```
*/
class ASMJSDirective extends KnownDirective {
ASMJSDirective() { this.getDirectiveText() = "use asm" }
class AsmJSDirective extends KnownDirective {
AsmJSDirective() { this.getDirectiveText() = "use asm" }
}
/** DEPRECATED: Alias for AsmJSDirective */
deprecated class ASMJSDirective = AsmJSDirective;
/**
* A Babel directive.
*

107
javascript/ql/lib/semmle/javascript/XML.qll Executable file → Normal file
View File

@@ -8,7 +8,7 @@ private class TXmlLocatable =
@xmldtd or @xmlelement or @xmlattribute or @xmlnamespace or @xmlcomment or @xmlcharacters;
/** An XML element that has a location. */
class XMLLocatable extends @xmllocatable, TXmlLocatable {
class XmlLocatable extends @xmllocatable, TXmlLocatable {
/** Gets the source location for this element. */
Location getLocation() { xmllocations(this, result) }
@@ -32,13 +32,16 @@ class XMLLocatable extends @xmllocatable, TXmlLocatable {
string toString() { none() } // overridden in subclasses
}
/** DEPRECATED: Alias for XmlLocatable */
deprecated class XMLLocatable = XmlLocatable;
/**
* An `XMLParent` is either an `XMLElement` or an `XMLFile`,
* An `XmlParent` is either an `XmlElement` or an `XmlFile`,
* both of which can contain other elements.
*/
class XMLParent extends @xmlparent {
XMLParent() {
// explicitly restrict `this` to be either an `XMLElement` or an `XMLFile`;
class XmlParent extends @xmlparent {
XmlParent() {
// explicitly restrict `this` to be either an `XmlElement` or an `XmlFile`;
// the type `@xmlparent` currently also includes non-XML files
this instanceof @xmlelement or xmlEncoding(this, _)
}
@@ -50,28 +53,28 @@ class XMLParent extends @xmlparent {
string getName() { none() } // overridden in subclasses
/** Gets the file to which this XML parent belongs. */
XMLFile getFile() { result = this or xmlElements(this, _, _, _, result) }
XmlFile getFile() { result = this or xmlElements(this, _, _, _, result) }
/** Gets the child element at a specified index of this XML parent. */
XMLElement getChild(int index) { xmlElements(result, _, this, index, _) }
XmlElement getChild(int index) { xmlElements(result, _, this, index, _) }
/** Gets a child element of this XML parent. */
XMLElement getAChild() { xmlElements(result, _, this, _, _) }
XmlElement getAChild() { xmlElements(result, _, this, _, _) }
/** Gets a child element of this XML parent with the given `name`. */
XMLElement getAChild(string name) { xmlElements(result, _, this, _, _) and result.hasName(name) }
XmlElement getAChild(string name) { xmlElements(result, _, this, _, _) and result.hasName(name) }
/** Gets a comment that is a child of this XML parent. */
XMLComment getAComment() { xmlComments(result, _, this, _) }
XmlComment getAComment() { xmlComments(result, _, this, _) }
/** Gets a character sequence that is a child of this XML parent. */
XMLCharacters getACharactersSet() { xmlChars(result, _, this, _, _, _) }
XmlCharacters getACharactersSet() { xmlChars(result, _, this, _, _, _) }
/** Gets the depth in the tree. (Overridden in XMLElement.) */
/** Gets the depth in the tree. (Overridden in XmlElement.) */
int getDepth() { result = 0 }
/** Gets the number of child XML elements of this XML parent. */
int getNumberOfChildren() { result = count(XMLElement e | xmlElements(e, _, this, _, _)) }
int getNumberOfChildren() { result = count(XmlElement e | xmlElements(e, _, this, _, _)) }
/** Gets the number of places in the body of this XML parent where text occurs. */
int getNumberOfCharacterSets() { result = count(int pos | xmlChars(_, _, this, pos, _, _)) }
@@ -92,9 +95,12 @@ class XMLParent extends @xmlparent {
string toString() { result = this.getName() }
}
/** DEPRECATED: Alias for XmlParent */
deprecated class XMLParent = XmlParent;
/** An XML file. */
class XMLFile extends XMLParent, File {
XMLFile() { xmlEncoding(this, _) }
class XmlFile extends XmlParent, File {
XmlFile() { xmlEncoding(this, _) }
/** Gets a printable representation of this XML file. */
override string toString() { result = this.getName() }
@@ -120,15 +126,21 @@ class XMLFile extends XMLParent, File {
string getEncoding() { xmlEncoding(this, result) }
/** Gets the XML file itself. */
override XMLFile getFile() { result = this }
override XmlFile getFile() { result = this }
/** Gets a top-most element in an XML file. */
XMLElement getARootElement() { result = this.getAChild() }
XmlElement getARootElement() { result = this.getAChild() }
/** Gets a DTD associated with this XML file. */
XMLDTD getADTD() { xmlDTDs(result, _, _, _, this) }
XmlDtd getADtd() { xmlDTDs(result, _, _, _, this) }
/** DEPRECATED: Alias for getADtd */
deprecated XmlDtd getADTD() { result = this.getADtd() }
}
/** DEPRECATED: Alias for XmlFile */
deprecated class XMLFile = XmlFile;
/**
* An XML document type definition (DTD).
*
@@ -140,7 +152,7 @@ class XMLFile extends XMLParent, File {
* <!ELEMENT lastName (#PCDATA)>
* ```
*/
class XMLDTD extends XMLLocatable, @xmldtd {
class XmlDtd extends XmlLocatable, @xmldtd {
/** Gets the name of the root element of this DTD. */
string getRoot() { xmlDTDs(this, result, _, _, _) }
@@ -154,7 +166,7 @@ class XMLDTD extends XMLLocatable, @xmldtd {
predicate isPublic() { not xmlDTDs(this, _, "", _, _) }
/** Gets the parent of this DTD. */
XMLParent getParent() { xmlDTDs(this, _, _, _, result) }
XmlParent getParent() { xmlDTDs(this, _, _, _, result) }
override string toString() {
this.isPublic() and
@@ -165,6 +177,9 @@ class XMLDTD extends XMLLocatable, @xmldtd {
}
}
/** DEPRECATED: Alias for XmlDtd */
deprecated class XMLDTD = XmlDtd;
/**
* An XML element in an XML file.
*
@@ -176,7 +191,7 @@ class XMLDTD extends XMLLocatable, @xmldtd {
* </manifest>
* ```
*/
class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
class XmlElement extends @xmlelement, XmlParent, XmlLocatable {
/** Holds if this XML element has the given `name`. */
predicate hasName(string name) { name = this.getName() }
@@ -184,10 +199,10 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
override string getName() { xmlElements(this, result, _, _, _) }
/** Gets the XML file in which this XML element occurs. */
override XMLFile getFile() { xmlElements(this, _, _, _, result) }
override XmlFile getFile() { xmlElements(this, _, _, _, result) }
/** Gets the parent of this XML element. */
XMLParent getParent() { xmlElements(this, _, result, _, _) }
XmlParent getParent() { xmlElements(this, _, result, _, _) }
/** Gets the index of this XML element among its parent's children. */
int getIndex() { xmlElements(this, _, _, result, _) }
@@ -196,7 +211,7 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
predicate hasNamespace() { xmlHasNs(this, _, _) }
/** Gets the namespace of this XML element, if any. */
XMLNamespace getNamespace() { xmlHasNs(this, result, _) }
XmlNamespace getNamespace() { xmlHasNs(this, result, _) }
/** Gets the index of this XML element among its parent's children. */
int getElementPositionIndex() { xmlElements(this, _, _, result, _) }
@@ -205,10 +220,10 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
override int getDepth() { result = this.getParent().getDepth() + 1 }
/** Gets an XML attribute of this XML element. */
XMLAttribute getAnAttribute() { result.getElement() = this }
XmlAttribute getAnAttribute() { result.getElement() = this }
/** Gets the attribute with the specified `name`, if any. */
XMLAttribute getAttribute(string name) { result.getElement() = this and result.getName() = name }
XmlAttribute getAttribute(string name) { result.getElement() = this and result.getName() = name }
/** Holds if this XML element has an attribute with the specified `name`. */
predicate hasAttribute(string name) { exists(this.getAttribute(name)) }
@@ -220,6 +235,9 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
override string toString() { result = this.getName() }
}
/** DEPRECATED: Alias for XmlElement */
deprecated class XMLElement = XmlElement;
/**
* An attribute that occurs inside an XML element.
*
@@ -230,18 +248,18 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
* android:versionCode="1"
* ```
*/
class XMLAttribute extends @xmlattribute, XMLLocatable {
class XmlAttribute extends @xmlattribute, XmlLocatable {
/** Gets the name of this attribute. */
string getName() { xmlAttrs(this, _, result, _, _, _) }
/** Gets the XML element to which this attribute belongs. */
XMLElement getElement() { xmlAttrs(this, result, _, _, _, _) }
XmlElement getElement() { xmlAttrs(this, result, _, _, _, _) }
/** Holds if this attribute has a namespace. */
predicate hasNamespace() { xmlHasNs(this, _, _) }
/** Gets the namespace of this attribute, if any. */
XMLNamespace getNamespace() { xmlHasNs(this, result, _) }
XmlNamespace getNamespace() { xmlHasNs(this, result, _) }
/** Gets the value of this attribute. */
string getValue() { xmlAttrs(this, _, _, result, _, _) }
@@ -250,6 +268,9 @@ class XMLAttribute extends @xmlattribute, XMLLocatable {
override string toString() { result = this.getName() + "=" + this.getValue() }
}
/** DEPRECATED: Alias for XmlAttribute */
deprecated class XMLAttribute = XmlAttribute;
/**
* A namespace used in an XML file.
*
@@ -259,23 +280,29 @@ class XMLAttribute extends @xmlattribute, XMLLocatable {
* xmlns:android="http://schemas.android.com/apk/res/android"
* ```
*/
class XMLNamespace extends XMLLocatable, @xmlnamespace {
class XmlNamespace extends XmlLocatable, @xmlnamespace {
/** Gets the prefix of this namespace. */
string getPrefix() { xmlNs(this, result, _, _) }
/** Gets the URI of this namespace. */
string getURI() { xmlNs(this, _, result, _) }
string getUri() { xmlNs(this, _, result, _) }
/** DEPRECATED: Alias for getUri */
deprecated string getURI() { result = this.getUri() }
/** Holds if this namespace has no prefix. */
predicate isDefault() { this.getPrefix() = "" }
override string toString() {
this.isDefault() and result = this.getURI()
this.isDefault() and result = this.getUri()
or
not this.isDefault() and result = this.getPrefix() + ":" + this.getURI()
not this.isDefault() and result = this.getPrefix() + ":" + this.getUri()
}
}
/** DEPRECATED: Alias for XmlNamespace */
deprecated class XMLNamespace = XmlNamespace;
/**
* A comment in an XML file.
*
@@ -285,17 +312,20 @@ class XMLNamespace extends XMLLocatable, @xmlnamespace {
* <!-- This is a comment. -->
* ```
*/
class XMLComment extends @xmlcomment, XMLLocatable {
class XmlComment extends @xmlcomment, XmlLocatable {
/** Gets the text content of this XML comment. */
string getText() { xmlComments(this, result, _, _) }
/** Gets the parent of this XML comment. */
XMLParent getParent() { xmlComments(this, _, result, _) }
XmlParent getParent() { xmlComments(this, _, result, _) }
/** Gets a printable representation of this XML comment. */
override string toString() { result = this.getText() }
}
/** DEPRECATED: Alias for XmlComment */
deprecated class XMLComment = XmlComment;
/**
* A sequence of characters that occurs between opening and
* closing tags of an XML element, excluding other elements.
@@ -306,12 +336,12 @@ class XMLComment extends @xmlcomment, XMLLocatable {
* <content>This is a sequence of characters.</content>
* ```
*/
class XMLCharacters extends @xmlcharacters, XMLLocatable {
class XmlCharacters extends @xmlcharacters, XmlLocatable {
/** Gets the content of this character sequence. */
string getCharacters() { xmlChars(this, result, _, _, _, _) }
/** Gets the parent of this character sequence. */
XMLParent getParent() { xmlChars(this, _, result, _, _, _) }
XmlParent getParent() { xmlChars(this, _, result, _, _, _) }
/** Holds if this character sequence is CDATA. */
predicate isCDATA() { xmlChars(this, _, _, _, 1, _) }
@@ -319,3 +349,6 @@ class XMLCharacters extends @xmlcharacters, XMLLocatable {
/** Gets a printable representation of this XML character sequence. */
override string toString() { result = this.getCharacters() }
}
/** DEPRECATED: Alias for XmlCharacters */
deprecated class XMLCharacters = XmlCharacters;

View File

@@ -20,13 +20,13 @@ import javascript
* << : *DEFAULTS # an alias node referring to anchor `DEFAULTS`
* ```
*/
class YAMLNode extends @yaml_node, Locatable {
class YamlNode extends @yaml_node, Locatable {
override Location getLocation() { yaml_locations(this, result) }
/**
* Gets the parent node of this node, which is always a collection.
*/
YAMLCollection getParentNode() { yaml(this, _, result, _, _, _) }
YamlCollection getParentNode() { yaml(this, _, result, _, _, _) }
/**
* Gets the `i`th child node of this node.
@@ -34,12 +34,12 @@ class YAMLNode extends @yaml_node, Locatable {
* _Note_: The index of a child node relative to its parent is considered
* an implementation detail and may change between versions of the extractor.
*/
YAMLNode getChildNode(int i) { yaml(result, _, this, i, _, _) }
YamlNode getChildNode(int i) { yaml(result, _, this, i, _, _) }
/**
* Gets a child node of this node.
*/
YAMLNode getAChildNode() { result = this.getChildNode(_) }
YamlNode getAChildNode() { result = this.getChildNode(_) }
/**
* Gets the number of child nodes of this node.
@@ -49,12 +49,12 @@ class YAMLNode extends @yaml_node, Locatable {
/**
* Gets the `i`th child of this node, as a YAML value.
*/
YAMLValue getChild(int i) { result = this.getChildNode(i).eval() }
YamlValue getChild(int i) { result = this.getChildNode(i).eval() }
/**
* Gets a child of this node, as a YAML value.
*/
YAMLValue getAChild() { result = this.getChild(_) }
YamlValue getAChild() { result = this.getChild(_) }
/**
* Gets the tag of this node.
@@ -79,16 +79,19 @@ class YAMLNode extends @yaml_node, Locatable {
/**
* Gets the toplevel document to which this node belongs.
*/
YAMLDocument getDocument() { result = this.getParentNode*() }
YamlDocument getDocument() { result = this.getParentNode*() }
/**
* Gets the YAML value this node corresponds to after resolving aliases and includes.
*/
YAMLValue eval() { result = this }
YamlValue eval() { result = this }
override string getAPrimaryQlClass() { result = "YAMLNode" }
override string getAPrimaryQlClass() { result = "YamlNode" }
}
/** DEPRECATED: Alias for YamlNode */
deprecated class YAMLNode = YamlNode;
/**
* A YAML value; that is, either a scalar or a collection.
*
@@ -102,7 +105,10 @@ class YAMLNode extends @yaml_node, Locatable {
* - sequence
* ```
*/
abstract class YAMLValue extends YAMLNode { }
abstract class YamlValue extends YamlNode { }
/** DEPRECATED: Alias for YamlValue */
deprecated class YAMLValue = YamlValue;
/**
* A YAML scalar.
@@ -118,7 +124,7 @@ abstract class YAMLValue extends YAMLNode { }
* "hello"
* ```
*/
class YAMLScalar extends YAMLValue, @yaml_scalar_node {
class YamlScalar extends YamlValue, @yaml_scalar_node {
/**
* Gets the style of this scalar, which is one of the following:
*
@@ -147,9 +153,12 @@ class YAMLScalar extends YAMLValue, @yaml_scalar_node {
*/
string getValue() { yaml_scalars(this, _, result) }
override string getAPrimaryQlClass() { result = "YAMLScalar" }
override string getAPrimaryQlClass() { result = "YamlScalar" }
}
/** DEPRECATED: Alias for YamlScalar */
deprecated class YAMLScalar = YamlScalar;
/**
* A YAML scalar representing an integer value.
*
@@ -160,8 +169,8 @@ class YAMLScalar extends YAMLValue, @yaml_scalar_node {
* 0xffff
* ```
*/
class YAMLInteger extends YAMLScalar {
YAMLInteger() { this.hasStandardTypeTag("int") }
class YamlInteger extends YamlScalar {
YamlInteger() { this.hasStandardTypeTag("int") }
/**
* Gets the value of this scalar, as an integer.
@@ -169,6 +178,9 @@ class YAMLInteger extends YAMLScalar {
int getIntValue() { result = this.getValue().toInt() }
}
/** DEPRECATED: Alias for YamlInteger */
deprecated class YAMLInteger = YamlInteger;
/**
* A YAML scalar representing a floating point value.
*
@@ -179,8 +191,8 @@ class YAMLInteger extends YAMLScalar {
* 6.626e-34
* ```
*/
class YAMLFloat extends YAMLScalar {
YAMLFloat() { this.hasStandardTypeTag("float") }
class YamlFloat extends YamlScalar {
YamlFloat() { this.hasStandardTypeTag("float") }
/**
* Gets the value of this scalar, as a floating point number.
@@ -188,6 +200,9 @@ class YAMLFloat extends YAMLScalar {
float getFloatValue() { result = this.getValue().toFloat() }
}
/** DEPRECATED: Alias for YamlFloat */
deprecated class YAMLFloat = YamlFloat;
/**
* A YAML scalar representing a time stamp.
*
@@ -197,8 +212,8 @@ class YAMLFloat extends YAMLScalar {
* 2001-12-15T02:59:43.1Z
* ```
*/
class YAMLTimestamp extends YAMLScalar {
YAMLTimestamp() { this.hasStandardTypeTag("timestamp") }
class YamlTimestamp extends YamlScalar {
YamlTimestamp() { this.hasStandardTypeTag("timestamp") }
/**
* Gets the value of this scalar, as a date.
@@ -206,6 +221,9 @@ class YAMLTimestamp extends YAMLScalar {
date getDateValue() { result = this.getValue().toDate() }
}
/** DEPRECATED: Alias for YamlTimestamp */
deprecated class YAMLTimestamp = YamlTimestamp;
/**
* A YAML scalar representing a Boolean value.
*
@@ -215,8 +233,8 @@ class YAMLTimestamp extends YAMLScalar {
* true
* ```
*/
class YAMLBool extends YAMLScalar {
YAMLBool() { this.hasStandardTypeTag("bool") }
class YamlBool extends YamlScalar {
YamlBool() { this.hasStandardTypeTag("bool") }
/**
* Gets the value of this scalar, as a Boolean.
@@ -224,6 +242,9 @@ class YAMLBool extends YAMLScalar {
boolean getBoolValue() { if this.getValue() = "true" then result = true else result = false }
}
/** DEPRECATED: Alias for YamlBool */
deprecated class YAMLBool = YamlBool;
/**
* A YAML scalar representing the null value.
*
@@ -233,10 +254,13 @@ class YAMLBool extends YAMLScalar {
* null
* ```
*/
class YAMLNull extends YAMLScalar {
YAMLNull() { this.hasStandardTypeTag("null") }
class YamlNull extends YamlScalar {
YamlNull() { this.hasStandardTypeTag("null") }
}
/** DEPRECATED: Alias for YamlNull */
deprecated class YAMLNull = YamlNull;
/**
* A YAML scalar representing a string value.
*
@@ -246,10 +270,13 @@ class YAMLNull extends YAMLScalar {
* "hello"
* ```
*/
class YAMLString extends YAMLScalar {
YAMLString() { this.hasStandardTypeTag("str") }
class YamlString extends YamlScalar {
YamlString() { this.hasStandardTypeTag("str") }
}
/** DEPRECATED: Alias for YamlString */
deprecated class YAMLString = YamlString;
/**
* A YAML scalar representing a merge key.
*
@@ -260,10 +287,13 @@ class YAMLString extends YAMLScalar {
* << : *DEFAULTS # merge key
* ```
*/
class YAMLMergeKey extends YAMLScalar {
YAMLMergeKey() { this.hasStandardTypeTag("merge") }
class YamlMergeKey extends YamlScalar {
YamlMergeKey() { this.hasStandardTypeTag("merge") }
}
/** DEPRECATED: Alias for YamlMergeKey */
deprecated class YAMLMergeKey = YamlMergeKey;
/**
* A YAML scalar representing an `!include` directive.
*
@@ -271,11 +301,11 @@ class YAMLMergeKey extends YAMLScalar {
* !include common.yaml
* ```
*/
class YAMLInclude extends YAMLScalar {
YAMLInclude() { this.getTag() = "!include" }
class YamlInclude extends YamlScalar {
YamlInclude() { this.getTag() = "!include" }
override YAMLValue eval() {
exists(YAMLDocument targetDoc |
override YamlValue eval() {
exists(YamlDocument targetDoc |
targetDoc.getFile().getAbsolutePath() = this.getTargetPath() and
result = targetDoc.eval()
)
@@ -293,6 +323,9 @@ class YAMLInclude extends YAMLScalar {
}
}
/** DEPRECATED: Alias for YamlInclude */
deprecated class YAMLInclude = YamlInclude;
/**
* A YAML collection, that is, either a mapping or a sequence.
*
@@ -310,10 +343,13 @@ class YAMLInclude extends YAMLScalar {
* - -blue
* ```
*/
class YAMLCollection extends YAMLValue, @yaml_collection_node {
override string getAPrimaryQlClass() { result = "YAMLCollection" }
class YamlCollection extends YamlValue, @yaml_collection_node {
override string getAPrimaryQlClass() { result = "YamlCollection" }
}
/** DEPRECATED: Alias for YamlCollection */
deprecated class YAMLCollection = YamlCollection;
/**
* A YAML mapping.
*
@@ -324,11 +360,11 @@ class YAMLCollection extends YAMLValue, @yaml_collection_node {
* y: 1
* ```
*/
class YAMLMapping extends YAMLCollection, @yaml_mapping_node {
class YamlMapping extends YamlCollection, @yaml_mapping_node {
/**
* Gets the `i`th key of this mapping.
*/
YAMLNode getKeyNode(int i) {
YamlNode getKeyNode(int i) {
i >= 0 and
exists(int j | i = j - 1 and result = this.getChildNode(j))
}
@@ -336,7 +372,7 @@ class YAMLMapping extends YAMLCollection, @yaml_mapping_node {
/**
* Gets the `i`th value of this mapping.
*/
YAMLNode getValueNode(int i) {
YamlNode getValueNode(int i) {
i >= 0 and
exists(int j | i = -j - 1 and result = this.getChildNode(j))
}
@@ -344,30 +380,33 @@ class YAMLMapping extends YAMLCollection, @yaml_mapping_node {
/**
* Gets the `i`th key of this mapping, as a YAML value.
*/
YAMLValue getKey(int i) { result = this.getKeyNode(i).eval() }
YamlValue getKey(int i) { result = this.getKeyNode(i).eval() }
/**
* Gets the `i`th value of this mapping, as a YAML value.
*/
YAMLValue getValue(int i) { result = this.getValueNode(i).eval() }
YamlValue getValue(int i) { result = this.getValueNode(i).eval() }
/**
* Holds if this mapping maps `key` to `value`.
*/
predicate maps(YAMLValue key, YAMLValue value) {
predicate maps(YamlValue key, YamlValue value) {
exists(int i | key = this.getKey(i) and value = this.getValue(i))
or
exists(YAMLMergeKey merge, YAMLMapping that | this.maps(merge, that) | that.maps(key, value))
exists(YamlMergeKey merge, YamlMapping that | this.maps(merge, that) | that.maps(key, value))
}
/**
* Gets the value that this mapping maps `key` to.
*/
YAMLValue lookup(string key) { exists(YAMLScalar s | s.getValue() = key | this.maps(s, result)) }
YamlValue lookup(string key) { exists(YamlScalar s | s.getValue() = key | this.maps(s, result)) }
override string getAPrimaryQlClass() { result = "YAMLMapping" }
override string getAPrimaryQlClass() { result = "YamlMapping" }
}
/** DEPRECATED: Alias for YamlMapping */
deprecated class YAMLMapping = YamlMapping;
/**
* A YAML sequence.
*
@@ -379,20 +418,23 @@ class YAMLMapping extends YAMLCollection, @yaml_mapping_node {
* - blue
* ```
*/
class YAMLSequence extends YAMLCollection, @yaml_sequence_node {
class YamlSequence extends YamlCollection, @yaml_sequence_node {
/**
* Gets the `i`th element in this sequence.
*/
YAMLNode getElementNode(int i) { result = this.getChildNode(i) }
YamlNode getElementNode(int i) { result = this.getChildNode(i) }
/**
* Gets the `i`th element in this sequence, as a YAML value.
*/
YAMLValue getElement(int i) { result = this.getElementNode(i).eval() }
YamlValue getElement(int i) { result = this.getElementNode(i).eval() }
override string getAPrimaryQlClass() { result = "YAMLSequence" }
override string getAPrimaryQlClass() { result = "YamlSequence" }
}
/** DEPRECATED: Alias for YamlSequence */
deprecated class YAMLSequence = YamlSequence;
/**
* A YAML alias node referring to a target anchor.
*
@@ -402,8 +444,8 @@ class YAMLSequence extends YAMLCollection, @yaml_sequence_node {
* *DEFAULTS
* ```
*/
class YAMLAliasNode extends YAMLNode, @yaml_alias_node {
override YAMLValue eval() {
class YamlAliasNode extends YamlNode, @yaml_alias_node {
override YamlValue eval() {
result.getAnchor() = this.getTarget() and
result.getDocument() = this.getDocument()
}
@@ -413,9 +455,12 @@ class YAMLAliasNode extends YAMLNode, @yaml_alias_node {
*/
string getTarget() { yaml_aliases(this, result) }
override string getAPrimaryQlClass() { result = "YAMLAliasNode" }
override string getAPrimaryQlClass() { result = "YamlAliasNode" }
}
/** DEPRECATED: Alias for YamlAliasNode */
deprecated class YAMLAliasNode = YamlAliasNode;
/**
* A YAML document.
*
@@ -427,14 +472,17 @@ class YAMLAliasNode extends YAMLNode, @yaml_alias_node {
* y: 1
* ```
*/
class YAMLDocument extends YAMLNode {
YAMLDocument() { not exists(this.getParentNode()) }
class YamlDocument extends YamlNode {
YamlDocument() { not exists(this.getParentNode()) }
}
/** DEPRECATED: Alias for YamlDocument */
deprecated class YAMLDocument = YamlDocument;
/**
* An error message produced by the YAML parser while processing a YAML file.
*/
class YAMLParseError extends @yaml_error, Error {
class YamlParseError extends @yaml_error, Error {
override Location getLocation() { yaml_locations(this, result) }
override string getMessage() { yaml_errors(this, result) }
@@ -442,6 +490,9 @@ class YAMLParseError extends @yaml_error, Error {
override string toString() { result = this.getMessage() }
}
/** DEPRECATED: Alias for YamlParseError */
deprecated class YAMLParseError = YamlParseError;
/**
* A YAML node that may contain sub-nodes that can be identified by a name.
* I.e. a mapping, sequence, or scalar.
@@ -464,30 +515,30 @@ class YAMLParseError extends @yaml_error, Error {
*
* are equivalent.
*/
class YAMLMappingLikeNode extends YAMLNode {
YAMLMappingLikeNode() {
this instanceof YAMLMapping
class YamlMappingLikeNode extends YamlNode {
YamlMappingLikeNode() {
this instanceof YamlMapping
or
this instanceof YAMLSequence
this instanceof YamlSequence
or
this instanceof YAMLScalar
this instanceof YamlScalar
}
/** Gets sub-name identified by `name`. */
YAMLNode getNode(string name) {
exists(YAMLMapping mapping |
YamlNode getNode(string name) {
exists(YamlMapping mapping |
mapping = this and
result = mapping.lookup(name)
)
or
exists(YAMLSequence sequence, YAMLNode node |
exists(YamlSequence sequence, YamlNode node |
sequence = this and
sequence.getAChildNode() = node and
node.eval().toString() = name and
result = node
)
or
exists(YAMLScalar scalar |
exists(YamlScalar scalar |
scalar = this and
scalar.getValue() = name and
result = scalar
@@ -496,19 +547,22 @@ class YAMLMappingLikeNode extends YAMLNode {
/** Gets the number of elements in this mapping or sequence. */
int getElementCount() {
exists(YAMLMapping mapping |
exists(YamlMapping mapping |
mapping = this and
result = mapping.getNumChild() / 2
)
or
exists(YAMLSequence sequence |
exists(YamlSequence sequence |
sequence = this and
result = sequence.getNumChild()
)
or
exists(YAMLScalar scalar |
exists(YamlScalar scalar |
scalar = this and
result = 1
)
}
}
/** DEPRECATED: Alias for YamlMappingLikeNode */
deprecated class YAMLMappingLikeNode = YamlMappingLikeNode;

View File

@@ -1267,56 +1267,47 @@ private predicate loadStep(
* If `onlyRelevantInCall` is true, the `base` object will not be propagated out of return edges, because
* the flow that originally reached `base.startProp` used a call edge.
*/
pragma[nomagic]
pragma[noopt]
private predicate reachableFromStoreBase(
string startProp, string endProp, DataFlow::Node base, DataFlow::Node nd,
DataFlow::Configuration cfg, PathSummary summary, boolean onlyRelevantInCall
DataFlow::Configuration cfg, TPathSummary summary, boolean onlyRelevantInCall
) {
exists(PathSummary s1, PathSummary s2, DataFlow::Node rhs |
reachableFromSource(rhs, cfg, s1) and
onlyRelevantInCall = s1.hasCall()
or
reachableFromStoreBase(_, _, _, rhs, cfg, s1, onlyRelevantInCall)
|
exists(TPathSummary s1, TPathSummary s2, DataFlow::Node rhs |
storeStep(rhs, nd, startProp, cfg, s2) and
endProp = startProp and
base = nd and
summary =
MkPathSummary(false, s2.hasCall(), DataFlow::FlowLabel::data(), DataFlow::FlowLabel::data())
exists(boolean hasCall, DataFlow::FlowLabel data |
hasCall = hasCall(s2) and
data = DataFlow::FlowLabel::data() and
summary = MkPathSummary(false, hasCall, data, data)
)
|
reachableFromSource(rhs, cfg, s1) and
onlyRelevantInCall = hasCall(s1)
or
reachableFromStoreBase(_, _, _, rhs, cfg, s1, onlyRelevantInCall)
)
or
exists(PathSummary newSummary, PathSummary oldSummary |
reachableFromStoreBaseStep(startProp, endProp, base, nd, cfg, oldSummary, newSummary,
onlyRelevantInCall) and
summary = oldSummary.appendValuePreserving(newSummary)
)
}
/**
* Holds if `base` is the base of a write to property `endProp`, and `nd` is reachable
* from `base` under configuration `cfg` (possibly through callees) along a path whose
* last step is summarized by `newSummary`, and the previous steps are summarized
* by `oldSummary`.
*/
pragma[noinline]
private predicate reachableFromStoreBaseStep(
string startProp, string endProp, DataFlow::Node base, DataFlow::Node nd,
DataFlow::Configuration cfg, PathSummary oldSummary, PathSummary newSummary,
boolean onlyRelevantInCall
) {
exists(DataFlow::Node mid |
exists(DataFlow::Node mid, PathSummary oldSummary, PathSummary newSummary |
reachableFromStoreBase(startProp, endProp, base, mid, cfg, oldSummary, onlyRelevantInCall) and
flowStep(mid, cfg, nd, newSummary) and
onlyRelevantInCall.booleanAnd(newSummary.hasReturn()) = false
exists(boolean hasReturn |
hasReturn = newSummary.hasReturn() and
onlyRelevantInCall.booleanAnd(hasReturn) = false
)
or
exists(string midProp |
reachableFromStoreBase(startProp, midProp, base, mid, cfg, oldSummary, onlyRelevantInCall) and
isAdditionalLoadStoreStep(mid, nd, midProp, endProp, cfg) and
newSummary = PathSummary::level()
)
|
summary = oldSummary.appendValuePreserving(newSummary)
)
}
private boolean hasCall(PathSummary summary) { result = summary.hasCall() }
/**
* Holds if the value of `pred` is written to a property of some base object, and that base
* object may flow into the base of property read `succ` under configuration `cfg` along

View File

@@ -1029,6 +1029,32 @@ module DataFlow {
override File getFile() { result = function.getFile() }
}
/**
* A data flow node representing the arguments object given to a function.
*/
class ReflectiveParametersNode extends DataFlow::Node, TReflectiveParametersNode {
Function function;
ReflectiveParametersNode() { this = TReflectiveParametersNode(function) }
override string toString() { result = "'arguments' object of " + function.describe() }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
function.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
override BasicBlock getBasicBlock() { result = function.getEntry().getBasicBlock() }
/**
* Gets the function whose `arguments` object is represented by this node.
*/
Function getFunction() { result = function }
override File getFile() { result = function.getFile() }
}
/**
* A data flow node representing the exceptions thrown by the callee of an invocation.
*/
@@ -1627,6 +1653,35 @@ module DataFlow {
exists(Function f | not f.isAsyncOrGenerator() |
DataFlow::functionReturnNode(succ, f) and pred = valueNode(f.getAReturnedExpr())
)
or
// from a reflective params node to a reference to the arguments object.
exists(DataFlow::ReflectiveParametersNode params, Function f | f = params.getFunction() |
succ = f.getArgumentsVariable().getAnAccess().flow() and
pred = params
)
}
/** A load step from a reflective parameter node to each parameter. */
private class ReflectiveParamsStep extends PreCallGraphStep {
override predicate loadStep(DataFlow::Node obj, DataFlow::Node element, string prop) {
exists(DataFlow::ReflectiveParametersNode params, DataFlow::FunctionNode f, int i |
f.getFunction() = params.getFunction() and
obj = params and
prop = i + "" and
element = f.getParameter(i)
)
}
}
/** A taint step from the reflective parameters node to any parameter. */
private class ReflectiveParamsTaintStep extends TaintTracking::SharedTaintStep {
override predicate step(DataFlow::Node obj, DataFlow::Node element) {
exists(DataFlow::ReflectiveParametersNode params, DataFlow::FunctionNode f |
f.getFunction() = params.getFunction() and
obj = params and
element = f.getAParameter()
)
}
}
/**

View File

@@ -332,6 +332,8 @@ module SourceNode {
or
// Include return nodes because they model the implicit Promise creation in async functions.
DataFlow::functionReturnNode(this, _)
or
this instanceof DataFlow::ReflectiveParametersNode
}
}
}

View File

@@ -89,6 +89,18 @@ module CallGraph {
result = getAFunctionReference(outer, 0, t.continue()).getAnInvocation() and
locallyReturnedFunction(outer, function)
)
or
// dynamic dispatch to unknown property of an object
exists(DataFlow::ObjectLiteralNode obj, DataFlow::PropRead read |
getAFunctionReference(function, 0, t.continue()) = obj.getAPropertySource() and
obj.getAPropertyRead() = read and
not exists(read.getPropertyName()) and
result = read and
// there exists only local reads of the object, nothing else.
forex(DataFlow::Node ref | ref = obj.getALocalUse() and exists(ref.asExpr()) |
ref = [obj, any(DataFlow::PropRead r).getBase()]
)
)
}
private predicate locallyReturnedFunction(

View File

@@ -31,4 +31,5 @@ newtype TNode =
TExceptionalFunctionReturnNode(Function f) or
TExceptionalInvocationReturnNode(InvokeExpr e) or
TGlobalAccessPathRoot() or
TTemplatePlaceholderTag(Templating::TemplatePlaceholderTag tag)
TTemplatePlaceholderTag(Templating::TemplatePlaceholderTag tag) or
TReflectiveParametersNode(Function f)

View File

@@ -224,6 +224,14 @@ private module CachedSteps {
or
arg = invk.(DataFlow::PropWrite).getRhs() and
parm = DataFlow::parameterNode(f.getParameter(0))
or
calls(invk, f) and
exists(MethodCallExpr apply |
invk = DataFlow::reflectiveCallNode(apply) and
apply.getMethodName() = "apply" and
arg = apply.getArgument(1).flow()
) and
parm.(DataFlow::ReflectiveParametersNode).getFunction() = f
)
or
exists(DataFlow::Node callback, int i, Parameter p, Function target |

View File

@@ -171,10 +171,10 @@ abstract class CallWithNonLocalAnalyzedReturnFlow extends DataFlow::AnalyzedValu
/**
* Flow analysis for the return value of IIFEs.
*/
private class IIFEWithAnalyzedReturnFlow extends CallWithAnalyzedReturnFlow {
private class IifeWithAnalyzedReturnFlow extends CallWithAnalyzedReturnFlow {
ImmediatelyInvokedFunctionExpr iife;
IIFEWithAnalyzedReturnFlow() { astNode = iife.getInvocation() }
IifeWithAnalyzedReturnFlow() { astNode = iife.getInvocation() }
override AnalyzedFunction getACallee() { result = iife.analyze() }
}

View File

@@ -692,10 +692,10 @@ abstract private class CallWithAnalyzedParameters extends FunctionWithAnalyzedPa
/**
* Flow analysis for simple parameters of IIFEs.
*/
private class IIFEWithAnalyzedParameters extends CallWithAnalyzedParameters {
private class IifeWithAnalyzedParameters extends CallWithAnalyzedParameters {
ImmediatelyInvokedFunctionExpr iife;
IIFEWithAnalyzedParameters() {
IifeWithAnalyzedParameters() {
this = iife and
iife.getInvocationKind() = "direct"
}

View File

@@ -276,15 +276,15 @@ class ExternalScriptDependency extends ScriptDependency, @xmlattribute {
/**
* A dependency on GWT indicated by a GWT header script.
*/
private class GWTDependency extends ScriptDependency {
GWTDependency() { this instanceof GWTHeader }
private class GwtDependency extends ScriptDependency {
GwtDependency() { this instanceof GwtHeader }
override predicate info(string id, string v) {
id = "gwt" and
exists(GWTHeader h | h = this |
v = h.getGWTVersion()
exists(GwtHeader h | h = this |
v = h.getGwtVersion()
or
not exists(h.getGWTVersion()) and v = "unknown"
not exists(h.getGwtVersion()) and v = "unknown"
)
}

View File

@@ -904,8 +904,8 @@ private class SinonJS extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWi
/**
* The TinyMCE framework.
*/
private class TinyMCE extends FrameworkLibraryWithGenericUrl {
TinyMCE() { this = "tinymce" }
private class TinyMce extends FrameworkLibraryWithGenericUrl {
TinyMce() { this = "tinymce" }
override string getAnAlias() { result = "jquery.tinymce" or result = "tinymce.jquery" }
}

View File

@@ -112,7 +112,7 @@ module Electron {
*/
class ProcessSender extends Process {
ProcessSender() {
exists(IPCSendRegistration reg | reg.getEmitter() instanceof MainProcess |
exists(IpcSendRegistration reg | reg.getEmitter() instanceof MainProcess |
this = reg.getABoundCallbackParameter(1, 0).getAPropertyRead("sender")
)
}
@@ -123,28 +123,31 @@ module Electron {
* Does mostly the same as an EventEmitter event handler,
* except that values can be returned through the `event.returnValue` property.
*/
class IPCSendRegistration extends EventRegistration::DefaultEventRegistration,
class IpcSendRegistration extends EventRegistration::DefaultEventRegistration,
DataFlow::MethodCallNode {
override Process emitter;
IPCSendRegistration() { this = emitter.ref().getAMethodCall(EventEmitter::on()) }
IpcSendRegistration() { this = emitter.ref().getAMethodCall(EventEmitter::on()) }
override DataFlow::Node getAReturnedValue() {
result = this.getABoundCallbackParameter(1, 0).getAPropertyWrite("returnValue").getRhs()
}
override IPCDispatch getAReturnDispatch() { result.getCalleeName() = "sendSync" }
override IpcDispatch getAReturnDispatch() { result.getCalleeName() = "sendSync" }
}
/** DEPRECATED: Alias for IpcSendRegistration */
deprecated class IPCSendRegistration = IpcSendRegistration;
/**
* A dispatch of an IPC event.
* An IPC event is sent from the renderer to the main process.
* And a value can be returned through the `returnValue` property of the event (first parameter in the callback).
*/
class IPCDispatch extends EventDispatch::DefaultEventDispatch, DataFlow::InvokeNode {
class IpcDispatch extends EventDispatch::DefaultEventDispatch, DataFlow::InvokeNode {
override Process emitter;
IPCDispatch() {
IpcDispatch() {
exists(string methodName | methodName = "sendSync" or methodName = "send" |
this = emitter.ref().getAMemberCall(methodName)
)
@@ -163,7 +166,7 @@ module Electron {
/**
* Gets a registration that this dispatch can send an event to.
*/
override IPCSendRegistration getAReceiver() {
override IpcSendRegistration getAReceiver() {
this.getEmitter() instanceof RendererProcess and
result.getEmitter() instanceof MainProcess
or
@@ -171,6 +174,9 @@ module Electron {
result.getEmitter() instanceof RendererProcess
}
}
/** DEPRECATED: Alias for IpcDispatch */
deprecated class IPCDispatch = IpcDispatch;
}
/**

View File

@@ -13,10 +13,13 @@ abstract class EmscriptenMarkerComment extends GeneratedCodeMarkerComment { }
/**
* An `EMSCRIPTEN_START_ASM` marker comment.
*/
class EmscriptenStartASMComment extends EmscriptenMarkerComment {
EmscriptenStartASMComment() { getText().trim() = "EMSCRIPTEN_START_ASM" }
class EmscriptenStartAsmComment extends EmscriptenMarkerComment {
EmscriptenStartAsmComment() { getText().trim() = "EMSCRIPTEN_START_ASM" }
}
/** DEPRECATED: Alias for EmscriptenStartAsmComment */
deprecated class EmscriptenStartASMComment = EmscriptenStartAsmComment;
/**
* An `EMSCRIPTEN_START_FUNCS` marker comment.
*/
@@ -27,10 +30,13 @@ class EmscriptenStartFuncsComment extends EmscriptenMarkerComment {
/**
* An `EMSCRIPTEN_END_ASM` marker comment.
*/
class EmscriptenEndASMComment extends EmscriptenMarkerComment {
EmscriptenEndASMComment() { getText().trim() = "EMSCRIPTEN_END_ASM" }
class EmscriptenEndAsmComment extends EmscriptenMarkerComment {
EmscriptenEndAsmComment() { getText().trim() = "EMSCRIPTEN_END_ASM" }
}
/** DEPRECATED: Alias for EmscriptenEndAsmComment */
deprecated class EmscriptenEndASMComment = EmscriptenEndAsmComment;
/**
* An `EMSCRIPTEN_END_FUNCS` marker comment.
*/

View File

@@ -7,32 +7,44 @@ import javascript
/**
* A `$gwt_version` variable.
*/
class GWTVersionVariable extends GlobalVariable {
GWTVersionVariable() { getName() = "$gwt_version" }
class GwtVersionVariable extends GlobalVariable {
GwtVersionVariable() { getName() = "$gwt_version" }
}
/** DEPRECATED: Alias for GwtVersionVariable */
deprecated class GWTVersionVariable = GwtVersionVariable;
/**
* A GWT header script that defines the `$gwt_version` variable.
*/
class GWTHeader extends InlineScript {
GWTHeader() {
exists(GWTVersionVariable gwtVersion | gwtVersion.getADeclaration().getTopLevel() = this)
class GwtHeader extends InlineScript {
GwtHeader() {
exists(GwtVersionVariable gwtVersion | gwtVersion.getADeclaration().getTopLevel() = this)
}
/**
* Gets the GWT version this script was generated with, if it can be determined.
*/
string getGWTVersion() {
string getGwtVersion() {
exists(Expr e | e.getTopLevel() = this |
e = any(GWTVersionVariable v).getAnAssignedExpr() and
e = any(GwtVersionVariable v).getAnAssignedExpr() and
result = e.getStringValue()
)
}
/** DEPRECATED: Alias for getGwtVersion */
deprecated string getGWTVersion() { result = getGwtVersion() }
}
/** DEPRECATED: Alias for GwtHeader */
deprecated class GWTHeader = GwtHeader;
/**
* A toplevel in a file that appears to be GWT-generated.
*/
class GWTGeneratedTopLevel extends TopLevel {
GWTGeneratedTopLevel() { exists(GWTHeader h | getFile() = h.getFile()) }
class GwtGeneratedTopLevel extends TopLevel {
GwtGeneratedTopLevel() { exists(GwtHeader h | getFile() = h.getFile()) }
}
/** DEPRECATED: Alias for GwtGeneratedTopLevel */
deprecated class GWTGeneratedTopLevel = GwtGeneratedTopLevel;

View File

@@ -4,9 +4,9 @@
import javascript
/** Provides classes for modeling NoSQL query sinks. */
/** Provides classes for modeling NoSql query sinks. */
module NoSql {
/** An expression that is interpreted as a NoSQL query. */
/** An expression that is interpreted as a NoSql query. */
abstract class Query extends Expr {
/** Gets an expression that is interpreted as a code operator in this query. */
DataFlow::Node getACodeOperator() { none() }

View File

@@ -14,23 +14,23 @@ private module ServerLess {
* Holds if the `.yml` file `ymlFile` contains a serverless configuration with `handler` and `codeURI` properties.
* `codeURI` defaults to the empty string if no explicit value is set in the configuration.
*/
private predicate hasServerlessHandler(File ymlFile, string handler, string codeURI) {
exists(YAMLMapping resource | ymlFile = resource.getFile() |
private predicate hasServerlessHandler(File ymlFile, string handler, string codeUri) {
exists(YamlMapping resource | ymlFile = resource.getFile() |
// There exists at least "AWS::Serverless::Function" and "Aliyun::Serverless::Function"
resource.lookup("Type").(YAMLScalar).getValue().regexpMatch(".*::Serverless::Function") and
exists(YAMLMapping properties | properties = resource.lookup("Properties") |
handler = properties.lookup("Handler").(YAMLScalar).getValue() and
resource.lookup("Type").(YamlScalar).getValue().regexpMatch(".*::Serverless::Function") and
exists(YamlMapping properties | properties = resource.lookup("Properties") |
handler = properties.lookup("Handler").(YamlScalar).getValue() and
if exists(properties.lookup("CodeUri"))
then codeURI = properties.lookup("CodeUri").(YAMLScalar).getValue()
else codeURI = ""
then codeUri = properties.lookup("CodeUri").(YamlScalar).getValue()
else codeUri = ""
)
or
// The `serverless` library, which specifies a top-level `functions` property
exists(YAMLMapping functions |
exists(YamlMapping functions |
functions = resource.lookup("functions") and
not exists(resource.getParentNode()) and
handler = functions.getValue(_).(YAMLMapping).lookup("handler").(YAMLScalar).getValue() and
codeURI = ""
handler = functions.getValue(_).(YamlMapping).lookup("handler").(YamlScalar).getValue() and
codeUri = ""
)
)
}
@@ -58,9 +58,9 @@ private module ServerLess {
*
* For example if `codeURI` is "function/." and `file` is "index", then the result becomes "function/index.js".
*/
bindingset[codeURI, file]
private string getPathFromHandlerProperties(string codeURI, string file) {
exists(string folder | folder = removeLeadingDotSlash(removeTrailingDot(codeURI)) |
bindingset[codeUri, file]
private string getPathFromHandlerProperties(string codeUri, string file) {
exists(string folder | folder = removeLeadingDotSlash(removeTrailingDot(codeUri)) |
result = folder + file + ".js"
)
}
@@ -69,8 +69,8 @@ private module ServerLess {
* Holds if `file` has a serverless handler function with name `func`.
*/
private predicate hasServerlessHandler(File file, string func) {
exists(File ymlFile, string handler, string codeURI, string fileName |
hasServerlessHandler(ymlFile, handler, codeURI) and
exists(File ymlFile, string handler, string codeUri, string fileName |
hasServerlessHandler(ymlFile, handler, codeUri) and
// Splits a `handler` into two components. The `fileName` to the left of the dot, and the `func` to the right.
// E.g. if `handler` is "index.foo", then `fileName` is "index" and `func` is "foo".
exists(string pattern | pattern = "(.*)\\.(.*)" |
@@ -80,7 +80,7 @@ private module ServerLess {
|
file.getAbsolutePath() =
ymlFile.getParentContainer().getAbsolutePath() + "/" +
getPathFromHandlerProperties(codeURI, fileName)
getPathFromHandlerProperties(codeUri, fileName)
)
}

View File

@@ -27,8 +27,8 @@ class QUnitTest extends Test, @call_expr {
* that is, an invocation of a function named `it` where the first argument
* is a string and the second argument is a function.
*/
class BDDTest extends Test, @call_expr {
BDDTest() {
class BddTest extends Test, @call_expr {
BddTest() {
exists(CallExpr call | call = this |
call.getCallee().(VarAccess).getName() = "it" and
exists(call.getArgument(0).getStringValue()) and
@@ -37,6 +37,9 @@ class BDDTest extends Test, @call_expr {
}
}
/** DEPRECATED: Alias for BddTest */
deprecated class BDDTest = BddTest;
/**
* Gets the test file for `f` with stem extension `stemExt`, where `stemExt` is "test" or "spec".
* That is, a file named `<base>.<stemExt>.<ext>` in the

View File

@@ -155,6 +155,22 @@ module ModelInput {
*/
abstract predicate row(string row);
}
/**
* A unit class for adding additional type variable model rows.
*/
class TypeVariableModelCsv extends Unit {
/**
* Holds if `row` specifies a path through a type variable.
*
* A row of form,
* ```
* name;path
* ```
* means `path` can be substituted for a token `TypeVar[name]`.
*/
abstract predicate row(string row);
}
}
private import ModelInput
@@ -182,6 +198,8 @@ private predicate summaryModel(string row) { any(SummaryModelCsv s).row(inverseP
private predicate typeModel(string row) { any(TypeModelCsv s).row(inversePad(row)) }
private predicate typeVariableModel(string row) { any(TypeVariableModelCsv s).row(inversePad(row)) }
/** Holds if a source model exists for the given parameters. */
predicate sourceModel(string package, string type, string path, string kind) {
exists(string row |
@@ -219,7 +237,7 @@ private predicate summaryModel(
)
}
/** Holds if an type model exists for the given parameters. */
/** Holds if a type model exists for the given parameters. */
private predicate typeModel(
string package1, string type1, string package2, string type2, string path
) {
@@ -233,6 +251,15 @@ private predicate typeModel(
)
}
/** Holds if a type variable model exists for the given parameters. */
private predicate typeVariableModel(string name, string path) {
exists(string row |
typeVariableModel(row) and
row.splitAt(";", 0) = name and
row.splitAt(";", 1) = path
)
}
/**
* Gets a package that should be seen as an alias for the given other `package`,
* or the `package` itself.
@@ -253,7 +280,7 @@ private predicate isRelevantPackage(string package) {
sourceModel(package, _, _, _) or
sinkModel(package, _, _, _) or
summaryModel(package, _, _, _, _, _) or
typeModel(package, _, _, _, _)
typeModel(_, _, package, _, _)
) and
(
Specific::isPackageUsed(package)
@@ -290,6 +317,8 @@ private class AccessPathRange extends AccessPath::Range {
summaryModel(package, _, _, this, _, _) or
summaryModel(package, _, _, _, this, _)
)
or
typeVariableModel(_, this)
}
}
@@ -361,6 +390,72 @@ private API::Node getNodeFromPath(string package, string type, AccessPath path,
// Similar to the other recursive case, but where the path may have stepped through one or more call-site filters
result =
getSuccessorFromInvoke(getInvocationFromPath(package, type, path, n - 1), path.getToken(n - 1))
or
// Apply a subpath
result =
getNodeFromSubPath(getNodeFromPath(package, type, path, n - 1), getSubPathAt(path, n - 1))
or
// Apply a type step
typeStep(getNodeFromPath(package, type, path, n), result)
}
/**
* Gets a subpath for the `TypeVar` token found at the `n`th token of `path`.
*/
pragma[nomagic]
private AccessPath getSubPathAt(AccessPath path, int n) {
exists(string typeVarName |
path.getToken(n).getAnArgument("TypeVar") = typeVarName and
typeVariableModel(typeVarName, result)
)
}
/**
* Gets a node that is found by evaluating the first `n` tokens of `subPath` starting at `base`.
*/
pragma[nomagic]
private API::Node getNodeFromSubPath(API::Node base, AccessPath subPath, int n) {
exists(AccessPath path, int k |
base = [getNodeFromPath(_, _, path, k), getNodeFromSubPath(_, path, k)] and
subPath = getSubPathAt(path, k) and
result = base and
n = 0
)
or
exists(string package, string type, AccessPath basePath |
typeStepModel(package, type, basePath, subPath) and
base = getNodeFromPath(package, type, basePath) and
result = base and
n = 0
)
or
result = getSuccessorFromNode(getNodeFromSubPath(base, subPath, n - 1), subPath.getToken(n - 1))
or
result =
getSuccessorFromInvoke(getInvocationFromSubPath(base, subPath, n - 1), subPath.getToken(n - 1))
or
result =
getNodeFromSubPath(getNodeFromSubPath(base, subPath, n - 1), getSubPathAt(subPath, n - 1))
or
typeStep(getNodeFromSubPath(base, subPath, n), result)
}
/**
* Gets a call site that is found by evaluating the first `n` tokens of `subPath` starting at `base`.
*/
private Specific::InvokeNode getInvocationFromSubPath(API::Node base, AccessPath subPath, int n) {
result = Specific::getAnInvocationOf(getNodeFromSubPath(base, subPath, n))
or
result = getInvocationFromSubPath(base, subPath, n - 1) and
invocationMatchesCallSiteFilter(result, subPath.getToken(n - 1))
}
/**
* Gets a node that is found by evaluating `subPath` starting at `base`.
*/
pragma[nomagic]
private API::Node getNodeFromSubPath(API::Node base, AccessPath subPath) {
result = getNodeFromSubPath(base, subPath, subPath.getNumToken())
}
/** Gets the node identified by the given `(package, type, path)` tuple. */
@@ -368,6 +463,20 @@ API::Node getNodeFromPath(string package, string type, AccessPath path) {
result = getNodeFromPath(package, type, path, path.getNumToken())
}
pragma[nomagic]
private predicate typeStepModel(string package, string type, AccessPath basePath, AccessPath output) {
summaryModel(package, type, basePath, "", output, "type")
}
pragma[nomagic]
private predicate typeStep(API::Node pred, API::Node succ) {
exists(string package, string type, AccessPath basePath, AccessPath output |
typeStepModel(package, type, basePath, output) and
pred = getNodeFromPath(package, type, basePath) and
succ = getNodeFromSubPath(pred, output)
)
}
/**
* Gets an invocation identified by the given `(package, type, path)` tuple.
*
@@ -390,7 +499,7 @@ Specific::InvokeNode getInvocationFromPath(string package, string type, AccessPa
*/
bindingset[name]
predicate isValidTokenNameInIdentifyingAccessPath(string name) {
name = ["Argument", "Parameter", "ReturnValue", "WithArity"]
name = ["Argument", "Parameter", "ReturnValue", "WithArity", "TypeVar"]
or
Specific::isExtraValidTokenNameInIdentifyingAccessPath(name)
}
@@ -418,6 +527,9 @@ predicate isValidTokenArgumentInIdentifyingAccessPath(string name, string argume
name = "WithArity" and
argument.regexpMatch("\\d+(\\.\\.(\\d+)?)?")
or
name = "TypeVar" and
exists(argument)
or
Specific::isExtraValidTokenArgumentInIdentifyingAccessPath(name, argument)
}
@@ -489,6 +601,8 @@ module ModelOutput {
any(SummaryModelCsv csv).row(row) and kind = "summary" and expectedArity = 6
or
any(TypeModelCsv csv).row(row) and kind = "type" and expectedArity = 5
or
any(TypeVariableModelCsv csv).row(row) and kind = "type-variable" and expectedArity = 2
|
actualArity = count(row.indexOf(";")) + 1 and
actualArity != expectedArity and
@@ -499,7 +613,7 @@ module ModelOutput {
or
// Check names and arguments of access path tokens
exists(AccessPath path, AccessPathToken token |
isRelevantFullPath(_, _, path) and
(isRelevantFullPath(_, _, path) or typeVariableModel(_, path)) and
token = path.getToken(_)
|
not isValidTokenNameInIdentifyingAccessPath(token.getName()) and

View File

@@ -104,6 +104,9 @@ API::Node getExtraSuccessorFromNode(API::Node node, AccessPathToken token) {
token.getName() = "Member" and
result = node.getMember(token.getAnArgument())
or
token.getName() = "AnyMember" and
result = node.getAMember()
or
token.getName() = "Instance" and
result = node.getInstance()
or
@@ -163,6 +166,16 @@ predicate invocationMatchesExtraCallSiteFilter(API::InvokeNode invoke, AccessPat
token.getName() = "Call" and
invoke instanceof API::CallNode and
invoke instanceof DataFlow::CallNode // Workaround compiler bug
or
token.getName() = "WithStringArgument" and
exists(string operand, string argIndex, string stringValue |
operand = token.getAnArgument() and
argIndex = operand.splitAt("=", 0) and
stringValue = operand.splitAt("=", 1) and
invoke
.getArgument(AccessPath::parseIntWithArity(argIndex, invoke.getNumArgument()))
.getStringValue() = stringValue
)
}
/**
@@ -225,8 +238,9 @@ bindingset[name]
predicate isExtraValidTokenNameInIdentifyingAccessPath(string name) {
name =
[
"Member", "Instance", "Awaited", "ArrayElement", "Element", "MapValue", "NewCall", "Call",
"DecoratedClass", "DecoratedMember", "DecoratedParameter"
"Member", "AnyMember", "Instance", "Awaited", "ArrayElement", "Element", "MapValue",
"NewCall", "Call", "DecoratedClass", "DecoratedMember", "DecoratedParameter",
"WithStringArgument"
]
}
@@ -237,7 +251,7 @@ predicate isExtraValidTokenNameInIdentifyingAccessPath(string name) {
predicate isExtraValidNoArgumentTokenInIdentifyingAccessPath(string name) {
name =
[
"Instance", "Awaited", "ArrayElement", "Element", "MapValue", "NewCall", "Call",
"AnyMember", "Instance", "Awaited", "ArrayElement", "Element", "MapValue", "NewCall", "Call",
"DecoratedClass", "DecoratedMember", "DecoratedParameter"
]
}
@@ -250,4 +264,8 @@ bindingset[name, argument]
predicate isExtraValidTokenArgumentInIdentifyingAccessPath(string name, string argument) {
name = ["Member"] and
exists(argument)
or
name = "WithStringArgument" and
exists(argument.indexOf("=")) and
exists(AccessPath::parseIntWithArity(argument.splitAt("=", 0), 10))
}

View File

@@ -281,7 +281,7 @@ private module JQueryClientRequest {
.getParameter(0)
or
result =
getAResponseNodeFromAnXHRObject(this.getOptionArgument([0 .. 1],
getAResponseNodeFromAnXhrObject(this.getOptionArgument([0 .. 1],
any(string method | method = "error" or method = "complete"))
.getALocalSource()
.(DataFlow::FunctionNode)
@@ -303,15 +303,15 @@ private module JQueryClientRequest {
.getParameter(0)
or
result =
getAResponseNodeFromAnXHRObject(request.getAMemberCall("fail").getCallback(0).getParameter(0))
getAResponseNodeFromAnXhrObject(request.getAMemberCall("fail").getCallback(0).getParameter(0))
}
/**
* Gets a node referring to the response contained in an `jqXHR` object.
*/
private DataFlow::SourceNode getAResponseNodeFromAnXHRObject(DataFlow::SourceNode jqXHR) {
private DataFlow::SourceNode getAResponseNodeFromAnXhrObject(DataFlow::SourceNode jqXhr) {
result =
jqXHR
jqXhr
.getAPropertyRead(any(string s |
s = "responseText" or
s = "responseXML"

View File

@@ -60,7 +60,7 @@ module ESLint {
}
/** An `.eslintrc.yaml` file. */
private class EslintrcYaml extends Configuration, YAMLDocument, YAMLMapping {
private class EslintrcYaml extends Configuration, YamlDocument, YamlMapping {
EslintrcYaml() {
exists(string n | n = getFile().getBaseName() |
n = ".eslintrc.yaml" or n = ".eslintrc.yml" or n = ".eslintrc"
@@ -71,11 +71,11 @@ module ESLint {
}
/** An ESLint configuration object in YAML format. */
private class YamlConfigurationObject extends ConfigurationObject, YAMLMapping {
private class YamlConfigurationObject extends ConfigurationObject, YamlMapping {
override Configuration getConfiguration() { this = result.(EslintrcYaml).getValue(_) }
override boolean getBooleanProperty(string p) {
exists(string v | v = lookup(p).(YAMLBool).getValue() |
exists(string v | v = lookup(p).(YamlBool).getValue() |
v = "true" and result = true
or
v = "false" and result = false

View File

@@ -173,7 +173,7 @@ module RangePrinter {
}
/** Gets the number of parts we should print for a given `range`. */
private int parts(OverlyWideRange range) { result = 1 + strictcount(cutoff(range, _)) }
private int parts(OverlyWideRange range) { result = 1 + count(cutoff(range, _)) }
/** Holds if the given part of a range should span from `low` to `high`. */
private predicate part(OverlyWideRange range, int part, string low, string high) {
@@ -238,8 +238,13 @@ module RangePrinter {
/** Gets a char range that is overly large because of `reason`. */
RegExpCharacterRange getABadRange(string reason, int priority) {
result instanceof OverlyWideRange and
priority = 0 and
reason = "is equivalent to " + result.(OverlyWideRange).printEquivalent()
exists(string equiv | equiv = result.(OverlyWideRange).printEquivalent() |
if equiv.length() <= 50
then reason = "is equivalent to " + equiv
else reason = "is equivalent to " + equiv.substring(0, 50) + "..."
)
or
priority = 1 and
exists(RegExpCharacterRange other |

View File

@@ -21,11 +21,11 @@ predicate config(string key, string val, Locatable valElement) {
val = valElement.(JsonString).getValue()
)
or
exists(YAMLMapping m, YAMLString keyElement |
exists(YamlMapping m, YamlString keyElement |
m.maps(keyElement, valElement) and
key = keyElement.getValue() and
(
val = valElement.(YAMLString).getValue()
val = valElement.(YamlString).getValue()
or
valElement.toString() = "" and
val = ""

View File

@@ -177,7 +177,7 @@ module ClientSideUrlRedirect {
)
or
// e.g. node.setAttribute("href", sink)
any(DomMethodCallExpr call).interpretsArgumentsAsURL(this.asExpr())
any(DomMethodCallExpr call).interpretsArgumentsAsUrl(this.asExpr())
}
override predicate isXssSink() { any() }

View File

@@ -86,7 +86,7 @@ class DomMethodCallExpr extends MethodCallExpr {
/**
* Holds if `arg` is an argument that is used as an URL.
*/
predicate interpretsArgumentsAsURL(Expr arg) {
predicate interpretsArgumentsAsUrl(Expr arg) {
exists(int argPos, string name |
arg = this.getArgument(argPos) and
name = this.getMethodName()
@@ -103,6 +103,9 @@ class DomMethodCallExpr extends MethodCallExpr {
)
}
/** DEPRECATED: Alias for interpretsArgumentsAsUrl */
deprecated predicate interpretsArgumentsAsURL(Expr arg) { this.interpretsArgumentsAsUrl(arg) }
/** DEPRECATED: Alias for interpretsArgumentsAsHtml */
deprecated predicate interpretsArgumentsAsHTML(Expr arg) { this.interpretsArgumentsAsHtml(arg) }
}

View File

@@ -23,13 +23,16 @@ deprecated class JQueryHtmlOrSelectorInjectionConfiguration = Configuration;
* A sink that is not a URL write or a JQuery selector,
* assumed to be a value that is interpreted as HTML.
*/
class HTMLSink extends DataFlow::Node instanceof Sink {
HTMLSink() {
class HtmlSink extends DataFlow::Node instanceof Sink {
HtmlSink() {
not this instanceof WriteUrlSink and
not this instanceof JQueryHtmlOrSelectorSink
}
}
/** DEPRECATED: Alias for HtmlSink */
deprecated class HTMLSink = HtmlSink;
/**
* A taint-tracking configuration for reasoning about XSS.
* Both ordinary HTML sinks, URL sinks, and JQuery selector based sinks.
@@ -55,7 +58,7 @@ class Configuration extends TaintTracking::Configuration {
}
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
sink instanceof HTMLSink and
sink instanceof HtmlSink and
label = [TaintedUrlSuffix::label(), prefixLabel(), DataFlow::FlowLabel::taint()]
or
sink instanceof JQueryHtmlOrSelectorSink and

View File

@@ -1,10 +1,10 @@
/** DEPRECATED. Import `ExternalAPIUsedWithUntrustedDataQuery` instead. */
/** DEPRECATED. Import `ExternalApiUsedWithUntrustedDataQuery` instead. */
import javascript
private import ExternalAPIUsedWithUntrustedDataQuery as ExternalAPIUsedWithUntrustedDataQuery // ignore-query-import
private import ExternalAPIUsedWithUntrustedDataQuery as ExternalApiUsedWithUntrustedDataQuery // ignore-query-import
/** DEPRECATED. Import `ExternalAPIUsedWithUntrustedDataQuery` instead. */
deprecated module ExternalApiUsedWithUntrustedData = ExternalAPIUsedWithUntrustedDataQuery;
/** DEPRECATED. Import `ExternalApiUsedWithUntrustedDataQuery` instead. */
deprecated module ExternalApiUsedWithUntrustedData = ExternalApiUsedWithUntrustedDataQuery;
/** DEPRECATED: Alias for ExternalApiUsedWithUntrustedData */
deprecated module ExternalAPIUsedWithUntrustedData = ExternalApiUsedWithUntrustedData;

View File

@@ -81,6 +81,7 @@ deprecated class UntrustedExternalAPIDataNode = UntrustedExternalApiDataNode;
* Name of an external API sink, boxed in a newtype for consistency with other languages.
*/
private newtype TExternalApi =
/** An external API sink with `name`. */
MkExternalApiNode(string name) {
exists(Sink sink |
any(Configuration c).hasFlow(_, sink) and

View File

@@ -68,7 +68,7 @@ module PrototypePollutingAssignment {
/**
* A parameter of an exported function, seen as a source prototype-polluting assignment.
*/
class ExternalInputSource extends Source, DataFlow::SourceNode {
class ExternalInputSource extends Source {
ExternalInputSource() { this = Exports::getALibraryInputParameter() }
override string describe() { result = "library input" }

View File

@@ -21,11 +21,11 @@ module UnsafeCodeConstruction {
/**
* A parameter of an exported function, seen as a source.
*/
class ExternalInputSource extends Source, DataFlow::ParameterNode {
class ExternalInputSource extends Source {
ExternalInputSource() {
this = Exports::getALibraryInputParameter() and
// permit parameters that clearly are intended to contain executable code.
not this.getName() = "code"
not this.(DataFlow::ParameterNode).getName() = "code"
}
}

View File

@@ -22,7 +22,7 @@ module UnsafeHtmlConstruction {
/**
* A parameter of an exported function, seen as a source for usnafe HTML constructed from input.
*/
class ExternalInputSource extends Source, DataFlow::ParameterNode {
class ExternalInputSource extends Source {
ExternalInputSource() {
this = Exports::getALibraryInputParameter() and
// An AMD-style module sometimes loads the jQuery library in a way which looks like library input.

View File

@@ -49,7 +49,7 @@ module UnsafeShellCommandConstruction {
/**
* A parameter of an exported function, seen as a source for shell command constructed from library input.
*/
class ExternalInputSource extends Source, DataFlow::SourceNode {
class ExternalInputSource extends Source {
ExternalInputSource() {
this = Exports::getALibraryInputParameter() and
not (

View File

@@ -62,7 +62,7 @@ module Shared {
}
}
private import semmle.javascript.security.dataflow.IncompleteHtmlAttributeSanitizationCustomizations::IncompleteHtmlAttributeSanitization as IncompleteHTML
private import semmle.javascript.security.dataflow.IncompleteHtmlAttributeSanitizationCustomizations::IncompleteHtmlAttributeSanitization as IncompleteHtml
/**
* A guard that checks if a string can contain quotes, which is a guard for strings that are inside a HTML attribute.
@@ -72,7 +72,7 @@ module Shared {
this.getSubstring().mayHaveStringValue("\"") and
this.getBaseString()
.getALocalSource()
.flowsTo(any(IncompleteHTML::HtmlAttributeConcatenation attributeConcat))
.flowsTo(any(IncompleteHtml::HtmlAttributeConcatenation attributeConcat))
}
override predicate sanitizes(boolean outcome, Expr e) {

View File

@@ -67,10 +67,10 @@ module XssThroughDom {
/**
* A source for text from a DOM property read by jQuery.
*/
class JQueryDOMPropertySource extends DomPropertySource instanceof JQuery::MethodCall {
class JQueryDomPropertySource extends DomPropertySource instanceof JQuery::MethodCall {
string prop;
JQueryDOMPropertySource() {
JQueryDomPropertySource() {
exists(string methodName |
this.getMethodName() = methodName and
this.getNumArgument() = 1 and
@@ -87,6 +87,9 @@ module XssThroughDom {
override string getPropertyName() { result = prop }
}
/** DEPRECATED: Alias for JQueryDomPropertySource */
deprecated class JQueryDOMPropertySource = JQueryDomPropertySource;
/**
* A source for text from the DOM from a `d3` method call.
*/

View File

@@ -115,6 +115,7 @@ private newtype TStatePair =
private int rankState(State state) {
state =
rank[result](State s, Location l |
stateInsideBacktracking(s) and
l = s.getRepr().getLocation()
|
s order by l.getStartLine(), l.getStartColumn(), s.toString()

View File

@@ -93,8 +93,6 @@ class RegExpRoot extends RegExpTerm {
* Holds if this root term is relevant to the ReDoS analysis.
*/
predicate isRelevant() {
// there is at least one repetition
getRoot(any(InfiniteRepetitionQuantifier q)) = this and
// is actually used as a RegExp
this.isUsedAsRegExp() and
// not excluded for library specific reasons
@@ -877,6 +875,101 @@ predicate isStartState(State state) {
*/
signature predicate isCandidateSig(State state, string pump);
/**
* Holds if `state` is a candidate for ReDoS.
*/
signature predicate isCandidateSig(State state);
/**
* Predicates for constructing a prefix string that leads to a given state.
*/
module PrefixConstruction<isCandidateSig/1 isCandidate> {
/**
* Holds if `state` is the textually last start state for the regular expression.
*/
private predicate lastStartState(State state) {
exists(RegExpRoot root |
state =
max(State s, Location l |
s = stateInRelevantRegexp() and
isStartState(s) and
getRoot(s.getRepr()) = root and
l = s.getRepr().getLocation()
|
s
order by
l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(),
l.getEndLine()
)
)
}
/**
* Holds if there exists any transition (Epsilon() or other) from `a` to `b`.
*/
private predicate existsTransition(State a, State b) { delta(a, _, b) }
/**
* Gets the minimum number of transitions it takes to reach `state` from the `start` state.
*/
int prefixLength(State start, State state) =
shortestDistances(lastStartState/1, existsTransition/2)(start, state, result)
/**
* Gets the minimum number of transitions it takes to reach `state` from the start state.
*/
private int lengthFromStart(State state) { result = prefixLength(_, state) }
/**
* Gets a string for which the regular expression will reach `state`.
*
* Has at most one result for any given `state`.
* This predicate will not always have a result even if there is a ReDoS issue in
* the regular expression.
*/
string prefix(State state) {
lastStartState(state) and
result = ""
or
// the search stops past the last redos candidate state.
lengthFromStart(state) <= max(lengthFromStart(any(State s | isCandidate(s)))) and
exists(State prev |
// select a unique predecessor (by an arbitrary measure)
prev =
min(State s, Location loc |
lengthFromStart(s) = lengthFromStart(state) - 1 and
loc = s.getRepr().getLocation() and
delta(s, _, state)
|
s
order by
loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(),
s.getRepr().toString()
)
|
// greedy search for the shortest prefix
result = prefix(prev) and delta(prev, Epsilon(), state)
or
not delta(prev, Epsilon(), state) and
result = prefix(prev) + getCanonicalEdgeChar(prev, state)
)
}
/**
* Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA.
*/
private string getCanonicalEdgeChar(State prev, State next) {
result =
min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next))
}
/** Gets a state within a regular expression that contains a candidate state. */
pragma[noinline]
State stateInRelevantRegexp() {
exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(result.getRepr()))
}
}
/**
* A module for pruning candidate ReDoS states.
* The candidates are specified by the `isCandidate` signature predicate.
@@ -910,95 +1003,9 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
/** Gets a state that can reach the `accept-any` state using only epsilon steps. */
private State acceptsAnySuffix() { epsilonSucc*(result) = AcceptAnySuffix(_) }
/**
* Predicates for constructing a prefix string that leads to a given state.
*/
private module PrefixConstruction {
/**
* Holds if `state` is the textually last start state for the regular expression.
*/
private predicate lastStartState(State state) {
exists(RegExpRoot root |
state =
max(State s, Location l |
s = stateInPumpableRegexp() and
isStartState(s) and
getRoot(s.getRepr()) = root and
l = s.getRepr().getLocation()
|
s
order by
l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(),
l.getEndLine()
)
)
}
predicate isCandidateState(State s) { isReDoSCandidate(s, _) }
/**
* Holds if there exists any transition (Epsilon() or other) from `a` to `b`.
*/
private predicate existsTransition(State a, State b) { delta(a, _, b) }
/**
* Gets the minimum number of transitions it takes to reach `state` from the `start` state.
*/
int prefixLength(State start, State state) =
shortestDistances(lastStartState/1, existsTransition/2)(start, state, result)
/**
* Gets the minimum number of transitions it takes to reach `state` from the start state.
*/
private int lengthFromStart(State state) { result = prefixLength(_, state) }
/**
* Gets a string for which the regular expression will reach `state`.
*
* Has at most one result for any given `state`.
* This predicate will not always have a result even if there is a ReDoS issue in
* the regular expression.
*/
string prefix(State state) {
lastStartState(state) and
result = ""
or
// the search stops past the last redos candidate state.
lengthFromStart(state) <= max(lengthFromStart(any(State s | isReDoSCandidate(s, _)))) and
exists(State prev |
// select a unique predecessor (by an arbitrary measure)
prev =
min(State s, Location loc |
lengthFromStart(s) = lengthFromStart(state) - 1 and
loc = s.getRepr().getLocation() and
delta(s, _, state)
|
s
order by
loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(),
s.getRepr().toString()
)
|
// greedy search for the shortest prefix
result = prefix(prev) and delta(prev, Epsilon(), state)
or
not delta(prev, Epsilon(), state) and
result = prefix(prev) + getCanonicalEdgeChar(prev, state)
)
}
/**
* Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA.
*/
private string getCanonicalEdgeChar(State prev, State next) {
result =
min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next))
}
/** Gets a state within a regular expression that has a pumpable state. */
pragma[noinline]
State stateInPumpableRegexp() {
exists(State s | isReDoSCandidate(s, _) | getRoot(s.getRepr()) = getRoot(result.getRepr()))
}
}
import PrefixConstruction<isCandidateState/1> as Prefix
/**
* Predicates for testing the presence of a rejecting suffix.
@@ -1018,8 +1025,6 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
* using epsilon transitions. But any attempt at repeating `w` will end in a state that accepts all suffixes.
*/
private module SuffixConstruction {
import PrefixConstruction
/**
* Holds if all states reachable from `fork` by repeating `w`
* are likely rejectable by appending some suffix.
@@ -1036,7 +1041,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
*/
pragma[noinline]
private predicate isLikelyRejectable(State s) {
s = stateInPumpableRegexp() and
s = Prefix::stateInRelevantRegexp() and
(
// exists a reject edge with some char.
hasRejectEdge(s)
@@ -1052,7 +1057,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
* Holds if `s` is not an accept state, and there is no epsilon transition to an accept state.
*/
predicate isRejectState(State s) {
s = stateInPumpableRegexp() and not epsilonSucc*(s) = Accept(_)
s = Prefix::stateInRelevantRegexp() and not epsilonSucc*(s) = Accept(_)
}
/**
@@ -1060,7 +1065,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
*/
pragma[noopt]
predicate hasEdgeToLikelyRejectable(State s) {
s = stateInPumpableRegexp() and
s = Prefix::stateInRelevantRegexp() and
// all edges (at least one) with some char leads to another state that is rejectable.
// the `next` states might not share a common suffix, which can cause FPs.
exists(string char | char = hasEdgeToLikelyRejectableHelper(s) |
@@ -1076,7 +1081,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
*/
pragma[noinline]
private string hasEdgeToLikelyRejectableHelper(State s) {
s = stateInPumpableRegexp() and
s = Prefix::stateInRelevantRegexp() and
not hasRejectEdge(s) and
not isRejectState(s) and
deltaClosedChar(s, result, _)
@@ -1088,8 +1093,8 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
* `prev` to `next` that the character symbol `char`.
*/
predicate deltaClosedChar(State prev, string char, State next) {
prev = stateInPumpableRegexp() and
next = stateInPumpableRegexp() and
prev = Prefix::stateInRelevantRegexp() and
next = Prefix::stateInRelevantRegexp() and
deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next)
}
@@ -1099,18 +1104,28 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
result = getAnInputSymbolMatching(char)
}
pragma[noinline]
RegExpRoot relevantRoot() {
exists(RegExpTerm term, State s |
s.getRepr() = term and isCandidateState(s) and result = term.getRootTerm()
)
}
/**
* Gets a char used for finding possible suffixes inside `root`.
*/
pragma[noinline]
private string relevant(RegExpRoot root) {
exists(ascii(result)) and exists(root)
or
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
or
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
result = ["|", "\n", "Z"] and exists(root)
root = relevantRoot() and
(
exists(ascii(result)) and exists(root)
or
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
or
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
result = ["|", "\n", "Z"] and exists(root)
)
}
/**
@@ -1208,12 +1223,12 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
predicate hasReDoSResult(RegExpTerm t, string pump, State s, string prefixMsg) {
isReDoSAttackable(t, pump, s) and
(
prefixMsg = "starting with '" + escape(PrefixConstruction::prefix(s)) + "' and " and
not PrefixConstruction::prefix(s) = ""
prefixMsg = "starting with '" + escape(Prefix::prefix(s)) + "' and " and
not Prefix::prefix(s) = ""
or
PrefixConstruction::prefix(s) = "" and prefixMsg = ""
Prefix::prefix(s) = "" and prefixMsg = ""
or
not exists(PrefixConstruction::prefix(s)) and prefixMsg = ""
not exists(Prefix::prefix(s)) and prefixMsg = ""
)
}

View File

@@ -138,7 +138,7 @@ module PolynomialReDoS {
/**
* A parameter of an exported function, seen as a source for polynomial-redos.
*/
class ExternalInputSource extends Source, DataFlow::SourceNode {
class ExternalInputSource extends Source {
ExternalInputSource() { this = Exports::getALibraryInputParameter() }
override string getKind() { result = "library" }

View File

@@ -1,3 +1,10 @@
## 0.3.3
### New Queries
* Added a new query, `py/suspicious-regexp-range`, to detect character ranges in regular expressions that seem to match
too many characters.
## 0.3.2
## 0.3.1

View File

@@ -13,4 +13,4 @@ import UnusedParameter
from Parameter p
where isAnAccidentallyUnusedParameter(p)
select p, "Unused parameter " + p.getAVariable().getName() + "."
select p, "The parameter '" + p.getVariable().getName() + "' is never used."

View File

@@ -53,4 +53,4 @@ where
not e instanceof EqualityTest and
e.getRightOperand().getIntValue() = 0 and
not acceptableSignCheck(b)
select e, "Sign check of a bitwise operation"
select e, "Potentially unsafe sign check of a bitwise operation."

View File

@@ -21,5 +21,5 @@ import DataFlow::PathGraph
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "This path depends on $@.", source.getNode(),
"a user-provided value"
select sink.getNode(), source, sink, "$@ flows to here and is used in a path.", source.getNode(),
"User-provided value"

View File

@@ -18,6 +18,6 @@ import DataFlow::PathGraph
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink.getNode(), source, sink,
"Unsanitized zip archive $@, which may contain '..', is used in a file system operation.",
source.getNode(), "item path"
select source.getNode(), source, sink,
"Unsanitized archive entry, which may contain '..', is used in a $@.", sink.getNode(),
"file system operation"

View File

@@ -28,5 +28,5 @@ where
else highlight = sink.getNode()
) and
sourceNode = source.getNode()
select highlight, source, sink, "This command depends on $@.", sourceNode,
select highlight, source, sink, "$@ flows to here and is used in a command.", source.getNode(),
sourceNode.getSourceType()

View File

@@ -16,5 +16,5 @@ import DataFlow::PathGraph
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "$@ flows here and is used in a format string.",
select sink.getNode(), source, sink, "$@ flows to here and is used in a format string.",
source.getNode(), "User-provided value"

View File

@@ -20,55 +20,29 @@ string toOtherCase(string s) {
if s.regexpMatch(".*[a-z].*") then result = s.toUpperCase() else result = s.toLowerCase()
}
RegExpCharacterClass getEnclosingClass(RegExpTerm term) {
term = result.getAChild()
or
term = result.getAChild().(RegExpRange).getAChild()
}
import semmle.javascript.security.regexp.NfaUtils as NfaUtils
/**
* Holds if `term` seems to distinguish between upper and lower case letters, assuming the `i` flag is not present.
*/
pragma[inline]
predicate isLikelyCaseSensitiveRegExp(RegExpTerm term) {
exists(RegExpConstant const |
const = term.getAChild*() and
const.getValue().regexpMatch(".*[a-zA-Z].*") and
not getEnclosingClass(const).getAChild().(RegExpConstant).getValue() =
toOtherCase(const.getValue()) and
not const.getParent*() instanceof RegExpNegativeLookahead and
not const.getParent*() instanceof RegExpNegativeLookbehind
/** Holds if `s` is a relevant regexp term were we want to compute a string that matches the term (for `getCaseSensitiveBypassExample`). */
predicate isCand(NfaUtils::State s) {
s.getRepr() instanceof NfaUtils::RegExpRoot and
exists(DataFlow::RegExpCreationNode creation |
isCaseSensitiveMiddleware(_, creation, _) and
s.getRepr().getRootTerm() = creation.getRoot()
)
}
/**
* Gets a string matched by `term`, or part of such a string.
*/
import NfaUtils::PrefixConstruction<isCand/1> as Prefix
/** Gets a string matched by `term`. */
string getExampleString(RegExpTerm term) {
result = term.getAMatchedString()
or
// getAMatchedString does not recurse into sequences. Perform one step manually.
exists(RegExpSequence seq | seq = term |
result =
strictconcat(RegExpTerm child, int i, string text |
child = seq.getChild(i) and
(
text = child.getAMatchedString()
or
not exists(child.getAMatchedString()) and
text = ""
)
|
text order by i
)
)
result = Prefix::prefix(any(NfaUtils::State s | s.getRepr() = term))
}
string getCaseSensitiveBypassExample(RegExpTerm term) {
exists(string example |
example = getExampleString(term) and
result = toOtherCase(example) and
result != example // getting an example string is approximate; ensure we got a proper case-change example
exists(string byPassExample |
byPassExample = getExampleString(term) and
result = toOtherCase(byPassExample) and
result != byPassExample // getting an byPassExample string is approximate; ensure we got a proper case-change byPassExample
)
}
@@ -89,7 +63,6 @@ predicate isCaseSensitiveMiddleware(
) and
arg = call.getArgument(0) and
regexp.getAReference().flowsTo(arg) and
isLikelyCaseSensitiveRegExp(regexp.getRoot()) and
exists(string flags |
flags = regexp.getFlags() and
not RegExp::isIgnoreCase(flags)
@@ -108,14 +81,64 @@ predicate isGuardedCaseInsensitiveEndpoint(
)
}
/**
* Gets an example path that will hit `endpoint`.
* Query parameters (e.g. the ":param" in "/foo/:param") have been replaced with example values.
*/
string getAnEndpointExample(Routing::RouteSetup endpoint) {
exists(string raw |
raw = endpoint.getRelativePath() and
result = raw.regexpReplaceAll(":\\w+\\b|\\*", ["a", "1"])
)
}
import semmle.javascript.security.regexp.RegexpMatching as RegexpMatching
NfaUtils::RegExpRoot getARoot(DataFlow::RegExpCreationNode creator) {
result.getRootTerm() = creator.getRoot()
}
/**
* Holds if the regexp matcher should test whether `root` matches `str`.
* The result is used to test whether a case-sensitive bypass exists.
*/
predicate isMatchingCandidate(
RegexpMatching::RootTerm root, string str, boolean ignorePrefix, boolean testWithGroups
) {
exists(
Routing::RouteSetup middleware, Routing::RouteSetup endPoint,
DataFlow::RegExpCreationNode regexp
|
isCaseSensitiveMiddleware(middleware, regexp, _) and
isGuardedCaseInsensitiveEndpoint(endPoint, middleware)
|
root = regexp.getRoot() and
exists(getCaseSensitiveBypassExample(getARoot(regexp))) and
ignorePrefix = true and
testWithGroups = false and
str =
[
getCaseSensitiveBypassExample(getARoot(regexp)), getAnEndpointExample(endPoint),
toOtherCase(getAnEndpointExample(endPoint))
]
)
}
import RegexpMatching::RegexpMatching<isMatchingCandidate/4> as Matcher
from
DataFlow::RegExpCreationNode regexp, Routing::RouteSetup middleware, Routing::RouteSetup endpoint,
DataFlow::Node arg, string example
DataFlow::Node arg, string byPassExample, string endpointExample, string byPassEndPoint
where
isCaseSensitiveMiddleware(middleware, regexp, arg) and
example = getCaseSensitiveBypassExample(regexp.getRoot()) and
byPassExample = getCaseSensitiveBypassExample(getARoot(regexp)) and
isGuardedCaseInsensitiveEndpoint(endpoint, middleware) and
exists(endpoint.getRelativePath().toLowerCase().indexOf(example.toLowerCase()))
// only report one example.
endpointExample =
min(string ex | ex = getAnEndpointExample(endpoint) and Matcher::matches(regexp.getRoot(), ex)) and
not Matcher::matches(regexp.getRoot(), byPassExample) and
byPassEndPoint = toOtherCase(endpointExample) and
not Matcher::matches(regexp.getRoot(), byPassEndPoint)
select arg,
"This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '"
+ example + "' will bypass the middleware.", regexp, "pattern", endpoint, "here"
+ byPassEndPoint + "' will bypass the middleware.", regexp, "pattern", endpoint, "here"

View File

@@ -18,5 +18,6 @@ import DataFlow::PathGraph
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Cryptographically insecure $@ in a security context.",
source.getNode(), "random value"
select sink.getNode(), source, sink,
"Cryptographically insecure random number is generated at $@ and used here in a security context.",
source.getNode(), source.getNode().toString()

View File

@@ -17,5 +17,5 @@ import DataFlow::PathGraph
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "$@ flows here and is used in an XPath expression.",
select sink.getNode(), source, sink, "$@ flows to here and is used in an XPath expression.",
source.getNode(), "User-provided value"

View File

@@ -61,8 +61,8 @@ module StaticCreation {
}
/** A script element that refers to untrusted content. */
class CDNScriptElementWithUntrustedContent extends AddsUntrustedUrl, HTML::ScriptElement {
CDNScriptElementWithUntrustedContent() {
class CdnScriptElementWithUntrustedContent extends AddsUntrustedUrl, HTML::ScriptElement {
CdnScriptElementWithUntrustedContent() {
not exists(string digest | not digest = "" | this.getIntegrityDigest() = digest) and
isCdnUrlWithCheckingRequired(this.getSourcePath())
}

View File

@@ -15,16 +15,17 @@ import javascript
/**
* Gets an iteration variable that loop `for` tests and updates.
*/
Variable getAnIterationVariable(ForStmt for) {
Variable getAnIterationVariable(ForStmt for, Expr upAccess) {
result.getAnAccess().getParentExpr*() = for.getTest() and
exists(UpdateExpr upd | upd.getParentExpr*() = for.getUpdate() |
upd.getOperand() = result.getAnAccess()
upAccess = upd.getOperand() and upAccess = result.getAnAccess()
)
}
from ForStmt outer, ForStmt inner
from ForStmt outer, ForStmt inner, Variable iteration, Expr upAccess
where
inner.nestedIn(outer) and
getAnIterationVariable(outer) = getAnIterationVariable(inner)
select inner.getTest(), "This for statement uses the same loop variable as an enclosing $@.", outer,
"for statement"
iteration = getAnIterationVariable(outer, _) and
iteration = getAnIterationVariable(inner, upAccess)
select inner.getTest(), "Nested for statement uses loop variable $@ of enclosing $@.", upAccess,
iteration.getName(), outer, "for statement"

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The alert message of many queries have been changed to make the message consistent with other languages.

View File

@@ -1,5 +1,6 @@
---
category: newQuery
---
## 0.3.3
### New Queries
* Added a new query, `py/suspicious-regexp-range`, to detect character ranges in regular expressions that seem to match
too many characters.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.3.2
lastReleaseVersion: 0.3.3

View File

@@ -78,9 +78,9 @@ class ProbableJob extends Actions::Job {
/**
* An action step that doesn't contain `actor` or `label` check in `if:` or
*/
class ProbablePullRequestTarget extends Actions::On, YAMLMappingLikeNode {
class ProbablePullRequestTarget extends Actions::On, YamlMappingLikeNode {
ProbablePullRequestTarget() {
exists(YAMLNode prtNode |
exists(YamlNode prtNode |
// The `on:` is triggered on `pull_request_target`
this.getNode("pull_request_target") = prtNode and
(
@@ -88,7 +88,7 @@ class ProbablePullRequestTarget extends Actions::On, YAMLMappingLikeNode {
not exists(prtNode.getAChild())
or
// or has the filter, that is something else than just [labeled]
exists(YAMLMappingLikeNode prt, YAMLMappingLikeNode types |
exists(YamlMappingLikeNode prt, YamlMappingLikeNode types |
types = prt.getNode("types") and
prtNode = prt and
(

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-queries
version: 0.3.3-dev
version: 0.3.4-dev
groups:
- javascript
- queries

View File

@@ -15,11 +15,13 @@ basicBlock
| arguments.js:1:1:12:4 | (functi ... );\\n})() | arguments.js:1:1:1:0 | entry node of <toplevel> |
| arguments.js:1:1:12:4 | exceptional return of (functi ... );\\n})() | arguments.js:1:1:1:0 | entry node of <toplevel> |
| arguments.js:1:2:1:1 | this | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} |
| arguments.js:1:2:12:1 | 'arguments' object of anonymous function | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} |
| arguments.js:1:2:12:1 | exceptional return of anonymous function | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} |
| arguments.js:1:2:12:1 | functio ... , 3);\\n} | arguments.js:1:1:1:0 | entry node of <toplevel> |
| arguments.js:1:2:12:1 | return of anonymous function | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} |
| arguments.js:2:5:2:4 | this | arguments.js:2:5:2:4 | entry node of functio ... ;\\n } |
| arguments.js:2:5:2:5 | arguments | arguments.js:2:5:2:4 | entry node of functio ... ;\\n } |
| arguments.js:2:5:10:5 | 'arguments' object of function f | arguments.js:2:5:2:4 | entry node of functio ... ;\\n } |
| arguments.js:2:5:10:5 | exceptional return of function f | arguments.js:2:5:2:4 | entry node of functio ... ;\\n } |
| arguments.js:2:5:10:5 | functio ... ;\\n } | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} |
| arguments.js:2:5:10:5 | return of function f | arguments.js:2:5:2:4 | entry node of functio ... ;\\n } |
@@ -66,6 +68,7 @@ basicBlock
| arguments.js:11:13:11:13 | 3 | arguments.js:1:2:1:1 | entry node of functio ... , 3);\\n} |
| eval.js:1:1:1:0 | this | eval.js:1:1:1:0 | entry node of <toplevel> |
| eval.js:1:1:1:0 | this | eval.js:1:1:1:0 | entry node of functio ... eval`\\n} |
| eval.js:1:1:5:1 | 'arguments' object of function k | eval.js:1:1:1:0 | entry node of functio ... eval`\\n} |
| eval.js:1:1:5:1 | exceptional return of function k | eval.js:1:1:1:0 | entry node of functio ... eval`\\n} |
| eval.js:1:1:5:1 | functio ... eval`\\n} | eval.js:1:1:1:0 | entry node of <toplevel> |
| eval.js:1:1:5:1 | return of function k | eval.js:1:1:1:0 | entry node of functio ... eval`\\n} |
@@ -85,6 +88,7 @@ basicBlock
| sources.js:1:5:1:12 | (x => x) | sources.js:1:1:1:0 | entry node of <toplevel> |
| sources.js:1:6:1:6 | x | sources.js:1:6:1:5 | entry node of x => x |
| sources.js:1:6:1:6 | x | sources.js:1:6:1:5 | entry node of x => x |
| sources.js:1:6:1:11 | 'arguments' object of anonymous function | sources.js:1:6:1:5 | entry node of x => x |
| sources.js:1:6:1:11 | exceptional return of anonymous function | sources.js:1:6:1:5 | entry node of x => x |
| sources.js:1:6:1:11 | return of anonymous function | sources.js:1:6:1:5 | entry node of x => x |
| sources.js:1:6:1:11 | x => x | sources.js:1:1:1:0 | entry node of <toplevel> |
@@ -93,6 +97,7 @@ basicBlock
| sources.js:3:1:5:6 | (functi ... \\n})(23) | sources.js:1:1:1:0 | entry node of <toplevel> |
| sources.js:3:1:5:6 | exceptional return of (functi ... \\n})(23) | sources.js:1:1:1:0 | entry node of <toplevel> |
| sources.js:3:2:3:1 | this | sources.js:3:2:3:1 | entry node of functio ... x+19;\\n} |
| sources.js:3:2:5:1 | 'arguments' object of anonymous function | sources.js:3:2:3:1 | entry node of functio ... x+19;\\n} |
| sources.js:3:2:5:1 | exceptional return of anonymous function | sources.js:3:2:3:1 | entry node of functio ... x+19;\\n} |
| sources.js:3:2:5:1 | functio ... x+19;\\n} | sources.js:1:1:1:0 | entry node of <toplevel> |
| sources.js:3:2:5:1 | return of anonymous function | sources.js:3:2:3:1 | entry node of functio ... x+19;\\n} |
@@ -104,6 +109,7 @@ basicBlock
| sources.js:5:4:5:5 | 23 | sources.js:1:1:1:0 | entry node of <toplevel> |
| sources.js:7:1:7:3 | /x/ | sources.js:1:1:1:0 | entry node of <toplevel> |
| sources.js:9:1:9:0 | this | sources.js:9:1:9:0 | entry node of functio ... ey; }\\n} |
| sources.js:9:1:12:1 | 'arguments' object of function foo | sources.js:9:1:9:0 | entry node of functio ... ey; }\\n} |
| sources.js:9:1:12:1 | exceptional return of function foo | sources.js:12:2:12:1 | exit node of functio ... ey; }\\n} |
| sources.js:9:1:12:1 | functio ... ey; }\\n} | sources.js:1:1:1:0 | entry node of <toplevel> |
| sources.js:9:1:12:1 | return of function foo | sources.js:12:2:12:1 | exit node of functio ... ey; }\\n} |
@@ -140,6 +146,7 @@ basicBlock
| tst2.ts:4:3:4:3 | x | tst2.ts:1:1:1:0 | entry node of <toplevel> |
| tst2.ts:7:1:7:0 | A | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} |
| tst2.ts:7:1:7:0 | this | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} |
| tst2.ts:7:1:9:1 | 'arguments' object of function setX | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} |
| tst2.ts:7:1:9:1 | exceptional return of function setX | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} |
| tst2.ts:7:1:9:1 | functio ... = 23;\\n} | tst2.ts:1:1:1:0 | entry node of <toplevel> |
| tst2.ts:7:1:9:1 | return of function setX | tst2.ts:7:1:7:0 | entry node of functio ... = 23;\\n} |
@@ -160,6 +167,7 @@ basicBlock
| tst2.ts:13:7:13:16 | StringList | tst2.ts:1:1:1:0 | entry node of <toplevel> |
| tst2.ts:13:26:13:29 | List | tst2.ts:1:1:1:0 | entry node of <toplevel> |
| tst2.ts:13:26:13:37 | List<string> | tst2.ts:1:1:1:0 | entry node of <toplevel> |
| tst2.ts:13:39:13:38 | 'arguments' object of default constructor of class StringList | tst2.ts:13:39:13:38 | entry node of (...arg ... rgs); } |
| tst2.ts:13:39:13:38 | (...arg ... rgs); } | tst2.ts:1:1:1:0 | entry node of <toplevel> |
| tst2.ts:13:39:13:38 | ...args | tst2.ts:13:39:13:38 | entry node of (...arg ... rgs); } |
| tst2.ts:13:39:13:38 | args | tst2.ts:13:39:13:38 | entry node of (...arg ... rgs); } |
@@ -221,6 +229,7 @@ basicBlock
| tst.js:16:1:20:9 | (functi ... ("arg") | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:16:1:20:9 | exceptional return of (functi ... ("arg") | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:16:2:16:1 | this | tst.js:16:2:16:1 | entry node of functio ... n "";\\n} |
| tst.js:16:2:20:1 | 'arguments' object of function f | tst.js:16:2:16:1 | entry node of functio ... n "";\\n} |
| tst.js:16:2:20:1 | exceptional return of function f | tst.js:20:2:20:1 | exit node of functio ... n "";\\n} |
| tst.js:16:2:20:1 | functio ... n "";\\n} | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:16:2:20:1 | return of function f | tst.js:20:2:20:1 | exit node of functio ... n "";\\n} |
@@ -254,12 +263,14 @@ basicBlock
| tst.js:28:1:30:3 | (() =>\\n ... les\\n)() | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:28:1:30:3 | exceptional return of (() =>\\n ... les\\n)() | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:28:2:28:1 | x | tst.js:28:2:28:1 | entry node of () =>\\n x |
| tst.js:28:2:29:3 | 'arguments' object of anonymous function | tst.js:28:2:28:1 | entry node of () =>\\n x |
| tst.js:28:2:29:3 | () =>\\n x | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:28:2:29:3 | exceptional return of anonymous function | tst.js:28:2:28:1 | entry node of () =>\\n x |
| tst.js:28:2:29:3 | return of anonymous function | tst.js:28:2:28:1 | entry node of () =>\\n x |
| tst.js:29:3:29:3 | x | tst.js:28:2:28:1 | entry node of () =>\\n x |
| tst.js:32:1:32:0 | this | tst.js:32:1:32:0 | entry node of functio ... ables\\n} |
| tst.js:32:1:32:0 | x | tst.js:32:1:32:0 | entry node of functio ... ables\\n} |
| tst.js:32:1:34:1 | 'arguments' object of function g | tst.js:32:1:32:0 | entry node of functio ... ables\\n} |
| tst.js:32:1:34:1 | exceptional return of function g | tst.js:32:1:32:0 | entry node of functio ... ables\\n} |
| tst.js:32:1:34:1 | functio ... ables\\n} | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:32:1:34:1 | return of function g | tst.js:32:1:32:0 | entry node of functio ... ables\\n} |
@@ -283,6 +294,7 @@ basicBlock
| tst.js:39:3:41:3 | m() {\\n this;\\n } | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:39:3:41:3 | m() {\\n this;\\n } | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:39:4:39:3 | this | tst.js:39:4:39:3 | entry node of () {\\n this;\\n } |
| tst.js:39:4:41:3 | 'arguments' object of method m | tst.js:39:4:39:3 | entry node of () {\\n this;\\n } |
| tst.js:39:4:41:3 | () {\\n this;\\n } | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:39:4:41:3 | exceptional return of method m | tst.js:39:4:39:3 | entry node of () {\\n this;\\n } |
| tst.js:39:4:41:3 | return of method m | tst.js:39:4:39:3 | entry node of () {\\n this;\\n } |
@@ -307,6 +319,7 @@ basicBlock
| tst.js:50:3:53:3 | constru ... et`\\n } | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:50:3:53:3 | constru ... et`\\n } | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:50:14:50:13 | this | tst.js:50:14:50:13 | entry node of () {\\n ... et`\\n } |
| tst.js:50:14:53:3 | 'arguments' object of constructor of class A | tst.js:50:14:50:13 | entry node of () {\\n ... et`\\n } |
| tst.js:50:14:53:3 | () {\\n ... et`\\n } | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:50:14:53:3 | exceptional return of constructor of class A | tst.js:50:14:50:13 | entry node of () {\\n ... et`\\n } |
| tst.js:50:14:53:3 | return of constructor of class A | tst.js:50:14:50:13 | entry node of () {\\n ... et`\\n } |
@@ -333,6 +346,7 @@ basicBlock
| tst.js:62:1:62:4 | o::g | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:62:4:62:4 | g | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:64:1:64:0 | this | tst.js:64:1:64:0 | entry node of functio ... lysed\\n} |
| tst.js:64:1:67:1 | 'arguments' object of function h | tst.js:64:1:64:0 | entry node of functio ... lysed\\n} |
| tst.js:64:1:67:1 | exceptional return of function h | tst.js:64:1:64:0 | entry node of functio ... lysed\\n} |
| tst.js:64:1:67:1 | functio ... lysed\\n} | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:64:1:67:1 | return of function h | tst.js:64:1:64:0 | entry node of functio ... lysed\\n} |
@@ -356,6 +370,7 @@ basicBlock
| tst.js:69:6:69:9 | next | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:69:11:69:12 | 23 | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:71:1:71:0 | this | tst.js:71:1:71:0 | entry node of async f ... lysed\\n} |
| tst.js:71:1:73:1 | 'arguments' object of function k | tst.js:71:1:71:0 | entry node of async f ... lysed\\n} |
| tst.js:71:1:73:1 | async f ... lysed\\n} | tst.js:16:1:20:10 | (functi ... "arg"); |
| tst.js:71:1:73:1 | exceptional return of function k | tst.js:71:1:71:0 | entry node of async f ... lysed\\n} |
| tst.js:71:1:73:1 | return of function k | tst.js:71:1:71:0 | entry node of async f ... lysed\\n} |
@@ -398,6 +413,7 @@ basicBlock
| tst.js:87:1:96:2 | (functi ... r: 0\\n}) | tst.js:85:5:85:28 | vs2 = ( ... o) v ) |
| tst.js:87:1:96:2 | exceptional return of (functi ... r: 0\\n}) | tst.js:85:5:85:28 | vs2 = ( ... o) v ) |
| tst.js:87:2:87:1 | this | tst.js:87:2:87:1 | entry node of functio ... + z;\\n} |
| tst.js:87:2:92:1 | 'arguments' object of anonymous function | tst.js:87:2:87:1 | entry node of functio ... + z;\\n} |
| tst.js:87:2:92:1 | exceptional return of anonymous function | tst.js:87:2:87:1 | entry node of functio ... + z;\\n} |
| tst.js:87:2:92:1 | functio ... + z;\\n} | tst.js:85:5:85:28 | vs2 = ( ... o) v ) |
| tst.js:87:2:92:1 | return of anonymous function | tst.js:87:2:87:1 | entry node of functio ... + z;\\n} |
@@ -451,6 +467,7 @@ basicBlock
| tst.js:98:1:103:17 | (functi ... 3, 0 ]) | tst.js:85:5:85:28 | vs2 = ( ... o) v ) |
| tst.js:98:1:103:17 | exceptional return of (functi ... 3, 0 ]) | tst.js:85:5:85:28 | vs2 = ( ... o) v ) |
| tst.js:98:2:98:1 | this | tst.js:98:2:98:1 | entry node of functio ... + z;\\n} |
| tst.js:98:2:103:1 | 'arguments' object of anonymous function | tst.js:98:2:98:1 | entry node of functio ... + z;\\n} |
| tst.js:98:2:103:1 | exceptional return of anonymous function | tst.js:98:2:98:1 | entry node of functio ... + z;\\n} |
| tst.js:98:2:103:1 | functio ... + z;\\n} | tst.js:85:5:85:28 | vs2 = ( ... o) v ) |
| tst.js:98:2:103:1 | return of anonymous function | tst.js:98:2:98:1 | entry node of functio ... + z;\\n} |
@@ -492,6 +509,7 @@ basicBlock
| tst.js:105:6:105:6 | y | tst.js:105:6:105:6 | y |
| tst.js:107:1:113:2 | (functi ... v2c;\\n}) | tst.js:107:1:113:3 | (functi ... 2c;\\n}); |
| tst.js:107:2:107:1 | this | tst.js:107:2:107:1 | entry node of functio ... v2c;\\n} |
| tst.js:107:2:113:1 | 'arguments' object of anonymous function | tst.js:107:2:107:1 | entry node of functio ... v2c;\\n} |
| tst.js:107:2:113:1 | exceptional return of anonymous function | tst.js:107:2:107:1 | entry node of functio ... v2c;\\n} |
| tst.js:107:2:113:1 | functio ... v2c;\\n} | tst.js:107:1:113:3 | (functi ... 2c;\\n}); |
| tst.js:107:2:113:1 | return of anonymous function | tst.js:107:2:107:1 | entry node of functio ... v2c;\\n} |
@@ -918,6 +936,11 @@ flowStep
| arguments.js:2:5:2:5 | arguments | arguments.js:4:28:4:36 | arguments |
| arguments.js:2:5:2:5 | arguments | arguments.js:5:25:5:33 | arguments |
| arguments.js:2:5:2:5 | arguments | arguments.js:6:20:6:28 | arguments |
| arguments.js:2:5:10:5 | 'arguments' object of function f | arguments.js:4:28:4:36 | arguments |
| arguments.js:2:5:10:5 | 'arguments' object of function f | arguments.js:5:25:5:33 | arguments |
| arguments.js:2:5:10:5 | 'arguments' object of function f | arguments.js:6:20:6:28 | arguments |
| arguments.js:2:5:10:5 | 'arguments' object of function f | arguments.js:8:9:8:17 | arguments |
| arguments.js:2:5:10:5 | 'arguments' object of function f | arguments.js:9:27:9:35 | arguments |
| arguments.js:2:5:10:5 | functio ... ;\\n } | arguments.js:2:14:2:14 | f |
| arguments.js:2:14:2:14 | f | arguments.js:11:5:11:5 | f |
| arguments.js:2:16:2:16 | x | arguments.js:2:16:2:16 | x |
@@ -1421,9 +1444,11 @@ sources
| arguments.js:1:1:1:0 | this |
| arguments.js:1:1:12:4 | (functi ... );\\n})() |
| arguments.js:1:2:1:1 | this |
| arguments.js:1:2:12:1 | 'arguments' object of anonymous function |
| arguments.js:1:2:12:1 | functio ... , 3);\\n} |
| arguments.js:1:2:12:1 | return of anonymous function |
| arguments.js:2:5:2:4 | this |
| arguments.js:2:5:10:5 | 'arguments' object of function f |
| arguments.js:2:5:10:5 | functio ... ;\\n } |
| arguments.js:2:5:10:5 | return of function f |
| arguments.js:2:16:2:16 | x |
@@ -1435,6 +1460,7 @@ sources
| arguments.js:11:5:11:14 | f(1, 2, 3) |
| eval.js:1:1:1:0 | this |
| eval.js:1:1:1:0 | this |
| eval.js:1:1:5:1 | 'arguments' object of function k |
| eval.js:1:1:5:1 | functio ... eval`\\n} |
| eval.js:1:1:5:1 | return of function k |
| eval.js:3:3:3:6 | eval |
@@ -1444,15 +1470,18 @@ sources
| sources.js:1:1:1:0 | this |
| sources.js:1:1:1:12 | new (x => x) |
| sources.js:1:6:1:6 | x |
| sources.js:1:6:1:11 | 'arguments' object of anonymous function |
| sources.js:1:6:1:11 | return of anonymous function |
| sources.js:1:6:1:11 | x => x |
| sources.js:3:1:5:6 | (functi ... \\n})(23) |
| sources.js:3:2:3:1 | this |
| sources.js:3:2:5:1 | 'arguments' object of anonymous function |
| sources.js:3:2:5:1 | functio ... x+19;\\n} |
| sources.js:3:2:5:1 | return of anonymous function |
| sources.js:3:11:3:11 | x |
| sources.js:7:1:7:3 | /x/ |
| sources.js:9:1:9:0 | this |
| sources.js:9:1:12:1 | 'arguments' object of function foo |
| sources.js:9:1:12:1 | functio ... ey; }\\n} |
| sources.js:9:1:12:1 | return of function foo |
| sources.js:9:14:9:18 | array |
@@ -1462,12 +1491,14 @@ sources
| tst2.ts:1:1:1:0 | this |
| tst2.ts:3:3:3:8 | setX() |
| tst2.ts:7:1:7:0 | this |
| tst2.ts:7:1:9:1 | 'arguments' object of function setX |
| tst2.ts:7:1:9:1 | functio ... = 23;\\n} |
| tst2.ts:7:1:9:1 | return of function setX |
| tst2.ts:8:3:8:5 | A.x |
| tst2.ts:11:11:11:13 | A.x |
| tst2.ts:13:1:13:40 | class S ... ing> {} |
| tst2.ts:13:26:13:29 | List |
| tst2.ts:13:39:13:38 | 'arguments' object of default constructor of class StringList |
| tst2.ts:13:39:13:38 | (...arg ... rgs); } |
| tst2.ts:13:39:13:38 | args |
| tst2.ts:13:39:13:38 | return of default constructor of class StringList |
@@ -1480,6 +1511,7 @@ sources
| tst.js:4:9:4:12 | "hi" |
| tst.js:16:1:20:9 | (functi ... ("arg") |
| tst.js:16:2:16:1 | this |
| tst.js:16:2:20:1 | 'arguments' object of function f |
| tst.js:16:2:20:1 | functio ... n "";\\n} |
| tst.js:16:2:20:1 | return of function f |
| tst.js:16:13:16:13 | a |
@@ -1490,15 +1522,18 @@ sources
| tst.js:20:4:20:8 | "arg" |
| tst.js:22:7:22:18 | readFileSync |
| tst.js:28:1:30:3 | (() =>\\n ... les\\n)() |
| tst.js:28:2:29:3 | 'arguments' object of anonymous function |
| tst.js:28:2:29:3 | () =>\\n x |
| tst.js:28:2:29:3 | return of anonymous function |
| tst.js:32:1:32:0 | this |
| tst.js:32:1:34:1 | 'arguments' object of function g |
| tst.js:32:1:34:1 | functio ... ables\\n} |
| tst.js:32:1:34:1 | return of function g |
| tst.js:32:12:32:12 | b |
| tst.js:35:1:35:7 | g(true) |
| tst.js:37:9:42:1 | {\\n x: ... ;\\n }\\n} |
| tst.js:39:4:39:3 | this |
| tst.js:39:4:41:3 | 'arguments' object of method m |
| tst.js:39:4:41:3 | () {\\n this;\\n } |
| tst.js:39:4:41:3 | return of method m |
| tst.js:43:1:43:3 | o.x |
@@ -1510,6 +1545,7 @@ sources
| tst.js:49:1:54:1 | class A ... `\\n }\\n} |
| tst.js:49:17:49:17 | B |
| tst.js:50:14:50:13 | this |
| tst.js:50:14:53:3 | 'arguments' object of constructor of class A |
| tst.js:50:14:53:3 | () {\\n ... et`\\n } |
| tst.js:50:14:53:3 | return of constructor of class A |
| tst.js:51:5:51:13 | super(42) |
@@ -1519,6 +1555,7 @@ sources
| tst.js:61:3:61:5 | o.m |
| tst.js:62:1:62:4 | o::g |
| tst.js:64:1:64:0 | this |
| tst.js:64:1:67:1 | 'arguments' object of function h |
| tst.js:64:1:67:1 | functio ... lysed\\n} |
| tst.js:64:1:67:1 | return of function h |
| tst.js:65:3:65:10 | yield 42 |
@@ -1527,6 +1564,7 @@ sources
| tst.js:69:1:69:9 | iter.next |
| tst.js:69:1:69:13 | iter.next(23) |
| tst.js:71:1:71:0 | this |
| tst.js:71:1:73:1 | 'arguments' object of function k |
| tst.js:71:1:73:1 | async f ... lysed\\n} |
| tst.js:71:1:73:1 | return of function k |
| tst.js:72:3:72:11 | await p() |
@@ -1539,6 +1577,7 @@ sources
| tst.js:85:11:85:28 | ( for (v of o) v ) |
| tst.js:87:1:96:2 | (functi ... r: 0\\n}) |
| tst.js:87:2:87:1 | this |
| tst.js:87:2:92:1 | 'arguments' object of anonymous function |
| tst.js:87:2:92:1 | functio ... + z;\\n} |
| tst.js:87:2:92:1 | return of anonymous function |
| tst.js:87:11:87:24 | { p: x, ...o } |
@@ -1549,6 +1588,7 @@ sources
| tst.js:92:4:96:1 | {\\n p: ... r: 0\\n} |
| tst.js:98:1:103:17 | (functi ... 3, 0 ]) |
| tst.js:98:2:98:1 | this |
| tst.js:98:2:103:1 | 'arguments' object of anonymous function |
| tst.js:98:2:103:1 | functio ... + z;\\n} |
| tst.js:98:2:103:1 | return of anonymous function |
| tst.js:98:11:98:24 | [ x, ...rest ] |
@@ -1558,6 +1598,7 @@ sources
| tst.js:101:7:101:7 | z |
| tst.js:103:4:103:16 | [ 19, 23, 0 ] |
| tst.js:107:2:107:1 | this |
| tst.js:107:2:113:1 | 'arguments' object of anonymous function |
| tst.js:107:2:113:1 | functio ... v2c;\\n} |
| tst.js:107:2:113:1 | return of anonymous function |
| tst.js:108:7:108:9 | v1a |

View File

@@ -14,6 +14,7 @@ dataFlow
| callback.js:16:14:16:21 | "source" | callback.js:13:14:13:14 | x |
| callback.js:17:15:17:23 | "source2" | callback.js:13:14:13:14 | x |
| callback.js:27:15:27:23 | "source3" | callback.js:13:14:13:14 | x |
| destructuring.js:2:16:2:24 | "tainted" | destructuring.js:5:14:5:20 | tainted |
| destructuring.js:2:16:2:24 | "tainted" | destructuring.js:9:15:9:22 | tainted2 |
| destructuring.js:19:15:19:23 | "tainted" | destructuring.js:14:15:14:15 | p |
| destructuring.js:20:15:20:28 | "also tainted" | destructuring.js:15:15:15:15 | r |
@@ -201,6 +202,7 @@ germanFlow
| callback.js:17:15:17:23 | "source2" | callback.js:13:14:13:14 | x |
| callback.js:27:15:27:23 | "source3" | callback.js:13:14:13:14 | x |
| custom.js:1:14:1:26 | "verschmutzt" | custom.js:2:15:2:20 | quelle |
| destructuring.js:2:16:2:24 | "tainted" | destructuring.js:5:14:5:20 | tainted |
| destructuring.js:2:16:2:24 | "tainted" | destructuring.js:9:15:9:22 | tainted2 |
| destructuring.js:19:15:19:23 | "tainted" | destructuring.js:14:15:14:15 | p |
| destructuring.js:20:15:20:28 | "also tainted" | destructuring.js:15:15:15:15 | r |

View File

@@ -1,4 +1,15 @@
typeInferenceMismatch
| call-apply.js:27:14:27:21 | source() | call-apply.js:3:1:5:1 | 'arguments' object of function foo1 |
| call-apply.js:27:14:27:21 | source() | call-apply.js:7:1:9:1 | 'arguments' object of function foo2 |
| call-apply.js:27:14:27:21 | source() | call-apply.js:12:10:12:30 | reflective call |
| call-apply.js:27:14:27:21 | source() | call-apply.js:16:10:16:40 | reflective call |
| call-apply.js:27:14:27:21 | source() | call-apply.js:23:1:25:1 | 'arguments' object of function foo1_sink |
| call-apply.js:27:14:27:21 | source() | call-apply.js:29:6:29:32 | reflective call |
| call-apply.js:27:14:27:21 | source() | call-apply.js:32:6:32:35 | reflective call |
| call-apply.js:27:14:27:21 | source() | call-apply.js:33:6:33:35 | reflective call |
| call-apply.js:27:14:27:21 | source() | call-apply.js:64:3:66:3 | 'arguments' object of function sinkArguments1 |
| call-apply.js:27:14:27:21 | source() | call-apply.js:67:3:69:3 | 'arguments' object of function sinkArguments0 |
| call-apply.js:27:14:27:21 | source() | call-apply.js:71:3:74:3 | 'arguments' object of function fowardArguments |
| destruct.js:20:7:20:14 | source() | destruct.js:13:14:13:19 | [a, b] |
#select
| access-path-sanitizer.js:2:18:2:25 | source() | access-path-sanitizer.js:4:8:4:12 | obj.x |
@@ -12,6 +23,19 @@ typeInferenceMismatch
| array-mutation.js:31:33:31:40 | source() | array-mutation.js:32:8:32:8 | h |
| array-mutation.js:35:36:35:43 | source() | array-mutation.js:36:8:36:8 | i |
| array-mutation.js:39:17:39:24 | source() | array-mutation.js:40:8:40:8 | j |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:17:8:17:13 | arr[1] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:22:8:22:13 | arr[6] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:27:8:27:13 | arr[0] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:28:8:28:13 | arr[1] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:33:8:33:13 | arr[0] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:34:8:34:13 | arr[1] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:35:8:35:13 | arr[2] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:36:8:36:13 | arr[3] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:37:8:37:13 | arr[4] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:38:8:38:13 | arr[5] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:43:10:43:15 | arr[i] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:55:10:55:15 | arr[i] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:61:10:61:13 | item |
| arrays.js:2:15:2:22 | source() | arrays.js:5:10:5:20 | arrify(foo) |
| arrays.js:2:15:2:22 | source() | arrays.js:8:10:8:22 | arrayIfy(foo) |
| arrays.js:2:15:2:22 | source() | arrays.js:11:10:11:28 | union(["bla"], foo) |
@@ -28,6 +52,16 @@ typeInferenceMismatch
| bound-function.js:45:10:45:17 | source() | bound-function.js:45:6:45:18 | id3(source()) |
| bound-function.js:49:12:49:19 | source() | bound-function.js:54:6:54:14 | source0() |
| bound-function.js:49:12:49:19 | source() | bound-function.js:55:6:55:14 | source1() |
| call-apply.js:27:14:27:21 | source() | call-apply.js:24:8:24:11 | arg1 |
| call-apply.js:27:14:27:21 | source() | call-apply.js:29:6:29:32 | foo1.ca ... ce, "") |
| call-apply.js:27:14:27:21 | source() | call-apply.js:32:6:32:35 | foo1.ap ... e, ""]) |
| call-apply.js:27:14:27:21 | source() | call-apply.js:33:6:33:35 | foo2.ap ... e, ""]) |
| call-apply.js:27:14:27:21 | source() | call-apply.js:40:6:40:29 | foo1_ap ... e, ""]) |
| call-apply.js:27:14:27:21 | source() | call-apply.js:46:6:46:28 | foo1_ca ... e, ""]) |
| call-apply.js:27:14:27:21 | source() | call-apply.js:47:6:47:28 | foo1_ca ... ource]) |
| call-apply.js:27:14:27:21 | source() | call-apply.js:65:10:65:21 | arguments[1] |
| call-apply.js:27:14:27:21 | source() | call-apply.js:68:10:68:21 | arguments[0] |
| call-apply.js:87:17:87:24 | source() | call-apply.js:84:8:84:11 | this |
| callbacks.js:4:6:4:13 | source() | callbacks.js:34:27:34:27 | x |
| callbacks.js:4:6:4:13 | source() | callbacks.js:35:27:35:27 | x |
| callbacks.js:5:6:5:13 | source() | callbacks.js:34:27:34:27 | x |

View File

@@ -1,5 +1,12 @@
| access-path-sanitizer.js:2:18:2:25 | source() | access-path-sanitizer.js:4:8:4:12 | obj.x |
| advanced-callgraph.js:2:13:2:20 | source() | advanced-callgraph.js:6:22:6:22 | v |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:17:8:17:13 | arr[1] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:22:8:22:13 | arr[6] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:28:8:28:13 | arr[1] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:34:8:34:13 | arr[1] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:43:10:43:15 | arr[i] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:55:10:55:15 | arr[i] |
| arrays-init.js:2:16:2:23 | source() | arrays-init.js:61:10:61:13 | item |
| booleanOps.js:2:11:2:18 | source() | booleanOps.js:4:8:4:8 | x |
| booleanOps.js:2:11:2:18 | source() | booleanOps.js:7:10:7:10 | x |
| booleanOps.js:2:11:2:18 | source() | booleanOps.js:10:10:10:10 | x |
@@ -12,6 +19,12 @@
| bound-function.js:45:10:45:17 | source() | bound-function.js:45:6:45:18 | id3(source()) |
| bound-function.js:49:12:49:19 | source() | bound-function.js:54:6:54:14 | source0() |
| bound-function.js:49:12:49:19 | source() | bound-function.js:55:6:55:14 | source1() |
| call-apply.js:27:14:27:21 | source() | call-apply.js:24:8:24:11 | arg1 |
| call-apply.js:27:14:27:21 | source() | call-apply.js:29:6:29:32 | foo1.ca ... ce, "") |
| call-apply.js:27:14:27:21 | source() | call-apply.js:32:6:32:35 | foo1.ap ... e, ""]) |
| call-apply.js:27:14:27:21 | source() | call-apply.js:46:6:46:28 | foo1_ca ... e, ""]) |
| call-apply.js:27:14:27:21 | source() | call-apply.js:68:10:68:21 | arguments[0] |
| call-apply.js:87:17:87:24 | source() | call-apply.js:84:8:84:11 | this |
| callbacks.js:4:6:4:13 | source() | callbacks.js:34:27:34:27 | x |
| callbacks.js:4:6:4:13 | source() | callbacks.js:35:27:35:27 | x |
| callbacks.js:5:6:5:13 | source() | callbacks.js:34:27:34:27 | x |

View File

@@ -0,0 +1,63 @@
(function () {
let source = source();
var str = "FALSE";
console.log("=== access by index (init by ctor) ===");
var arr = new Array(2);
arr[0] = str;
arr[1] = source;
arr[2] = 'b';
arr[3] = 'c';
arr[4] = 'd';
arr[5] = 'e';
arr[6] = source;
sink(arr[0]); // OK
sink(arr[1]); // NOT OK
sink(arr[2]); // OK
sink(arr[3]); // OK
sink(arr[4]); // OK
sink(arr[5]); // OK
sink(arr[6]); // NOT OK
sink(str); // OK
console.log("=== access by index (init by [...]) ===");
var arr = [str, source];
sink(arr[0]); // OK
sink(arr[1]); // NOT OK
sink(str); // OK
console.log("=== access by index (init by [...], array.lenght > 5) ===");
var arr = [str, source, 'b', 'c', 'd', source];
sink(arr[0]); // OK
sink(arr[1]); // NOT OK
sink(arr[2]); // OK
sink(arr[3]); // OK
sink(arr[4]); // OK
sink(arr[5]); // NOT OK - but not flagged [INCONSISTENCY]
console.log("=== access in for (init by [...]) ===");
var arr = [str, source];
for (let i = 0; i < arr.length; i++) {
sink(arr[i]); // NOT OK
}
console.log("=== access in for (init by [...]) w/o source ===");
var arr = [str, 'a'];
for (let i = 0; i < arr.length; i++) {
sink(arr[i]); // OK
}
console.log("=== access in for (init by [...], array.lenght > 5) ===");
var arr = [str, 'a', 'b', 'c', 'd', source];
for (let i = 0; i < arr.length; i++) {
sink(arr[i]); // NOT OK
}
console.log("=== access in forof (init by [...]) ===");
var arr = [str, source];
for (const item of arr) {
sink(item); // NOT OK
}
}());

View File

@@ -0,0 +1,87 @@
import * as foolib from 'foolib';
function foo1(arg1, arg2) {
return arg1;
}
function foo2(arg1, arg2) {
return arg2;
}
function foo1_apply(arr) {
return foo1.apply(this, arr);
}
function foo1_call(arr) {
return foo1.call(this, arr[0], arr[1]);
}
function foo1_apply_sink(arr) {
foo1_sink.apply(this, arr);
}
function foo1_sink(arg1, arg2) {
sink(arg1); // NOT OK
}
var source = source();
sink(foo1.call(null, source, "")); // NOT OK
sink(foo2.call(null, source, "")); // OK
sink(foo1.apply(null, [source, ""])); // NOT OK
sink(foo2.apply(null, [source, ""])); // OK
// doesn't work due to fundamental limitations of our dataflow analysis.
// exactly (and I mean exactly) the same thing happens in the below `obj.foo` example.
// in general we don't track flow that first goes through a call, and then a return, unless we can summarize it.
// in the other examples we can summarize the flow, because it's quite simple, but here we can't.
// (try to read the QLDoc in the top of `Configuration.qll`, that might help).
sink(foo1_apply([source, ""])); // NOT OK - but not flagged [INCONSISTENCY]
foo1_apply_sink([source, ""]); // This works, because we don't need a return after a call (the sink is inside the called function).
sink(foo1_apply.apply(["", source])); // OK
sink(foo1_call([source, ""])); // NOT OK
sink(foo1_call(["", source])); // OK
var obj = {
foo: source(),
bar: "safe"
};
function foo(x) {
return bar(x);
}
function bar(x) {
return x.foo;
}
sink(foo(obj)); // NOT OK - but not flagged [INCONSISTENCY]
function argumentsObject() {
function sinkArguments1() {
sink(arguments[1]); // OK
}
function sinkArguments0() {
sink(arguments[0]); // NOT OK
}
function fowardArguments() {
sinkArguments1.apply(this, arguments);
sinkArguments0.apply(this, arguments);
}
fowardArguments.apply(this, [source, ""]);
}
function sinksThis() {
sinksThis2.apply(this, arguments);
}
function sinksThis2() {
sink(this); // NOT OK
}
sinksThis.apply(source(), []);

View File

@@ -99,6 +99,7 @@ nodes
| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) |
| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) |
| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) |
| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) |
| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
@@ -132,6 +133,9 @@ nodes
| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) |
| 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) |
| file://:0:0:0:0 | (TypeParameters) | semmle.label | (TypeParameters) |
| file://:0:0:0:0 | (TypeParameters) | semmle.label | (TypeParameters) |
@@ -1381,8 +1385,47 @@ nodes
| tst.ts:374:13:374:26 | [DotExpr] B.resolvedFile | semmle.label | [DotExpr] B.resolvedFile |
| tst.ts:374:13:374:28 | [MethodCallExpr] B.resolvedFile() | semmle.label | [MethodCallExpr] B.resolvedFile() |
| tst.ts:374:15:374:26 | [Label] resolvedFile | semmle.label | [Label] resolvedFile |
| tst.ts:379:1:386:1 | [NamespaceDeclaration] module ... ; } | semmle.label | [NamespaceDeclaration] module ... ; } |
| tst.ts:379:1:386:1 | [NamespaceDeclaration] module ... ; } | semmle.order | 84 |
| tst.ts:379:8:379:11 | [VarDecl] TS48 | semmle.label | [VarDecl] TS48 |
| tst.ts:381:5:381:73 | [TypeAliasDeclaration,TypeDefinition] type So ... never; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type So ... never; |
| tst.ts:381:10:381:16 | [Identifier] SomeNum | semmle.label | [Identifier] SomeNum |
| tst.ts:381:20:381:24 | [LiteralTypeExpr] "100" | semmle.label | [LiteralTypeExpr] "100" |
| tst.ts:381:20:381:72 | [ConditionalTypeExpr] "100" e ... : never | semmle.label | [ConditionalTypeExpr] "100" e ... : never |
| tst.ts:381:34:381:60 | [TemplateLiteralTypeExpr] `${infe ... umber}` | semmle.label | [TemplateLiteralTypeExpr] `${infe ... umber}` |
| tst.ts:381:37:381:58 | [InferTypeExpr] infer U ... number | semmle.label | [InferTypeExpr] infer U ... number |
| tst.ts:381:43:381:43 | [Identifier] U | semmle.label | [Identifier] U |
| tst.ts:381:43:381:58 | [TypeParameter] U extends number | semmle.label | [TypeParameter] U extends number |
| tst.ts:381:53:381:58 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number |
| tst.ts:381:64:381:64 | [LocalTypeAccess] U | semmle.label | [LocalTypeAccess] U |
| tst.ts:381:68:381:72 | [KeywordTypeExpr] never | semmle.label | [KeywordTypeExpr] never |
| tst.ts:383:5:383:54 | [FunctionDeclStmt] declare ... T): T; | semmle.label | [FunctionDeclStmt] declare ... T): T; |
| tst.ts:383:22:383:35 | [VarDecl] chooseRandomly | semmle.label | [VarDecl] chooseRandomly |
| tst.ts:383:37:383:37 | [Identifier] T | semmle.label | [Identifier] T |
| tst.ts:383:37:383:37 | [TypeParameter] T | semmle.label | [TypeParameter] T |
| tst.ts:383:40:383:40 | [SimpleParameter] x | semmle.label | [SimpleParameter] x |
| tst.ts:383:43:383:43 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
| tst.ts:383:46:383:46 | [SimpleParameter] y | semmle.label | [SimpleParameter] y |
| tst.ts:383:49:383:49 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
| tst.ts:383:53:383:53 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T |
| tst.ts:385:5:385:74 | [DeclStmt] let [a, ... ye!"]); | semmle.label | [DeclStmt] let [a, ... ye!"]); |
| tst.ts:385:9:385:17 | [ArrayPattern] [a, b, c] | semmle.label | [ArrayPattern] [a, b, c] |
| tst.ts:385:9:385:73 | [VariableDeclarator] [a, b, ... bye!"]) | semmle.label | [VariableDeclarator] [a, b, ... bye!"]) |
| tst.ts:385:10:385:10 | [VarDecl] a | semmle.label | [VarDecl] a |
| tst.ts:385:13:385:13 | [VarDecl] b | semmle.label | [VarDecl] b |
| tst.ts:385:16:385:16 | [VarDecl] c | semmle.label | [VarDecl] c |
| tst.ts:385:21:385:34 | [VarRef] chooseRandomly | semmle.label | [VarRef] chooseRandomly |
| tst.ts:385:21:385:73 | [CallExpr] chooseR ... bye!"]) | semmle.label | [CallExpr] chooseR ... bye!"]) |
| tst.ts:385:36:385:52 | [ArrayExpr] [42, true, "hi!"] | semmle.label | [ArrayExpr] [42, true, "hi!"] |
| tst.ts:385:37:385:38 | [Literal] 42 | semmle.label | [Literal] 42 |
| tst.ts:385:41:385:44 | [Literal] true | semmle.label | [Literal] true |
| tst.ts:385:47:385:51 | [Literal] "hi!" | semmle.label | [Literal] "hi!" |
| tst.ts:385:55:385:72 | [ArrayExpr] [0, false, "bye!"] | semmle.label | [ArrayExpr] [0, false, "bye!"] |
| tst.ts:385:56:385:56 | [Literal] 0 | semmle.label | [Literal] 0 |
| tst.ts:385:59:385:63 | [Literal] false | semmle.label | [Literal] false |
| tst.ts:385:66:385:71 | [Literal] "bye!" | semmle.label | [Literal] "bye!" |
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.label | [ExportDeclaration] export ... 'b'; } |
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 84 |
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 85 |
| tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | [FunctionDeclStmt] functio ... 'b'; } |
| tstModuleCJS.cts:1:17:1:28 | [VarDecl] tstModuleCJS | semmle.label | [VarDecl] tstModuleCJS |
| tstModuleCJS.cts:1:33:1:35 | [LiteralTypeExpr] 'a' | semmle.label | [LiteralTypeExpr] 'a' |
@@ -1400,7 +1443,7 @@ nodes
| tstModuleCJS.cts:2:34:2:36 | [Literal] 'a' | semmle.label | [Literal] 'a' |
| tstModuleCJS.cts:2:40:2:42 | [Literal] 'b' | semmle.label | [Literal] 'b' |
| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.label | [ExportDeclaration] export ... 'b'; } |
| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 85 |
| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 86 |
| tstModuleES.mts:1:16:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | [FunctionDeclStmt] functio ... 'b'; } |
| tstModuleES.mts:1:25:1:35 | [VarDecl] tstModuleES | semmle.label | [VarDecl] tstModuleES |
| tstModuleES.mts:1:40:1:42 | [LiteralTypeExpr] 'a' | semmle.label | [LiteralTypeExpr] 'a' |
@@ -1418,7 +1461,7 @@ nodes
| tstModuleES.mts:2:34:2:36 | [Literal] 'a' | semmle.label | [Literal] 'a' |
| tstModuleES.mts:2:40:2:42 | [Literal] 'b' | semmle.label | [Literal] 'b' |
| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } |
| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 86 |
| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 87 |
| tstSuffixA.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } |
| tstSuffixA.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile |
| tstSuffixA.ts:1:33:1:47 | [LiteralTypeExpr] 'tstSuffixA.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixA.ts' |
@@ -1426,7 +1469,7 @@ nodes
| tstSuffixA.ts:2:5:2:27 | [ReturnStmt] return ... xA.ts'; | semmle.label | [ReturnStmt] return ... xA.ts'; |
| tstSuffixA.ts:2:12:2:26 | [Literal] 'tstSuffixA.ts' | semmle.label | [Literal] 'tstSuffixA.ts' |
| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } |
| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 87 |
| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 88 |
| tstSuffixB.ios.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } |
| tstSuffixB.ios.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile |
| tstSuffixB.ios.ts:1:33:1:51 | [LiteralTypeExpr] 'tstSuffixB.ios.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixB.ios.ts' |
@@ -1434,7 +1477,7 @@ nodes
| tstSuffixB.ios.ts:2:5:2:31 | [ReturnStmt] return ... os.ts'; | semmle.label | [ReturnStmt] return ... os.ts'; |
| tstSuffixB.ios.ts:2:12:2:30 | [Literal] 'tstSuffixB.ios.ts' | semmle.label | [Literal] 'tstSuffixB.ios.ts' |
| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } |
| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 88 |
| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 89 |
| tstSuffixB.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } |
| tstSuffixB.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile |
| tstSuffixB.ts:1:33:1:47 | [LiteralTypeExpr] 'tstSuffixB.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixB.ts' |
@@ -1442,16 +1485,16 @@ nodes
| tstSuffixB.ts:2:5:2:27 | [ReturnStmt] return ... xB.ts'; | semmle.label | [ReturnStmt] return ... xB.ts'; |
| tstSuffixB.ts:2:12:2:26 | [Literal] 'tstSuffixB.ts' | semmle.label | [Literal] 'tstSuffixB.ts' |
| 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 | 89 |
| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 90 |
| 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 | 90 |
| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 91 |
| 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 | 91 |
| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay<T>>; | semmle.order | 92 |
| 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 |
@@ -1463,14 +1506,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 | 92 |
| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 93 |
| 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 | 93 |
| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 94 |
| 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 |
@@ -1486,12 +1529,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 | 94 |
| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 95 |
| 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 | 95 |
| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 96 |
| 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 |
@@ -1507,7 +1550,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 | 96 |
| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 97 |
| 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 |
@@ -1532,12 +1575,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 | 97 |
| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 98 |
| 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 | 98 |
| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 99 |
| 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] {} |
@@ -1545,36 +1588,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 | 99 |
| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 100 |
| 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 | 100 |
| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 101 |
| 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 | 101 |
| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 102 |
| 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 | 102 |
| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 103 |
| 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 | 103 |
| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 104 |
| 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 | 104 |
| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 105 |
| 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 | 105 |
| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 106 |
| 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 |
@@ -1582,14 +1625,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 | 106 |
| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 107 |
| 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 | 107 |
| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 108 |
| 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() {} |
@@ -1601,14 +1644,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 | 108 |
| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 109 |
| 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 | 109 |
| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 110 |
| 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 |
@@ -1617,29 +1660,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 | 110 |
| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 111 |
| 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 | 111 |
| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 112 |
| 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 | 112 |
| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 113 |
| 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 | 113 |
| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias<T> = T[]; | semmle.order | 114 |
| 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 | 114 |
| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 115 |
| 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 |
@@ -1794,6 +1837,10 @@ edges
| file://:0:0:0:0 | (Arguments) | tst.ts:370:13:370:28 | [MethodCallExpr] A.resolvedFile() | semmle.order | 0 |
| file://:0:0:0:0 | (Arguments) | tst.ts:374:13:374:28 | [MethodCallExpr] B.resolvedFile() | semmle.label | 0 |
| file://:0:0:0:0 | (Arguments) | tst.ts:374:13:374:28 | [MethodCallExpr] B.resolvedFile() | semmle.order | 0 |
| file://:0:0:0:0 | (Arguments) | tst.ts:385:36:385:52 | [ArrayExpr] [42, true, "hi!"] | semmle.label | 0 |
| file://:0:0:0:0 | (Arguments) | tst.ts:385:36:385:52 | [ArrayExpr] [42, true, "hi!"] | semmle.order | 0 |
| file://:0:0:0:0 | (Arguments) | tst.ts:385:55:385:72 | [ArrayExpr] [0, false, "bye!"] | semmle.label | 1 |
| file://:0:0:0:0 | (Arguments) | tst.ts:385:55:385:72 | [ArrayExpr] [0, false, "bye!"] | semmle.order | 1 |
| file://:0:0:0:0 | (Parameters) | tst.ts:14:17:14:17 | [SimpleParameter] x | semmle.label | 0 |
| file://:0:0:0:0 | (Parameters) | tst.ts:14:17:14:17 | [SimpleParameter] x | semmle.order | 0 |
| file://:0:0:0:0 | (Parameters) | tst.ts:14:28:14:28 | [SimpleParameter] y | semmle.label | 1 |
@@ -1866,6 +1913,10 @@ edges
| file://:0:0:0:0 | (Parameters) | tst.ts:344:9:344:13 | [SimpleParameter] value | semmle.order | 0 |
| file://:0:0:0:0 | (Parameters) | tst.ts:349:9:349:13 | [SimpleParameter] value | semmle.label | 0 |
| file://:0:0:0:0 | (Parameters) | tst.ts:349:9:349:13 | [SimpleParameter] value | semmle.order | 0 |
| file://:0:0:0:0 | (Parameters) | tst.ts:383:40:383:40 | [SimpleParameter] x | semmle.label | 0 |
| file://:0:0:0:0 | (Parameters) | tst.ts:383:40:383:40 | [SimpleParameter] x | semmle.order | 0 |
| file://:0:0:0:0 | (Parameters) | tst.ts:383:46:383:46 | [SimpleParameter] y | semmle.label | 1 |
| file://:0:0:0:0 | (Parameters) | tst.ts:383:46:383:46 | [SimpleParameter] y | semmle.order | 1 |
| file://:0:0:0:0 | (Parameters) | type_alias.ts:14:10:14:17 | [SimpleParameter] property | semmle.label | 0 |
| file://:0:0:0:0 | (Parameters) | type_alias.ts:14:10:14:17 | [SimpleParameter] property | semmle.order | 0 |
| file://:0:0:0:0 | (Parameters) | type_alias.ts:21:19:21:21 | [SimpleParameter] key | semmle.label | 0 |
@@ -1884,6 +1935,10 @@ edges
| file://:0:0:0:0 | (TypeParameters) | tst.ts:332:20:332:35 | [TypeParameter] S extends string | semmle.order | 0 |
| file://:0:0:0:0 | (TypeParameters) | tst.ts:342:17:342:24 | [TypeParameter] in out T | semmle.label | 0 |
| file://:0:0:0:0 | (TypeParameters) | tst.ts:342:17:342:24 | [TypeParameter] in out T | semmle.order | 0 |
| file://:0:0:0:0 | (TypeParameters) | tst.ts:381:43:381:58 | [TypeParameter] U extends number | semmle.label | 0 |
| file://:0:0:0:0 | (TypeParameters) | tst.ts:381:43:381:58 | [TypeParameter] U extends number | semmle.order | 0 |
| file://:0:0:0:0 | (TypeParameters) | tst.ts:383:37:383:37 | [TypeParameter] T | semmle.label | 0 |
| file://:0:0:0:0 | (TypeParameters) | tst.ts:383:37:383:37 | [TypeParameter] T | semmle.order | 0 |
| file://:0:0:0:0 | (TypeParameters) | type_alias.ts:5:19:5:19 | [TypeParameter] T | semmle.label | 0 |
| file://:0:0:0:0 | (TypeParameters) | type_alias.ts:5:19:5:19 | [TypeParameter] T | semmle.order | 0 |
| file://:0:0:0:0 | (TypeParameters) | type_definitions.ts:3:13:3:13 | [TypeParameter] S | semmle.label | 0 |
@@ -4078,6 +4133,76 @@ edges
| tst.ts:374:13:374:26 | [DotExpr] B.resolvedFile | tst.ts:374:15:374:26 | [Label] resolvedFile | semmle.order | 2 |
| tst.ts:374:13:374:28 | [MethodCallExpr] B.resolvedFile() | tst.ts:374:13:374:26 | [DotExpr] B.resolvedFile | semmle.label | 0 |
| tst.ts:374:13:374:28 | [MethodCallExpr] B.resolvedFile() | tst.ts:374:13:374:26 | [DotExpr] B.resolvedFile | semmle.order | 0 |
| tst.ts:379:1:386:1 | [NamespaceDeclaration] module ... ; } | tst.ts:379:8:379:11 | [VarDecl] TS48 | semmle.label | 1 |
| tst.ts:379:1:386:1 | [NamespaceDeclaration] module ... ; } | tst.ts:379:8:379:11 | [VarDecl] TS48 | semmle.order | 1 |
| tst.ts:379:1:386:1 | [NamespaceDeclaration] module ... ; } | tst.ts:381:5:381:73 | [TypeAliasDeclaration,TypeDefinition] type So ... never; | semmle.label | 2 |
| tst.ts:379:1:386:1 | [NamespaceDeclaration] module ... ; } | tst.ts:381:5:381:73 | [TypeAliasDeclaration,TypeDefinition] type So ... never; | semmle.order | 2 |
| tst.ts:379:1:386:1 | [NamespaceDeclaration] module ... ; } | tst.ts:383:5:383:54 | [FunctionDeclStmt] declare ... T): T; | semmle.label | 3 |
| tst.ts:379:1:386:1 | [NamespaceDeclaration] module ... ; } | tst.ts:383:5:383:54 | [FunctionDeclStmt] declare ... T): T; | semmle.order | 3 |
| tst.ts:379:1:386:1 | [NamespaceDeclaration] module ... ; } | tst.ts:385:5:385:74 | [DeclStmt] let [a, ... ye!"]); | semmle.label | 4 |
| tst.ts:379:1:386:1 | [NamespaceDeclaration] module ... ; } | tst.ts:385:5:385:74 | [DeclStmt] let [a, ... ye!"]); | semmle.order | 4 |
| tst.ts:381:5:381:73 | [TypeAliasDeclaration,TypeDefinition] type So ... never; | tst.ts:381:10:381:16 | [Identifier] SomeNum | semmle.label | 1 |
| tst.ts:381:5:381:73 | [TypeAliasDeclaration,TypeDefinition] type So ... never; | tst.ts:381:10:381:16 | [Identifier] SomeNum | semmle.order | 1 |
| tst.ts:381:5:381:73 | [TypeAliasDeclaration,TypeDefinition] type So ... never; | tst.ts:381:20:381:72 | [ConditionalTypeExpr] "100" e ... : never | semmle.label | 2 |
| tst.ts:381:5:381:73 | [TypeAliasDeclaration,TypeDefinition] type So ... never; | tst.ts:381:20:381:72 | [ConditionalTypeExpr] "100" e ... : never | semmle.order | 2 |
| tst.ts:381:20:381:72 | [ConditionalTypeExpr] "100" e ... : never | tst.ts:381:20:381:24 | [LiteralTypeExpr] "100" | semmle.label | 1 |
| tst.ts:381:20:381:72 | [ConditionalTypeExpr] "100" e ... : never | tst.ts:381:20:381:24 | [LiteralTypeExpr] "100" | semmle.order | 1 |
| tst.ts:381:20:381:72 | [ConditionalTypeExpr] "100" e ... : never | tst.ts:381:34:381:60 | [TemplateLiteralTypeExpr] `${infe ... umber}` | semmle.label | 2 |
| tst.ts:381:20:381:72 | [ConditionalTypeExpr] "100" e ... : never | tst.ts:381:34:381:60 | [TemplateLiteralTypeExpr] `${infe ... umber}` | semmle.order | 2 |
| tst.ts:381:20:381:72 | [ConditionalTypeExpr] "100" e ... : never | tst.ts:381:64:381:64 | [LocalTypeAccess] U | semmle.label | 3 |
| tst.ts:381:20:381:72 | [ConditionalTypeExpr] "100" e ... : never | tst.ts:381:64:381:64 | [LocalTypeAccess] U | semmle.order | 3 |
| tst.ts:381:20:381:72 | [ConditionalTypeExpr] "100" e ... : never | tst.ts:381:68:381:72 | [KeywordTypeExpr] never | semmle.label | 4 |
| tst.ts:381:20:381:72 | [ConditionalTypeExpr] "100" e ... : never | tst.ts:381:68:381:72 | [KeywordTypeExpr] never | semmle.order | 4 |
| tst.ts:381:34:381:60 | [TemplateLiteralTypeExpr] `${infe ... umber}` | tst.ts:381:37:381:58 | [InferTypeExpr] infer U ... number | semmle.label | 1 |
| tst.ts:381:34:381:60 | [TemplateLiteralTypeExpr] `${infe ... umber}` | tst.ts:381:37:381:58 | [InferTypeExpr] infer U ... number | semmle.order | 1 |
| tst.ts:381:37:381:58 | [InferTypeExpr] infer U ... number | file://:0:0:0:0 | (TypeParameters) | semmle.label | -100 |
| tst.ts:381:37:381:58 | [InferTypeExpr] infer U ... number | file://:0:0:0:0 | (TypeParameters) | semmle.order | -100 |
| tst.ts:381:43:381:58 | [TypeParameter] U extends number | tst.ts:381:43:381:43 | [Identifier] U | semmle.label | 1 |
| tst.ts:381:43:381:58 | [TypeParameter] U extends number | tst.ts:381:43:381:43 | [Identifier] U | semmle.order | 1 |
| tst.ts:381:43:381:58 | [TypeParameter] U extends number | tst.ts:381:53:381:58 | [KeywordTypeExpr] number | semmle.label | 2 |
| tst.ts:381:43:381:58 | [TypeParameter] U extends number | tst.ts:381:53:381:58 | [KeywordTypeExpr] number | semmle.order | 2 |
| tst.ts:383:5:383:54 | [FunctionDeclStmt] declare ... T): T; | file://:0:0:0:0 | (Parameters) | semmle.label | 1 |
| tst.ts:383:5:383:54 | [FunctionDeclStmt] declare ... T): T; | file://:0:0:0:0 | (Parameters) | semmle.order | 1 |
| tst.ts:383:5:383:54 | [FunctionDeclStmt] declare ... T): T; | file://:0:0:0:0 | (TypeParameters) | semmle.label | 2 |
| tst.ts:383:5:383:54 | [FunctionDeclStmt] declare ... T): T; | file://:0:0:0:0 | (TypeParameters) | semmle.order | 2 |
| tst.ts:383:5:383:54 | [FunctionDeclStmt] declare ... T): T; | tst.ts:383:22:383:35 | [VarDecl] chooseRandomly | semmle.label | 0 |
| tst.ts:383:5:383:54 | [FunctionDeclStmt] declare ... T): T; | tst.ts:383:22:383:35 | [VarDecl] chooseRandomly | semmle.order | 0 |
| tst.ts:383:5:383:54 | [FunctionDeclStmt] declare ... T): T; | tst.ts:383:53:383:53 | [LocalTypeAccess] T | semmle.label | 4 |
| tst.ts:383:5:383:54 | [FunctionDeclStmt] declare ... T): T; | tst.ts:383:53:383:53 | [LocalTypeAccess] T | semmle.order | 4 |
| tst.ts:383:37:383:37 | [TypeParameter] T | tst.ts:383:37:383:37 | [Identifier] T | semmle.label | 1 |
| tst.ts:383:37:383:37 | [TypeParameter] T | tst.ts:383:37:383:37 | [Identifier] T | semmle.order | 1 |
| tst.ts:383:40:383:40 | [SimpleParameter] x | tst.ts:383:43:383:43 | [LocalTypeAccess] T | semmle.label | 0 |
| tst.ts:383:40:383:40 | [SimpleParameter] x | tst.ts:383:43:383:43 | [LocalTypeAccess] T | semmle.order | 0 |
| tst.ts:383:46:383:46 | [SimpleParameter] y | tst.ts:383:49:383:49 | [LocalTypeAccess] T | semmle.label | 0 |
| tst.ts:383:46:383:46 | [SimpleParameter] y | tst.ts:383:49:383:49 | [LocalTypeAccess] T | semmle.order | 0 |
| tst.ts:385:5:385:74 | [DeclStmt] let [a, ... ye!"]); | tst.ts:385:9:385:73 | [VariableDeclarator] [a, b, ... bye!"]) | semmle.label | 1 |
| tst.ts:385:5:385:74 | [DeclStmt] let [a, ... ye!"]); | tst.ts:385:9:385:73 | [VariableDeclarator] [a, b, ... bye!"]) | semmle.order | 1 |
| tst.ts:385:9:385:17 | [ArrayPattern] [a, b, c] | tst.ts:385:10:385:10 | [VarDecl] a | semmle.label | 1 |
| tst.ts:385:9:385:17 | [ArrayPattern] [a, b, c] | tst.ts:385:10:385:10 | [VarDecl] a | semmle.order | 1 |
| tst.ts:385:9:385:17 | [ArrayPattern] [a, b, c] | tst.ts:385:13:385:13 | [VarDecl] b | semmle.label | 2 |
| tst.ts:385:9:385:17 | [ArrayPattern] [a, b, c] | tst.ts:385:13:385:13 | [VarDecl] b | semmle.order | 2 |
| tst.ts:385:9:385:17 | [ArrayPattern] [a, b, c] | tst.ts:385:16:385:16 | [VarDecl] c | semmle.label | 3 |
| tst.ts:385:9:385:17 | [ArrayPattern] [a, b, c] | tst.ts:385:16:385:16 | [VarDecl] c | semmle.order | 3 |
| tst.ts:385:9:385:73 | [VariableDeclarator] [a, b, ... bye!"]) | tst.ts:385:9:385:17 | [ArrayPattern] [a, b, c] | semmle.label | 1 |
| tst.ts:385:9:385:73 | [VariableDeclarator] [a, b, ... bye!"]) | tst.ts:385:9:385:17 | [ArrayPattern] [a, b, c] | semmle.order | 1 |
| tst.ts:385:9:385:73 | [VariableDeclarator] [a, b, ... bye!"]) | tst.ts:385:21:385:73 | [CallExpr] chooseR ... bye!"]) | semmle.label | 2 |
| tst.ts:385:9:385:73 | [VariableDeclarator] [a, b, ... bye!"]) | tst.ts:385:21:385:73 | [CallExpr] chooseR ... bye!"]) | semmle.order | 2 |
| tst.ts:385:21:385:73 | [CallExpr] chooseR ... bye!"]) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 |
| tst.ts:385:21:385:73 | [CallExpr] chooseR ... bye!"]) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 |
| tst.ts:385:21:385:73 | [CallExpr] chooseR ... bye!"]) | tst.ts:385:21:385:34 | [VarRef] chooseRandomly | semmle.label | 0 |
| tst.ts:385:21:385:73 | [CallExpr] chooseR ... bye!"]) | tst.ts:385:21:385:34 | [VarRef] chooseRandomly | semmle.order | 0 |
| tst.ts:385:36:385:52 | [ArrayExpr] [42, true, "hi!"] | tst.ts:385:37:385:38 | [Literal] 42 | semmle.label | 1 |
| tst.ts:385:36:385:52 | [ArrayExpr] [42, true, "hi!"] | tst.ts:385:37:385:38 | [Literal] 42 | semmle.order | 1 |
| tst.ts:385:36:385:52 | [ArrayExpr] [42, true, "hi!"] | tst.ts:385:41:385:44 | [Literal] true | semmle.label | 2 |
| tst.ts:385:36:385:52 | [ArrayExpr] [42, true, "hi!"] | tst.ts:385:41:385:44 | [Literal] true | semmle.order | 2 |
| tst.ts:385:36:385:52 | [ArrayExpr] [42, true, "hi!"] | tst.ts:385:47:385:51 | [Literal] "hi!" | semmle.label | 3 |
| tst.ts:385:36:385:52 | [ArrayExpr] [42, true, "hi!"] | tst.ts:385:47:385:51 | [Literal] "hi!" | semmle.order | 3 |
| tst.ts:385:55:385:72 | [ArrayExpr] [0, false, "bye!"] | tst.ts:385:56:385:56 | [Literal] 0 | semmle.label | 1 |
| tst.ts:385:55:385:72 | [ArrayExpr] [0, false, "bye!"] | tst.ts:385:56:385:56 | [Literal] 0 | semmle.order | 1 |
| tst.ts:385:55:385:72 | [ArrayExpr] [0, false, "bye!"] | tst.ts:385:59:385:63 | [Literal] false | semmle.label | 2 |
| tst.ts:385:55:385:72 | [ArrayExpr] [0, false, "bye!"] | tst.ts:385:59:385:63 | [Literal] false | semmle.order | 2 |
| tst.ts:385:55:385:72 | [ArrayExpr] [0, false, "bye!"] | tst.ts:385:66:385:71 | [Literal] "bye!" | semmle.label | 3 |
| tst.ts:385:55:385:72 | [ArrayExpr] [0, false, "bye!"] | tst.ts:385:66:385:71 | [Literal] "bye!" | semmle.order | 3 |
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | 1 |
| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.order | 1 |
| tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | tstModuleCJS.cts:1:17:1:28 | [VarDecl] tstModuleCJS | semmle.label | 0 |

View File

@@ -441,7 +441,7 @@ getExprType
| tst.ts:320:19:320:29 | toLowerCase | () => string |
| tst.ts:325:7:325:14 | ErrorMap | { new (entries?: readonly (readonly [string, Er... |
| tst.ts:325:18:325:20 | Map | MapConstructor |
| tst.ts:325:18:325:35 | Map<string, Error> | any |
| tst.ts:325:18:325:35 | Map<string, Error> | { new (entries?: readonly (readonly [string, Er... |
| tst.ts:327:7:327:14 | errorMap | Map<string, Error> |
| tst.ts:327:18:327:31 | new ErrorMap() | Map<string, Error> |
| tst.ts:327:22:327:29 | ErrorMap | { new (entries?: readonly (readonly [string, Er... |
@@ -502,6 +502,23 @@ getExprType
| tst.ts:374:13:374:26 | B.resolvedFile | () => "tstSuffixB.ios.ts" |
| tst.ts:374:13:374:28 | B.resolvedFile() | "tstSuffixB.ios.ts" |
| tst.ts:374:15:374:26 | resolvedFile | () => "tstSuffixB.ios.ts" |
| tst.ts:379:8:379:11 | TS48 | typeof TS48 in library-tests/TypeScript/Types/tst.ts |
| tst.ts:383:22:383:35 | chooseRandomly | <T>(x: T, y: T) => T |
| tst.ts:383:40:383:40 | x | T |
| tst.ts:383:46:383:46 | y | T |
| tst.ts:385:10:385:10 | a | number |
| tst.ts:385:13:385:13 | b | boolean |
| tst.ts:385:16:385:16 | c | string |
| tst.ts:385:21:385:34 | chooseRandomly | <T>(x: T, y: T) => T |
| tst.ts:385:21:385:73 | chooseR ... bye!"]) | [number, boolean, string] |
| tst.ts:385:36:385:52 | [42, true, "hi!"] | [number, boolean, string] |
| tst.ts:385:37:385:38 | 42 | 42 |
| tst.ts:385:41:385:44 | true | true |
| tst.ts:385:47:385:51 | "hi!" | "hi!" |
| tst.ts:385:55:385:72 | [0, false, "bye!"] | [number, boolean, string] |
| tst.ts:385:56:385:56 | 0 | 0 |
| tst.ts:385:59:385:63 | false | false |
| tst.ts:385:66:385:71 | "bye!" | "bye!" |
| tstModuleCJS.cts:1:17:1:28 | tstModuleCJS | () => "a" \| "b" |
| tstModuleCJS.cts:2:12:2:15 | Math | Math |
| tstModuleCJS.cts:2:12:2:22 | Math.random | () => number |
@@ -606,6 +623,7 @@ getTypeDefinitionType
| tst.ts:331:1:334:14 | type Fi ... never; | FirstString<T> |
| tst.ts:336:1:336:51 | type F ... lean]>; | "a" \| "b" |
| tst.ts:342:1:345:1 | interfa ... void;\\n} | State<T> |
| tst.ts:381:5:381:73 | type So ... never; | 100 |
| 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 |
@@ -861,6 +879,16 @@ getTypeExprType
| tst.ts:325:30:325:34 | Error | Error |
| tst.ts:331:6:331:16 | FirstString | FirstString<T> |
| tst.ts:331:18:331:18 | T | T |
| tst.ts:332:3:332:3 | T | T |
| tst.ts:332:13:332:50 | [infer ... nown[]] | [S, ...unknown[]] |
| tst.ts:332:14:332:35 | infer S ... string | S |
| tst.ts:332:20:332:20 | S | S |
| tst.ts:332:30:332:35 | string | string |
| tst.ts:332:38:332:49 | ...unknown[] | unknown |
| tst.ts:332:41:332:47 | unknown | unknown |
| tst.ts:332:41:332:49 | unknown[] | unknown[] |
| tst.ts:333:9:333:9 | S | S |
| tst.ts:334:9:334:13 | never | never |
| tst.ts:336:6:336:6 | F | "a" \| "b" |
| tst.ts:336:10:336:20 | FirstString | FirstString<T> |
| tst.ts:336:10:336:50 | FirstSt ... olean]> | "a" \| "b" |
@@ -881,6 +909,18 @@ getTypeExprType
| tst.ts:347:14:347:18 | State | State<T> |
| tst.ts:347:14:347:26 | State<number> | State<number> |
| tst.ts:347:20:347:25 | number | number |
| tst.ts:381:10:381:16 | SomeNum | 100 |
| tst.ts:381:20:381:24 | "100" | "100" |
| tst.ts:381:20:381:72 | "100" e ... : never | 100 |
| tst.ts:381:37:381:58 | infer U ... number | U |
| tst.ts:381:43:381:43 | U | U |
| tst.ts:381:53:381:58 | number | number |
| tst.ts:381:64:381:64 | U | U |
| tst.ts:381:68:381:72 | never | never |
| tst.ts:383:37:383:37 | T | T |
| tst.ts:383:43:383:43 | T | T |
| tst.ts:383:49:383:49 | T | T |
| tst.ts:383:53:383:53 | T | T |
| tstModuleCJS.cts:1:33:1:35 | 'a' | "a" |
| tstModuleCJS.cts:1:33:1:41 | 'a' \| 'b' | "a" \| "b" |
| tstModuleCJS.cts:1:39:1:41 | 'b' | "b" |
@@ -1027,6 +1067,15 @@ tupleTypes
| tst.ts:42:25:42:30 | [1, 2] | readonly [1, 2] | 1 | 2 | 2 | no-rest |
| tst.ts:42:25:42:39 | [1, 2] as const | readonly [1, 2] | 0 | 1 | 2 | no-rest |
| tst.ts:42:25:42:39 | [1, 2] as const | readonly [1, 2] | 1 | 2 | 2 | no-rest |
| tst.ts:385:21:385:73 | chooseR ... bye!"]) | [number, boolean, string] | 0 | number | 3 | no-rest |
| tst.ts:385:21:385:73 | chooseR ... bye!"]) | [number, boolean, string] | 1 | boolean | 3 | no-rest |
| tst.ts:385:21:385:73 | chooseR ... bye!"]) | [number, boolean, string] | 2 | string | 3 | no-rest |
| tst.ts:385:36:385:52 | [42, true, "hi!"] | [number, boolean, string] | 0 | number | 3 | no-rest |
| tst.ts:385:36:385:52 | [42, true, "hi!"] | [number, boolean, string] | 1 | boolean | 3 | no-rest |
| tst.ts:385:36:385:52 | [42, true, "hi!"] | [number, boolean, string] | 2 | string | 3 | no-rest |
| tst.ts:385:55:385:72 | [0, false, "bye!"] | [number, boolean, string] | 0 | number | 3 | no-rest |
| tst.ts:385:55:385:72 | [0, false, "bye!"] | [number, boolean, string] | 1 | boolean | 3 | no-rest |
| tst.ts:385:55:385:72 | [0, false, "bye!"] | [number, boolean, string] | 2 | string | 3 | no-rest |
unknownType
| tst.ts:40:5:40:15 | unknownType | unknown |
| tst.ts:47:8:47:8 | e | unknown |

View File

@@ -373,3 +373,14 @@ import * as B from './tstSuffixB';
console.log(B.resolvedFile()); // <- 'tstSuffixB.ios.ts'
/////////////////
module TS48 {
// SomeNum used to be 'number'; now it's '100'.
type SomeNum = "100" extends `${infer U extends number}` ? U : never;
declare function chooseRandomly<T>(x: T, y: T): T;
let [a, b, c] = chooseRandomly([42, true, "hi!"], [0, false, "bye!"]);
}

View File

@@ -1,28 +1,28 @@
import javascript
query predicate xmlAttribute(XMLAttribute attr, XMLElement element, string name, string value) {
query predicate xmlAttribute(XmlAttribute attr, XmlElement element, string name, string value) {
attr.getElement() = element and
attr.getName() = name and
attr.getValue() = value
}
query predicate xmlComment(XMLComment c, string text) { text = c.getText() }
query predicate xmlComment(XmlComment c, string text) { text = c.getText() }
query predicate xmlElement_getAnAttribute(XMLElement e, XMLAttribute attr) {
query predicate xmlElement_getAnAttribute(XmlElement e, XmlAttribute attr) {
attr = e.getAnAttribute()
}
query predicate xmlElement(XMLElement elt, string name, XMLParent parent, int index, XMLFile file) {
query predicate xmlElement(XmlElement elt, string name, XmlParent parent, int index, XmlFile file) {
name = elt.getName() and
parent = elt.getParent() and
index = elt.getIndex() and
file = elt.getFile()
}
query predicate xmlFile(XMLFile f) { any() }
query predicate xmlFile(XmlFile f) { any() }
query predicate xmlLocatable(XMLLocatable x) { any() }
query predicate xmlLocatable(XmlLocatable x) { any() }
query predicate xmlParent_getChild(XMLParent p, int i, XMLElement child) { child = p.getChild(i) }
query predicate xmlParent_getChild(XmlParent p, int i, XmlElement child) { child = p.getChild(i) }
query predicate xmlParent_getTextValue(XMLParent p, string text) { p.getTextValue() = text }
query predicate xmlParent_getTextValue(XmlParent p, string text) { p.getTextValue() = text }

View File

@@ -1,6 +1,6 @@
nodes
| external.yml:1:1:1:2 | [YAMLScalar] 42 | semmle.label | [YAMLScalar] 42 |
| external.yml:1:1:1:2 | [YAMLScalar] 42 | semmle.order | 1 |
| external.yml:1:1:1:2 | [YamlScalar] 42 | semmle.label | [YamlScalar] 42 |
| external.yml:1:1:1:2 | [YamlScalar] 42 | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 0) name: | semmle.label | (Mapping 0) name: |
| file://:0:0:0:0 | (Mapping 0) name: | semmle.label | (Mapping 0) name: |
| file://:0:0:0:0 | (Mapping 0) street: | semmle.label | (Mapping 0) street: |
@@ -15,137 +15,137 @@ nodes
| file://:0:0:0:0 | (Mapping 1) y: | semmle.label | (Mapping 1) y: |
| file://:0:0:0:0 | (Mapping 2) country: | semmle.label | (Mapping 2) country: |
| file://:0:0:0:0 | (Mapping 2) country: | semmle.label | (Mapping 2) country: |
| merge.yaml:1:1:3:8 | [YAMLSequence] - &A { ... y: 42 } | semmle.label | [YAMLSequence] - &A { ... y: 42 } |
| merge.yaml:1:1:3:8 | [YAMLSequence] - &A { ... y: 42 } | semmle.order | 2 |
| merge.yaml:1:3:1:21 | [YAMLMapping] &A { x: 23, y: 42 } | semmle.label | [YAMLMapping] &A { x: 23, y: 42 } |
| merge.yaml:1:8:1:8 | [YAMLScalar] x | semmle.label | [YAMLScalar] x |
| merge.yaml:1:11:1:12 | [YAMLScalar] 23 | semmle.label | [YAMLScalar] 23 |
| merge.yaml:1:15:1:15 | [YAMLScalar] y | semmle.label | [YAMLScalar] y |
| merge.yaml:1:18:1:19 | [YAMLScalar] 42 | semmle.label | [YAMLScalar] 42 |
| merge.yaml:2:3:2:3 | [YAMLScalar] x | semmle.label | [YAMLScalar] x |
| merge.yaml:2:3:3:8 | [YAMLMapping] x: 56 | semmle.label | [YAMLMapping] x: 56 |
| merge.yaml:2:6:2:7 | [YAMLScalar] 56 | semmle.label | [YAMLScalar] 56 |
| merge.yaml:3:3:3:4 | [YAMLScalar] << | semmle.label | [YAMLScalar] << |
| merge.yaml:3:7:3:8 | [YAMLAliasNode] *A | semmle.label | [YAMLAliasNode] *A |
| tst.yml:1:1:14:23 | [YAMLSequence] - "name ... Knopf" | semmle.label | [YAMLSequence] - "name ... Knopf" |
| tst.yml:1:1:14:23 | [YAMLSequence] - "name ... Knopf" | semmle.order | 3 |
| tst.yml:1:3:1:8 | [YAMLScalar] "name" | semmle.label | [YAMLScalar] "name" |
| tst.yml:1:3:7:0 | [YAMLMapping] "name": "Jim Knopf" | semmle.label | [YAMLMapping] "name": "Jim Knopf" |
| tst.yml:1:11:1:21 | [YAMLScalar] "Jim Knopf" | semmle.label | [YAMLScalar] "Jim Knopf" |
| tst.yml:2:3:2:9 | [YAMLScalar] address | semmle.label | [YAMLScalar] address |
| tst.yml:2:12:6:3 | [YAMLMapping] { | semmle.label | [YAMLMapping] { |
| tst.yml:3:5:3:12 | [YAMLScalar] "street" | semmle.label | [YAMLScalar] "street" |
| tst.yml:3:14:3:13 | [YAMLScalar] | semmle.label | [YAMLScalar] |
| tst.yml:4:5:4:12 | [YAMLScalar] "number" | semmle.label | [YAMLScalar] "number" |
| tst.yml:4:15:4:16 | [YAMLScalar] -1 | semmle.label | [YAMLScalar] -1 |
| tst.yml:5:5:5:13 | [YAMLScalar] "country" | semmle.label | [YAMLScalar] "country" |
| tst.yml:5:16:5:27 | [YAMLScalar] "Lummerland" | semmle.label | [YAMLScalar] "Lummerland" |
| tst.yml:7:3:7:6 | [YAMLScalar] name | semmle.label | [YAMLScalar] name |
| tst.yml:7:3:14:0 | [YAMLMapping] name: Frau Mahlzahn | semmle.label | [YAMLMapping] name: Frau Mahlzahn |
| tst.yml:7:9:7:21 | [YAMLScalar] Frau Mahlzahn | semmle.label | [YAMLScalar] Frau Mahlzahn |
| tst.yml:8:3:8:9 | [YAMLScalar] address | semmle.label | [YAMLScalar] address |
| tst.yml:9:5:9:10 | [YAMLScalar] street | semmle.label | [YAMLScalar] street |
| tst.yml:9:5:14:0 | [YAMLMapping] street: \| | semmle.label | [YAMLMapping] street: \| |
| tst.yml:9:13:11:0 | [YAMLScalar] \| | semmle.label | [YAMLScalar] \| |
| tst.yml:11:5:11:10 | [YAMLScalar] number | semmle.label | [YAMLScalar] number |
| tst.yml:11:13:11:15 | [YAMLScalar] 133 | semmle.label | [YAMLScalar] 133 |
| tst.yml:12:5:12:11 | [YAMLScalar] country | semmle.label | [YAMLScalar] country |
| tst.yml:12:14:13:18 | [YAMLScalar] < | semmle.label | [YAMLScalar] < |
| tst.yml:14:3:14:23 | [YAMLScalar] !includ ... nal.yml | semmle.label | [YAMLScalar] !includ ... nal.yml |
| merge.yaml:1:1:3:8 | [YamlSequence] - &A { ... y: 42 } | semmle.label | [YamlSequence] - &A { ... y: 42 } |
| merge.yaml:1:1:3:8 | [YamlSequence] - &A { ... y: 42 } | semmle.order | 2 |
| merge.yaml:1:3:1:21 | [YamlMapping] &A { x: 23, y: 42 } | semmle.label | [YamlMapping] &A { x: 23, y: 42 } |
| merge.yaml:1:8:1:8 | [YamlScalar] x | semmle.label | [YamlScalar] x |
| merge.yaml:1:11:1:12 | [YamlScalar] 23 | semmle.label | [YamlScalar] 23 |
| merge.yaml:1:15:1:15 | [YamlScalar] y | semmle.label | [YamlScalar] y |
| merge.yaml:1:18:1:19 | [YamlScalar] 42 | semmle.label | [YamlScalar] 42 |
| merge.yaml:2:3:2:3 | [YamlScalar] x | semmle.label | [YamlScalar] x |
| merge.yaml:2:3:3:8 | [YamlMapping] x: 56 | semmle.label | [YamlMapping] x: 56 |
| merge.yaml:2:6:2:7 | [YamlScalar] 56 | semmle.label | [YamlScalar] 56 |
| merge.yaml:3:3:3:4 | [YamlScalar] << | semmle.label | [YamlScalar] << |
| merge.yaml:3:7:3:8 | [YamlAliasNode] *A | semmle.label | [YamlAliasNode] *A |
| tst.yml:1:1:14:23 | [YamlSequence] - "name ... Knopf" | semmle.label | [YamlSequence] - "name ... Knopf" |
| tst.yml:1:1:14:23 | [YamlSequence] - "name ... Knopf" | semmle.order | 3 |
| tst.yml:1:3:1:8 | [YamlScalar] "name" | semmle.label | [YamlScalar] "name" |
| tst.yml:1:3:7:0 | [YamlMapping] "name": "Jim Knopf" | semmle.label | [YamlMapping] "name": "Jim Knopf" |
| tst.yml:1:11:1:21 | [YamlScalar] "Jim Knopf" | semmle.label | [YamlScalar] "Jim Knopf" |
| tst.yml:2:3:2:9 | [YamlScalar] address | semmle.label | [YamlScalar] address |
| tst.yml:2:12:6:3 | [YamlMapping] { | semmle.label | [YamlMapping] { |
| tst.yml:3:5:3:12 | [YamlScalar] "street" | semmle.label | [YamlScalar] "street" |
| tst.yml:3:14:3:13 | [YamlScalar] | semmle.label | [YamlScalar] |
| tst.yml:4:5:4:12 | [YamlScalar] "number" | semmle.label | [YamlScalar] "number" |
| tst.yml:4:15:4:16 | [YamlScalar] -1 | semmle.label | [YamlScalar] -1 |
| tst.yml:5:5:5:13 | [YamlScalar] "country" | semmle.label | [YamlScalar] "country" |
| tst.yml:5:16:5:27 | [YamlScalar] "Lummerland" | semmle.label | [YamlScalar] "Lummerland" |
| tst.yml:7:3:7:6 | [YamlScalar] name | semmle.label | [YamlScalar] name |
| tst.yml:7:3:14:0 | [YamlMapping] name: Frau Mahlzahn | semmle.label | [YamlMapping] name: Frau Mahlzahn |
| tst.yml:7:9:7:21 | [YamlScalar] Frau Mahlzahn | semmle.label | [YamlScalar] Frau Mahlzahn |
| tst.yml:8:3:8:9 | [YamlScalar] address | semmle.label | [YamlScalar] address |
| tst.yml:9:5:9:10 | [YamlScalar] street | semmle.label | [YamlScalar] street |
| tst.yml:9:5:14:0 | [YamlMapping] street: \| | semmle.label | [YamlMapping] street: \| |
| tst.yml:9:13:11:0 | [YamlScalar] \| | semmle.label | [YamlScalar] \| |
| tst.yml:11:5:11:10 | [YamlScalar] number | semmle.label | [YamlScalar] number |
| tst.yml:11:13:11:15 | [YamlScalar] 133 | semmle.label | [YamlScalar] 133 |
| tst.yml:12:5:12:11 | [YamlScalar] country | semmle.label | [YamlScalar] country |
| tst.yml:12:14:13:18 | [YamlScalar] < | semmle.label | [YamlScalar] < |
| tst.yml:14:3:14:23 | [YamlScalar] !includ ... nal.yml | semmle.label | [YamlScalar] !includ ... nal.yml |
edges
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:1:3:1:8 | [YAMLScalar] "name" | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:1:3:1:8 | [YAMLScalar] "name" | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:1:11:1:21 | [YAMLScalar] "Jim Knopf" | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:1:11:1:21 | [YAMLScalar] "Jim Knopf" | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:7:3:7:6 | [YAMLScalar] name | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:7:3:7:6 | [YAMLScalar] name | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:7:9:7:21 | [YAMLScalar] Frau Mahlzahn | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:7:9:7:21 | [YAMLScalar] Frau Mahlzahn | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:3:5:3:12 | [YAMLScalar] "street" | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:3:5:3:12 | [YAMLScalar] "street" | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:3:14:3:13 | [YAMLScalar] | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:3:14:3:13 | [YAMLScalar] | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:9:5:9:10 | [YAMLScalar] street | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:9:5:9:10 | [YAMLScalar] street | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:9:13:11:0 | [YAMLScalar] \| | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:9:13:11:0 | [YAMLScalar] \| | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:1:8:1:8 | [YAMLScalar] x | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:1:8:1:8 | [YAMLScalar] x | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:1:11:1:12 | [YAMLScalar] 23 | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:1:11:1:12 | [YAMLScalar] 23 | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:2:3:2:3 | [YAMLScalar] x | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:2:3:2:3 | [YAMLScalar] x | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:2:6:2:7 | [YAMLScalar] 56 | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:2:6:2:7 | [YAMLScalar] 56 | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 1) <<: | merge.yaml:3:3:3:4 | [YAMLScalar] << | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 1) <<: | merge.yaml:3:3:3:4 | [YAMLScalar] << | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 1) <<: | merge.yaml:3:7:3:8 | [YAMLAliasNode] *A | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 1) <<: | merge.yaml:3:7:3:8 | [YAMLAliasNode] *A | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:2:3:2:9 | [YAMLScalar] address | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:2:3:2:9 | [YAMLScalar] address | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:2:12:6:3 | [YAMLMapping] { | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:2:12:6:3 | [YAMLMapping] { | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:8:3:8:9 | [YAMLScalar] address | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:8:3:8:9 | [YAMLScalar] address | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:9:5:14:0 | [YAMLMapping] street: \| | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:9:5:14:0 | [YAMLMapping] street: \| | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:4:5:4:12 | [YAMLScalar] "number" | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:4:5:4:12 | [YAMLScalar] "number" | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:4:15:4:16 | [YAMLScalar] -1 | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:4:15:4:16 | [YAMLScalar] -1 | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:11:5:11:10 | [YAMLScalar] number | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:11:5:11:10 | [YAMLScalar] number | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:11:13:11:15 | [YAMLScalar] 133 | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:11:13:11:15 | [YAMLScalar] 133 | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 1) y: | merge.yaml:1:15:1:15 | [YAMLScalar] y | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 1) y: | merge.yaml:1:15:1:15 | [YAMLScalar] y | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 1) y: | merge.yaml:1:18:1:19 | [YAMLScalar] 42 | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 1) y: | merge.yaml:1:18:1:19 | [YAMLScalar] 42 | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:5:5:5:13 | [YAMLScalar] "country" | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:5:5:5:13 | [YAMLScalar] "country" | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:5:16:5:27 | [YAMLScalar] "Lummerland" | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:5:16:5:27 | [YAMLScalar] "Lummerland" | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:12:5:12:11 | [YAMLScalar] country | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:12:5:12:11 | [YAMLScalar] country | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:12:14:13:18 | [YAMLScalar] < | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:12:14:13:18 | [YAMLScalar] < | semmle.order | 1 |
| merge.yaml:1:1:3:8 | [YAMLSequence] - &A { ... y: 42 } | merge.yaml:1:3:1:21 | [YAMLMapping] &A { x: 23, y: 42 } | semmle.label | 0 |
| merge.yaml:1:1:3:8 | [YAMLSequence] - &A { ... y: 42 } | merge.yaml:1:3:1:21 | [YAMLMapping] &A { x: 23, y: 42 } | semmle.order | 0 |
| merge.yaml:1:1:3:8 | [YAMLSequence] - &A { ... y: 42 } | merge.yaml:2:3:3:8 | [YAMLMapping] x: 56 | semmle.label | 1 |
| merge.yaml:1:1:3:8 | [YAMLSequence] - &A { ... y: 42 } | merge.yaml:2:3:3:8 | [YAMLMapping] x: 56 | semmle.order | 1 |
| merge.yaml:1:3:1:21 | [YAMLMapping] &A { x: 23, y: 42 } | file://:0:0:0:0 | (Mapping 0) x: | semmle.label | 0 |
| merge.yaml:1:3:1:21 | [YAMLMapping] &A { x: 23, y: 42 } | file://:0:0:0:0 | (Mapping 0) x: | semmle.order | 0 |
| merge.yaml:1:3:1:21 | [YAMLMapping] &A { x: 23, y: 42 } | file://:0:0:0:0 | (Mapping 1) y: | semmle.label | 1 |
| merge.yaml:1:3:1:21 | [YAMLMapping] &A { x: 23, y: 42 } | file://:0:0:0:0 | (Mapping 1) y: | semmle.order | 1 |
| merge.yaml:2:3:3:8 | [YAMLMapping] x: 56 | file://:0:0:0:0 | (Mapping 0) x: | semmle.label | 0 |
| merge.yaml:2:3:3:8 | [YAMLMapping] x: 56 | file://:0:0:0:0 | (Mapping 0) x: | semmle.order | 0 |
| merge.yaml:2:3:3:8 | [YAMLMapping] x: 56 | file://:0:0:0:0 | (Mapping 1) <<: | semmle.label | 1 |
| merge.yaml:2:3:3:8 | [YAMLMapping] x: 56 | file://:0:0:0:0 | (Mapping 1) <<: | semmle.order | 1 |
| tst.yml:1:1:14:23 | [YAMLSequence] - "name ... Knopf" | tst.yml:1:3:7:0 | [YAMLMapping] "name": "Jim Knopf" | semmle.label | 0 |
| tst.yml:1:1:14:23 | [YAMLSequence] - "name ... Knopf" | tst.yml:1:3:7:0 | [YAMLMapping] "name": "Jim Knopf" | semmle.order | 0 |
| tst.yml:1:1:14:23 | [YAMLSequence] - "name ... Knopf" | tst.yml:7:3:14:0 | [YAMLMapping] name: Frau Mahlzahn | semmle.label | 1 |
| tst.yml:1:1:14:23 | [YAMLSequence] - "name ... Knopf" | tst.yml:7:3:14:0 | [YAMLMapping] name: Frau Mahlzahn | semmle.order | 1 |
| tst.yml:1:1:14:23 | [YAMLSequence] - "name ... Knopf" | tst.yml:14:3:14:23 | [YAMLScalar] !includ ... nal.yml | semmle.label | 2 |
| tst.yml:1:1:14:23 | [YAMLSequence] - "name ... Knopf" | tst.yml:14:3:14:23 | [YAMLScalar] !includ ... nal.yml | semmle.order | 2 |
| tst.yml:1:3:7:0 | [YAMLMapping] "name": "Jim Knopf" | file://:0:0:0:0 | (Mapping 0) name: | semmle.label | 0 |
| tst.yml:1:3:7:0 | [YAMLMapping] "name": "Jim Knopf" | file://:0:0:0:0 | (Mapping 0) name: | semmle.order | 0 |
| tst.yml:1:3:7:0 | [YAMLMapping] "name": "Jim Knopf" | file://:0:0:0:0 | (Mapping 1) address: | semmle.label | 1 |
| tst.yml:1:3:7:0 | [YAMLMapping] "name": "Jim Knopf" | file://:0:0:0:0 | (Mapping 1) address: | semmle.order | 1 |
| tst.yml:2:12:6:3 | [YAMLMapping] { | file://:0:0:0:0 | (Mapping 0) street: | semmle.label | 0 |
| tst.yml:2:12:6:3 | [YAMLMapping] { | file://:0:0:0:0 | (Mapping 0) street: | semmle.order | 0 |
| tst.yml:2:12:6:3 | [YAMLMapping] { | file://:0:0:0:0 | (Mapping 1) number: | semmle.label | 1 |
| tst.yml:2:12:6:3 | [YAMLMapping] { | file://:0:0:0:0 | (Mapping 1) number: | semmle.order | 1 |
| tst.yml:2:12:6:3 | [YAMLMapping] { | file://:0:0:0:0 | (Mapping 2) country: | semmle.label | 2 |
| tst.yml:2:12:6:3 | [YAMLMapping] { | file://:0:0:0:0 | (Mapping 2) country: | semmle.order | 2 |
| tst.yml:7:3:14:0 | [YAMLMapping] name: Frau Mahlzahn | file://:0:0:0:0 | (Mapping 0) name: | semmle.label | 0 |
| tst.yml:7:3:14:0 | [YAMLMapping] name: Frau Mahlzahn | file://:0:0:0:0 | (Mapping 0) name: | semmle.order | 0 |
| tst.yml:7:3:14:0 | [YAMLMapping] name: Frau Mahlzahn | file://:0:0:0:0 | (Mapping 1) address: | semmle.label | 1 |
| tst.yml:7:3:14:0 | [YAMLMapping] name: Frau Mahlzahn | file://:0:0:0:0 | (Mapping 1) address: | semmle.order | 1 |
| tst.yml:9:5:14:0 | [YAMLMapping] street: \| | file://:0:0:0:0 | (Mapping 0) street: | semmle.label | 0 |
| tst.yml:9:5:14:0 | [YAMLMapping] street: \| | file://:0:0:0:0 | (Mapping 0) street: | semmle.order | 0 |
| tst.yml:9:5:14:0 | [YAMLMapping] street: \| | file://:0:0:0:0 | (Mapping 1) number: | semmle.label | 1 |
| tst.yml:9:5:14:0 | [YAMLMapping] street: \| | file://:0:0:0:0 | (Mapping 1) number: | semmle.order | 1 |
| tst.yml:9:5:14:0 | [YAMLMapping] street: \| | file://:0:0:0:0 | (Mapping 2) country: | semmle.label | 2 |
| tst.yml:9:5:14:0 | [YAMLMapping] street: \| | file://:0:0:0:0 | (Mapping 2) country: | semmle.order | 2 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:1:3:1:8 | [YamlScalar] "name" | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:1:3:1:8 | [YamlScalar] "name" | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:1:11:1:21 | [YamlScalar] "Jim Knopf" | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:1:11:1:21 | [YamlScalar] "Jim Knopf" | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:7:3:7:6 | [YamlScalar] name | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:7:3:7:6 | [YamlScalar] name | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:7:9:7:21 | [YamlScalar] Frau Mahlzahn | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 0) name: | tst.yml:7:9:7:21 | [YamlScalar] Frau Mahlzahn | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:3:5:3:12 | [YamlScalar] "street" | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:3:5:3:12 | [YamlScalar] "street" | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:3:14:3:13 | [YamlScalar] | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:3:14:3:13 | [YamlScalar] | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:9:5:9:10 | [YamlScalar] street | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:9:5:9:10 | [YamlScalar] street | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:9:13:11:0 | [YamlScalar] \| | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 0) street: | tst.yml:9:13:11:0 | [YamlScalar] \| | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:1:8:1:8 | [YamlScalar] x | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:1:8:1:8 | [YamlScalar] x | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:1:11:1:12 | [YamlScalar] 23 | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:1:11:1:12 | [YamlScalar] 23 | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:2:3:2:3 | [YamlScalar] x | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:2:3:2:3 | [YamlScalar] x | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:2:6:2:7 | [YamlScalar] 56 | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 0) x: | merge.yaml:2:6:2:7 | [YamlScalar] 56 | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 1) <<: | merge.yaml:3:3:3:4 | [YamlScalar] << | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 1) <<: | merge.yaml:3:3:3:4 | [YamlScalar] << | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 1) <<: | merge.yaml:3:7:3:8 | [YamlAliasNode] *A | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 1) <<: | merge.yaml:3:7:3:8 | [YamlAliasNode] *A | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:2:3:2:9 | [YamlScalar] address | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:2:3:2:9 | [YamlScalar] address | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:2:12:6:3 | [YamlMapping] { | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:2:12:6:3 | [YamlMapping] { | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:8:3:8:9 | [YamlScalar] address | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:8:3:8:9 | [YamlScalar] address | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:9:5:14:0 | [YamlMapping] street: \| | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 1) address: | tst.yml:9:5:14:0 | [YamlMapping] street: \| | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:4:5:4:12 | [YamlScalar] "number" | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:4:5:4:12 | [YamlScalar] "number" | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:4:15:4:16 | [YamlScalar] -1 | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:4:15:4:16 | [YamlScalar] -1 | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:11:5:11:10 | [YamlScalar] number | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:11:5:11:10 | [YamlScalar] number | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:11:13:11:15 | [YamlScalar] 133 | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 1) number: | tst.yml:11:13:11:15 | [YamlScalar] 133 | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 1) y: | merge.yaml:1:15:1:15 | [YamlScalar] y | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 1) y: | merge.yaml:1:15:1:15 | [YamlScalar] y | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 1) y: | merge.yaml:1:18:1:19 | [YamlScalar] 42 | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 1) y: | merge.yaml:1:18:1:19 | [YamlScalar] 42 | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:5:5:5:13 | [YamlScalar] "country" | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:5:5:5:13 | [YamlScalar] "country" | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:5:16:5:27 | [YamlScalar] "Lummerland" | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:5:16:5:27 | [YamlScalar] "Lummerland" | semmle.order | 1 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:12:5:12:11 | [YamlScalar] country | semmle.label | 0 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:12:5:12:11 | [YamlScalar] country | semmle.order | 0 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:12:14:13:18 | [YamlScalar] < | semmle.label | 1 |
| file://:0:0:0:0 | (Mapping 2) country: | tst.yml:12:14:13:18 | [YamlScalar] < | semmle.order | 1 |
| merge.yaml:1:1:3:8 | [YamlSequence] - &A { ... y: 42 } | merge.yaml:1:3:1:21 | [YamlMapping] &A { x: 23, y: 42 } | semmle.label | 0 |
| merge.yaml:1:1:3:8 | [YamlSequence] - &A { ... y: 42 } | merge.yaml:1:3:1:21 | [YamlMapping] &A { x: 23, y: 42 } | semmle.order | 0 |
| merge.yaml:1:1:3:8 | [YamlSequence] - &A { ... y: 42 } | merge.yaml:2:3:3:8 | [YamlMapping] x: 56 | semmle.label | 1 |
| merge.yaml:1:1:3:8 | [YamlSequence] - &A { ... y: 42 } | merge.yaml:2:3:3:8 | [YamlMapping] x: 56 | semmle.order | 1 |
| merge.yaml:1:3:1:21 | [YamlMapping] &A { x: 23, y: 42 } | file://:0:0:0:0 | (Mapping 0) x: | semmle.label | 0 |
| merge.yaml:1:3:1:21 | [YamlMapping] &A { x: 23, y: 42 } | file://:0:0:0:0 | (Mapping 0) x: | semmle.order | 0 |
| merge.yaml:1:3:1:21 | [YamlMapping] &A { x: 23, y: 42 } | file://:0:0:0:0 | (Mapping 1) y: | semmle.label | 1 |
| merge.yaml:1:3:1:21 | [YamlMapping] &A { x: 23, y: 42 } | file://:0:0:0:0 | (Mapping 1) y: | semmle.order | 1 |
| merge.yaml:2:3:3:8 | [YamlMapping] x: 56 | file://:0:0:0:0 | (Mapping 0) x: | semmle.label | 0 |
| merge.yaml:2:3:3:8 | [YamlMapping] x: 56 | file://:0:0:0:0 | (Mapping 0) x: | semmle.order | 0 |
| merge.yaml:2:3:3:8 | [YamlMapping] x: 56 | file://:0:0:0:0 | (Mapping 1) <<: | semmle.label | 1 |
| merge.yaml:2:3:3:8 | [YamlMapping] x: 56 | file://:0:0:0:0 | (Mapping 1) <<: | semmle.order | 1 |
| tst.yml:1:1:14:23 | [YamlSequence] - "name ... Knopf" | tst.yml:1:3:7:0 | [YamlMapping] "name": "Jim Knopf" | semmle.label | 0 |
| tst.yml:1:1:14:23 | [YamlSequence] - "name ... Knopf" | tst.yml:1:3:7:0 | [YamlMapping] "name": "Jim Knopf" | semmle.order | 0 |
| tst.yml:1:1:14:23 | [YamlSequence] - "name ... Knopf" | tst.yml:7:3:14:0 | [YamlMapping] name: Frau Mahlzahn | semmle.label | 1 |
| tst.yml:1:1:14:23 | [YamlSequence] - "name ... Knopf" | tst.yml:7:3:14:0 | [YamlMapping] name: Frau Mahlzahn | semmle.order | 1 |
| tst.yml:1:1:14:23 | [YamlSequence] - "name ... Knopf" | tst.yml:14:3:14:23 | [YamlScalar] !includ ... nal.yml | semmle.label | 2 |
| tst.yml:1:1:14:23 | [YamlSequence] - "name ... Knopf" | tst.yml:14:3:14:23 | [YamlScalar] !includ ... nal.yml | semmle.order | 2 |
| tst.yml:1:3:7:0 | [YamlMapping] "name": "Jim Knopf" | file://:0:0:0:0 | (Mapping 0) name: | semmle.label | 0 |
| tst.yml:1:3:7:0 | [YamlMapping] "name": "Jim Knopf" | file://:0:0:0:0 | (Mapping 0) name: | semmle.order | 0 |
| tst.yml:1:3:7:0 | [YamlMapping] "name": "Jim Knopf" | file://:0:0:0:0 | (Mapping 1) address: | semmle.label | 1 |
| tst.yml:1:3:7:0 | [YamlMapping] "name": "Jim Knopf" | file://:0:0:0:0 | (Mapping 1) address: | semmle.order | 1 |
| tst.yml:2:12:6:3 | [YamlMapping] { | file://:0:0:0:0 | (Mapping 0) street: | semmle.label | 0 |
| tst.yml:2:12:6:3 | [YamlMapping] { | file://:0:0:0:0 | (Mapping 0) street: | semmle.order | 0 |
| tst.yml:2:12:6:3 | [YamlMapping] { | file://:0:0:0:0 | (Mapping 1) number: | semmle.label | 1 |
| tst.yml:2:12:6:3 | [YamlMapping] { | file://:0:0:0:0 | (Mapping 1) number: | semmle.order | 1 |
| tst.yml:2:12:6:3 | [YamlMapping] { | file://:0:0:0:0 | (Mapping 2) country: | semmle.label | 2 |
| tst.yml:2:12:6:3 | [YamlMapping] { | file://:0:0:0:0 | (Mapping 2) country: | semmle.order | 2 |
| tst.yml:7:3:14:0 | [YamlMapping] name: Frau Mahlzahn | file://:0:0:0:0 | (Mapping 0) name: | semmle.label | 0 |
| tst.yml:7:3:14:0 | [YamlMapping] name: Frau Mahlzahn | file://:0:0:0:0 | (Mapping 0) name: | semmle.order | 0 |
| tst.yml:7:3:14:0 | [YamlMapping] name: Frau Mahlzahn | file://:0:0:0:0 | (Mapping 1) address: | semmle.label | 1 |
| tst.yml:7:3:14:0 | [YamlMapping] name: Frau Mahlzahn | file://:0:0:0:0 | (Mapping 1) address: | semmle.order | 1 |
| tst.yml:9:5:14:0 | [YamlMapping] street: \| | file://:0:0:0:0 | (Mapping 0) street: | semmle.label | 0 |
| tst.yml:9:5:14:0 | [YamlMapping] street: \| | file://:0:0:0:0 | (Mapping 0) street: | semmle.order | 0 |
| tst.yml:9:5:14:0 | [YamlMapping] street: \| | file://:0:0:0:0 | (Mapping 1) number: | semmle.label | 1 |
| tst.yml:9:5:14:0 | [YamlMapping] street: \| | file://:0:0:0:0 | (Mapping 1) number: | semmle.order | 1 |
| tst.yml:9:5:14:0 | [YamlMapping] street: \| | file://:0:0:0:0 | (Mapping 2) country: | semmle.label | 2 |
| tst.yml:9:5:14:0 | [YamlMapping] street: \| | file://:0:0:0:0 | (Mapping 2) country: | semmle.order | 2 |
graphProperties
| semmle.graphKind | tree |

View File

@@ -1,18 +1,18 @@
import javascript
query predicate anchors(YAMLNode n, string anchor) { n.getAnchor() = anchor }
query predicate anchors(YamlNode n, string anchor) { n.getAnchor() = anchor }
query predicate eval(YAMLNode n, YAMLValue eval) {
query predicate eval(YamlNode n, YamlValue eval) {
not n.eval() = n and
eval = n.eval()
}
query predicate yamlParseError(YAMLParseError err) { any() }
query predicate yamlParseError(YamlParseError err) { any() }
query predicate yamlMapping_maps(YAMLMapping m, YAMLValue k, YAMLValue v) { m.maps(k, v) }
query predicate yamlMapping_maps(YamlMapping m, YamlValue k, YamlValue v) { m.maps(k, v) }
query predicate yamlNode(YAMLNode n, string tag) { tag = n.getTag() }
query predicate yamlNode(YamlNode n, string tag) { tag = n.getTag() }
query predicate yamlScalar(YAMLScalar s, string style, string value) {
query predicate yamlScalar(YamlScalar s, string style, string value) {
style = s.getStyle() and value = s.getValue()
}

View File

@@ -24,6 +24,7 @@ typeTracking
| tst.js:2:16:2:23 | source() | tst.js:29:14:29:14 | e |
| tst.js:2:16:2:23 | source() | tst.js:33:14:33:14 | e |
| tst.js:2:16:2:23 | source() | tst.js:37:14:37:14 | e |
| tst.js:2:16:2:23 | source() | tst.js:41:14:41:14 | e |
| tst.js:2:16:2:23 | source() | tst.js:45:14:45:14 | e |
| tst.js:2:16:2:23 | source() | tst.js:53:8:53:21 | map.get("key") |
| tst.js:2:16:2:23 | source() | tst.js:59:8:59:22 | map2.get("foo") |

View File

@@ -39,7 +39,7 @@
}
for (const e of new Set([source])) {
sink(e); // NOT OK (not caught by type-tracking, as it doesn't include array steps).
sink(e); // NOT OK
}
for (const e of new Set(set)) {

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