Merge remote-tracking branch 'upstream/main' into incomplete-hostname

This commit is contained in:
Arthur Baars
2022-03-16 12:31:12 +01:00
1166 changed files with 65711 additions and 51908 deletions

View File

@@ -8,6 +8,6 @@
import javascript
from JSXAttribute a
from JsxAttribute a
where a.getName() = "dangerouslySetInnerHTML"
select a

View File

@@ -4,7 +4,7 @@
* Configures boosting for adaptive threat modeling (ATM).
*/
private import javascript as raw
private import javascript as JS
import EndpointTypes
/**
@@ -28,23 +28,23 @@ import EndpointTypes
* `isAdditionalFlowStep` with a more generalised definition of additional edges. See
* `NosqlInjectionATM.qll` for an example of doing this.
*/
abstract class ATMConfig extends string {
abstract class AtmConfig extends string {
bindingset[this]
ATMConfig() { any() }
AtmConfig() { any() }
/**
* EXPERIMENTAL. This API may change in the future.
*
* Holds if `source` is a known source of flow.
*/
predicate isKnownSource(raw::DataFlow::Node source) { none() }
predicate isKnownSource(JS::DataFlow::Node source) { none() }
/**
* EXPERIMENTAL. This API may change in the future.
*
* Holds if `sink` is a known sink of flow.
*/
predicate isKnownSink(raw::DataFlow::Node sink) { none() }
predicate isKnownSink(JS::DataFlow::Node sink) { none() }
/**
* EXPERIMENTAL. This API may change in the future.
@@ -52,7 +52,7 @@ abstract class ATMConfig extends string {
* Holds if the candidate source `candidateSource` predicted by the machine learning model should be
* an effective source, i.e. one considered as a possible source of flow in the boosted query.
*/
predicate isEffectiveSource(raw::DataFlow::Node candidateSource) { none() }
predicate isEffectiveSource(JS::DataFlow::Node candidateSource) { none() }
/**
* EXPERIMENTAL. This API may change in the future.
@@ -60,29 +60,7 @@ abstract class ATMConfig extends string {
* Holds if the candidate sink `candidateSink` predicted by the machine learning model should be
* an effective sink, i.e. one considered as a possible sink of flow in the boosted query.
*/
predicate isEffectiveSink(raw::DataFlow::Node candidateSink) { none() }
/**
* EXPERIMENTAL. This API may change in the future.
*
* Holds if the candidate sink `candidateSink` predicted by the machine learning model should be
* an effective sink that overrides the score provided by the machine learning model with the
* score `score` for reason `why`. The effective sinks identified by this predicate MUST be a
* subset of those identified by the `isEffectiveSink` predicate.
*
* For example, in the ATM external API query, we use this method to ensure the ATM external API
* query produces the same results as the standard external API query, but assigns flows
* involving sinks that are filtered out by the endpoint filters a score of 0.
*
* This predicate can be phased out once we no longer need to rely on predicates like
* `paddedScore` in the ATM CodeQL libraries to add scores to alert messages in a way that works
* with lexical sort orders.
*/
predicate isEffectiveSinkWithOverridingScore(
raw::DataFlow::Node candidateSink, float score, string why
) {
none()
}
predicate isEffectiveSink(JS::DataFlow::Node candidateSink) { none() }
/**
* EXPERIMENTAL. This API may change in the future.
@@ -110,3 +88,6 @@ abstract class ATMConfig extends string {
*/
float getScoreCutoff() { result = 0.0 }
}
/** DEPRECATED: Alias for AtmConfig */
deprecated class ATMConfig = AtmConfig;

View File

@@ -4,8 +4,7 @@
* Provides information about the results of boosted queries for use in adaptive threat modeling (ATM).
*/
private import javascript as raw
private import raw::DataFlow as DataFlow
private import javascript::DataFlow as DataFlow
import ATMConfig
private import BaseScoring
private import EndpointScoring as EndpointScoring

View File

@@ -12,7 +12,7 @@ external predicate availableMlModels(
);
/** Get the ATM configuration. */
ATMConfig getCfg() { any() }
AtmConfig getCfg() { any() }
/**
* A string containing scoring information produced by a scoring model.

View File

@@ -61,7 +61,7 @@ predicate isArgumentToKnownLibrarySinkFunction(DataFlow::Node n) {
* This corresponds to known sinks from security queries whose sources include remote flow and
* DOM-based sources.
*/
predicate isKnownExternalAPIQuerySink(DataFlow::Node n) {
predicate isKnownExternalApiQuerySink(DataFlow::Node n) {
n instanceof Xxe::Sink or
n instanceof TaintedPath::Sink or
n instanceof XpathInjection::Sink or
@@ -86,11 +86,14 @@ predicate isKnownExternalAPIQuerySink(DataFlow::Node n) {
n instanceof HttpToFileAccess::Sink
}
/** DEPRECATED: Alias for isKnownExternalApiQuerySink */
deprecated predicate isKnownExternalAPIQuerySink = isKnownExternalApiQuerySink/1;
/**
* Holds if the node `n` is a known sink in a modeled library.
*/
predicate isKnownLibrarySink(DataFlow::Node n) {
isKnownExternalAPIQuerySink(n) or
isKnownExternalApiQuerySink(n) or
n instanceof CleartextLogging::Sink or
n instanceof StackTraceExposure::Sink or
n instanceof ShellCommandInjectionFromEnvironment::Sink or
@@ -207,7 +210,7 @@ predicate isOtherModeledArgument(DataFlow::Node n, FilteringReason reason) {
DatabaseAccess and
reason instanceof DatabaseAccessReason
or
call = DOM::domValueRef() and reason instanceof DOMReason
call = DOM::domValueRef() and reason instanceof DomReason
or
call.getCalleeName() = "next" and
exists(DataFlow::FunctionNode f | call = f.getLastParameter().getACall()) and

View File

@@ -62,14 +62,11 @@ private float getScoreForSource(DataFlow::Node source) {
private float getScoreForSink(DataFlow::Node sink) {
if getCfg().isKnownSink(sink)
then result = 1.0
else
if getCfg().isEffectiveSinkWithOverridingScore(sink, result, _)
then any()
else (
// This restriction on `sink` has no semantic effect but improves performance.
getCfg().isEffectiveSink(sink) and
ModelScoring::endpointScores(sink, getCfg().getASinkEndpointType().getEncoding(), result)
)
else (
// This restriction on `sink` has no semantic effect but improves performance.
getCfg().isEffectiveSink(sink) and
ModelScoring::endpointScores(sink, getCfg().getASinkEndpointType().getEncoding(), result)
)
}
class EndpointScoringResults extends ScoringResults {
@@ -109,10 +106,6 @@ class EndpointScoringResults extends ScoringResults {
result = "known" and getCfg().isKnownSink(sink)
or
not getCfg().isKnownSink(sink) and
getCfg().isEffectiveSinkWithOverridingScore(sink, _, result)
or
not getCfg().isKnownSink(sink) and
not getCfg().isEffectiveSinkWithOverridingScore(sink, _, _) and
result =
"predicted (scores: " +
concat(EndpointType type, float score |
@@ -127,29 +120,21 @@ class EndpointScoringResults extends ScoringResults {
override predicate shouldResultBeIncluded(DataFlow::Node source, DataFlow::Node sink) {
if getCfg().isKnownSink(sink)
then any()
else
if getCfg().isEffectiveSinkWithOverridingScore(sink, _, _)
then
exists(float score |
getCfg().isEffectiveSinkWithOverridingScore(sink, score, _) and
score >= getCfg().getScoreCutoff()
)
else (
// This restriction on `sink` has no semantic effect but improves performance.
getCfg().isEffectiveSink(sink) and
exists(float sinkScore |
ModelScoring::endpointScores(sink, getCfg().getASinkEndpointType().getEncoding(),
sinkScore) and
// Include the endpoint if (a) the query endpoint type scores higher than all other
// endpoint types, or (b) the query endpoint type scores at least
// 0.5 - (getCfg().getScoreCutoff() / 2).
sinkScore >=
[
max(float s | ModelScoring::endpointScores(sink, _, s)),
0.5 - getCfg().getScoreCutoff() / 2
]
)
else (
// This restriction on `sink` has no semantic effect but improves performance.
getCfg().isEffectiveSink(sink) and
exists(float sinkScore |
ModelScoring::endpointScores(sink, getCfg().getASinkEndpointType().getEncoding(), sinkScore) and
// Include the endpoint if (a) the query endpoint type scores higher than all other
// endpoint types, or (b) the query endpoint type scores at least
// 0.5 - (getCfg().getScoreCutoff() / 2).
sinkScore >=
[
max(float s | ModelScoring::endpointScores(sink, _, s)),
0.5 - getCfg().getScoreCutoff() / 2
]
)
)
}
}

View File

@@ -24,7 +24,7 @@ newtype TFilteringReason =
TMembershipCandidateTestReason() or
TFileSystemAccessReason() or
TDatabaseAccessReason() or
TDOMReason() or
TDomReason() or
TNextFunctionCallReason() or
TArgumentToArrayReason() or
TArgumentToBuiltinGlobalVarRefReason() or
@@ -161,12 +161,15 @@ class DatabaseAccessReason extends NotASinkReason, TDatabaseAccessReason {
override int getEncoding() { result = 21 }
}
class DOMReason extends NotASinkReason, TDOMReason {
class DomReason extends NotASinkReason, TDomReason {
override string getDescription() { result = "DOM" }
override int getEncoding() { result = 22 }
}
/** DEPRECATED: Alias for DomReason */
deprecated class DOMReason = DomReason;
class NextFunctionCallReason extends NotASinkReason, TNextFunctionCallReason {
override string getDescription() { result = "NextFunctionCall" }

View File

@@ -10,7 +10,7 @@ private import FeaturizationConfig
/**
* Gets a tokenized representation of the AST node for use in the `enclosingFunctionBody` feature.
*/
string getTokenizedAstNode(ASTNode node) {
string getTokenizedAstNode(AstNode node) {
// e.g. `x` -> "x"
result = node.(Identifier).getName()
or
@@ -35,12 +35,15 @@ string getTokenizedAstNode(ASTNode node) {
/** Gets an AST node within the function `f` that we should featurize. */
pragma[inline]
ASTNode getAnASTNodeToFeaturize(Function f) {
AstNode getAnAstNodeToFeaturize(Function f) {
result.getParent*() = f and
// Don't featurize the function name as part of the function body tokens
not result = f.getIdentifier()
}
/** DEPRECATED: Alias for getAnAstNodeToFeaturize */
deprecated ASTNode getAnASTNodeToFeaturize(Function f) { result = getAnAstNodeToFeaturize(f) }
/**
* Gets a function that contains the endpoint.
*
@@ -72,7 +75,7 @@ private int getMaxNumAstNodes() { result = 1024 }
private int getNumAstNodesInFunction(Function function) {
// Restrict the values `function` can take on
function = getAFunctionForEndpoint(_) and
result = count(getAnASTNodeToFeaturize(function))
result = count(getAnAstNodeToFeaturize(function))
}
/**
@@ -121,16 +124,19 @@ Function getRepresentativeFunctionForEndpoint(DataFlow::Node endpoint) {
}
/** Returns an AST node within the function `f` that an associated token feature. */
ASTNode getAnASTNodeWithAFeature(Function f) {
AstNode getAnAstNodeWithAFeature(Function f) {
// Performance optimization: Restrict the set of functions to those containing an endpoint to featurize.
f = getRepresentativeFunctionForEndpoint(any(FeaturizationConfig cfg).getAnEndpointToFeaturize()) and
result = getAnASTNodeToFeaturize(f)
result = getAnAstNodeToFeaturize(f)
}
/** DEPRECATED: Alias for getAnAstNodeWithAFeature */
deprecated ASTNode getAnASTNodeWithAFeature(Function f) { result = getAnAstNodeWithAFeature(f) }
/** Returns the number of source-code characters in a function. */
int getNumCharsInFunction(Function f) {
result =
strictsum(ASTNode node | node = getAnASTNodeWithAFeature(f) | getTokenizedAstNode(node).length())
strictsum(AstNode node | node = getAnAstNodeWithAFeature(f) | getTokenizedAstNode(node).length())
}
/**
@@ -149,8 +155,8 @@ string getBodyTokensFeature(Function function) {
// large body features are replaced by the absent token.
//
// We count nodes instead of tokens because tokens are often not unique.
strictcount(ASTNode node |
node = getAnASTNodeToFeaturize(function) and
strictcount(AstNode node |
node = getAnAstNodeToFeaturize(function) and
exists(getTokenizedAstNode(node))
) <= 256 and
// Performance optimization: If a function has more than getMaxChars() characters in its body subtokens,
@@ -161,8 +167,8 @@ string getBodyTokensFeature(Function function) {
// The use of a nested exists here allows us to avoid duplicates due to two AST nodes in the
// same location featurizing to the same token. By using a nested exists, we take only unique
// (location, token) pairs.
exists(ASTNode node |
node = getAnASTNodeToFeaturize(function) and
exists(AstNode node |
node = getAnAstNodeToFeaturize(function) and
token = getTokenizedAstNode(node) and
l = node.getLocation()
)

View File

@@ -87,8 +87,8 @@ module SinkEndpointFilter {
}
}
class NosqlInjectionATMConfig extends ATMConfig {
NosqlInjectionATMConfig() { this = "NosqlInjectionATMConfig" }
class NosqlInjectionAtmConfig extends AtmConfig {
NosqlInjectionAtmConfig() { this = "NosqlInjectionATMConfig" }
override predicate isKnownSource(DataFlow::Node source) {
source instanceof NosqlInjection::Source or TaintedObject::isSource(source, _)
@@ -103,7 +103,10 @@ class NosqlInjectionATMConfig extends ATMConfig {
override EndpointType getASinkEndpointType() { result instanceof NosqlInjectionSinkType }
}
/** Holds if src -> trg is an additional flow step in the non-boosted NoSQL injection security query. */
/** DEPRECATED: Alias for NosqlInjectionAtmConfig */
deprecated class NosqlInjectionATMConfig = NosqlInjectionAtmConfig;
/** Holds if src -> trg is an additional flow step in the non-boosted NoSql injection security query. */
predicate isBaseAdditionalFlowStep(
DataFlow::Node src, DataFlow::Node trg, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
) {
@@ -112,7 +115,7 @@ predicate isBaseAdditionalFlowStep(
// additional flow step to track taint through NoSQL query objects
inlbl = TaintedObject::label() and
outlbl = TaintedObject::label() and
exists(NoSQL::Query query, DataFlow::SourceNode queryObj |
exists(NoSql::Query query, DataFlow::SourceNode queryObj |
queryObj.flowsToExpr(query) and
queryObj.flowsTo(trg) and
src = queryObj.getAPropertyWrite().getRhs()
@@ -120,13 +123,17 @@ predicate isBaseAdditionalFlowStep(
}
/**
* Gets a value that is (transitively) written to `query`, where `query` is a NoSQL sink.
*
* This predicate allows us to propagate data flow through property writes and array constructors
* within a query object, enabling the security query to pick up NoSQL injection vulnerabilities
* involving more complex queries.
*/
DataFlow::Node getASubexpressionWithinQuery(DataFlow::Node query) {
any(NosqlInjectionAtmConfig cfg).isEffectiveSink(query) and
exists(DataFlow::SourceNode receiver |
receiver.flowsTo(getASubexpressionWithinQuery*(query.getALocalSource())) and
receiver = [getASubexpressionWithinQuery(query), query].getALocalSource()
|
result =
[receiver.getAPropertyWrite().getRhs(), receiver.(DataFlow::ArrayCreationNode).getAnElement()]
)
@@ -152,7 +159,7 @@ class Configuration extends TaintTracking::Configuration {
sink.(NosqlInjection::Sink).getAFlowLabel() = label
or
// Allow effective sinks to have any taint label
any(NosqlInjectionATMConfig cfg).isEffectiveSink(sink)
any(NosqlInjectionAtmConfig cfg).isEffectiveSink(sink)
}
override predicate isSanitizer(DataFlow::Node node) {
@@ -171,7 +178,7 @@ class Configuration extends TaintTracking::Configuration {
isBaseAdditionalFlowStep(src, trg, inlbl, outlbl)
or
// relaxed version of previous step to track taint through unmodeled NoSQL query objects
any(NosqlInjectionATMConfig cfg).isEffectiveSink(trg) and
any(NosqlInjectionAtmConfig cfg).isEffectiveSink(trg) and
src = getASubexpressionWithinQuery(trg)
}
}

View File

@@ -60,8 +60,8 @@ module SinkEndpointFilter {
}
}
class SqlInjectionATMConfig extends ATMConfig {
SqlInjectionATMConfig() { this = "SqlInjectionATMConfig" }
class SqlInjectionAtmConfig extends AtmConfig {
SqlInjectionAtmConfig() { this = "SqlInjectionATMConfig" }
override predicate isKnownSource(DataFlow::Node source) { source instanceof SqlInjection::Source }
@@ -74,6 +74,9 @@ class SqlInjectionATMConfig extends ATMConfig {
override EndpointType getASinkEndpointType() { result instanceof SqlInjectionSinkType }
}
/** DEPRECATED: Alias for SqlInjectionAtmConfig */
deprecated class SqlInjectionATMConfig = SqlInjectionAtmConfig;
/**
* A taint-tracking configuration for reasoning about SQL injection vulnerabilities.
*
@@ -86,7 +89,7 @@ class Configuration extends TaintTracking::Configuration {
override predicate isSource(DataFlow::Node source) { source instanceof SqlInjection::Source }
override predicate isSink(DataFlow::Node sink) {
sink instanceof SqlInjection::Sink or any(SqlInjectionATMConfig cfg).isEffectiveSink(sink)
sink instanceof SqlInjection::Sink or any(SqlInjectionAtmConfig cfg).isEffectiveSink(sink)
}
override predicate isSanitizer(DataFlow::Node node) {

View File

@@ -59,8 +59,8 @@ module SinkEndpointFilter {
}
}
class TaintedPathATMConfig extends ATMConfig {
TaintedPathATMConfig() { this = "TaintedPathATMConfig" }
class TaintedPathAtmConfig extends AtmConfig {
TaintedPathAtmConfig() { this = "TaintedPathATMConfig" }
override predicate isKnownSource(DataFlow::Node source) { source instanceof TaintedPath::Source }
@@ -73,6 +73,9 @@ class TaintedPathATMConfig extends ATMConfig {
override EndpointType getASinkEndpointType() { result instanceof TaintedPathSinkType }
}
/** DEPRECATED: Alias for TaintedPathAtmConfig */
deprecated class TaintedPathATMConfig = TaintedPathAtmConfig;
/**
* A taint-tracking configuration for reasoning about path injection vulnerabilities.
*
@@ -88,7 +91,7 @@ class Configuration extends TaintTracking::Configuration {
label = sink.(TaintedPath::Sink).getAFlowLabel()
or
// Allow effective sinks to have any taint label
any(TaintedPathATMConfig cfg).isEffectiveSink(sink)
any(TaintedPathAtmConfig cfg).isEffectiveSink(sink)
}
override predicate isSanitizer(DataFlow::Node node) { node instanceof TaintedPath::Sanitizer }

View File

@@ -60,8 +60,8 @@ module SinkEndpointFilter {
}
}
class DomBasedXssATMConfig extends ATMConfig {
DomBasedXssATMConfig() { this = "DomBasedXssATMConfig" }
class DomBasedXssAtmConfig extends AtmConfig {
DomBasedXssAtmConfig() { this = "DomBasedXssATMConfig" }
override predicate isKnownSource(DataFlow::Node source) { source instanceof DomBasedXss::Source }
@@ -74,6 +74,9 @@ class DomBasedXssATMConfig extends ATMConfig {
override EndpointType getASinkEndpointType() { result instanceof XssSinkType }
}
/** DEPRECATED: Alias for DomBasedXssAtmConfig */
deprecated class DomBasedXssATMConfig = DomBasedXssAtmConfig;
/**
* A taint-tracking configuration for reasoning about XSS vulnerabilities.
*
@@ -87,7 +90,7 @@ class Configuration extends TaintTracking::Configuration {
override predicate isSink(DataFlow::Node sink) {
sink instanceof DomBasedXss::Sink or
any(DomBasedXssATMConfig cfg).isEffectiveSink(sink)
any(DomBasedXssAtmConfig cfg).isEffectiveSink(sink)
}
override predicate isSanitizer(DataFlow::Node node) {

View File

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

View File

@@ -33,7 +33,7 @@ string getDescriptionForAlertCandidate(
) {
result = "excluded[reason=" + getAReasonSinkExcluded(sinkCandidate, query) + "]"
or
getATMCfg(query).isKnownSink(sinkCandidate) and
getAtmCfg(query).isKnownSink(sinkCandidate) and
result = "excluded[reason=known-sink]"
or
not exists(getAReasonSinkExcluded(sinkCandidate, query)) and

View File

@@ -20,7 +20,7 @@ import semmle.javascript.security.dataflow.DeepObjectResourceExhaustionQuery as
import semmle.javascript.security.dataflow.DifferentKindsComparisonBypassQuery as DifferentKindsComparisonBypass
import semmle.javascript.security.dataflow.DomBasedXssQuery as DomBasedXss
import semmle.javascript.security.dataflow.ExceptionXssQuery as ExceptionXss
import semmle.javascript.security.dataflow.ExternalAPIUsedWithUntrustedDataQuery as ExternalAPIUsedWithUntrustedData
import semmle.javascript.security.dataflow.ExternalAPIUsedWithUntrustedDataQuery as ExternalApiUsedWithUntrustedData
import semmle.javascript.security.dataflow.FileAccessToHttpQuery as FileAccessToHttp
import semmle.javascript.security.dataflow.HardcodedCredentialsQuery as HardcodedCredentials
import semmle.javascript.security.dataflow.HardcodedDataInterpretedAsCodeQuery as HardcodedDataInterpretedAsCode

View File

@@ -23,17 +23,20 @@ import NoFeaturizationRestrictionsConfig
import Queries
/** Gets the ATM configuration object for the specified query. */
ATMConfig getATMCfg(Query 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 */
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
@@ -47,7 +50,7 @@ DataFlow::Configuration getDataFlowCfg(Query query) {
/** Gets a known sink for the specified query. */
private DataFlow::Node getASink(Query query) {
getATMCfg(query).isKnownSink(result) and
getAtmCfg(query).isKnownSink(result) and
// Only consider the source code for the project being analyzed.
exists(result.getFile().getRelativePath())
}
@@ -71,10 +74,7 @@ private DataFlow::Node getANotASink(NotASinkReason reason) {
* specified query.
*/
private DataFlow::Node getAnUnknown(Query query) {
(
getATMCfg(query).isEffectiveSink(result) or
getATMCfg(query).isEffectiveSinkWithOverridingScore(result, _, _)
) and
getAtmCfg(query).isEffectiveSink(result) and
not result = getASink(query) and
// Only consider the source code for the project being analyzed.
exists(result.getFile().getRelativePath())

View File

@@ -0,0 +1,28 @@
/*
* For internal use only.
*
* 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.AdaptiveThreatModeling
from string queryName, AtmConfig c, EndpointType e
where
(
queryName = "SqlInjectionATM.ql" and
c instanceof SqlInjectionATM::SqlInjectionAtmConfig
or
queryName = "NosqlInjectionATM.ql" and
c instanceof NosqlInjectionATM::NosqlInjectionAtmConfig
or
queryName = "TaintedPathInjectionATM.ql" and
c instanceof TaintedPathATM::TaintedPathAtmConfig
or
queryName = "XssATM.ql" and c instanceof XssATM::DomBasedXssAtmConfig
) and
e = c.getASinkEndpointType()
select queryName, e.getEncoding() as endpointTypeEncoded

View File

@@ -19,8 +19,8 @@ EndpointType getEndpointType() { result instanceof NosqlInjectionSinkType }
DataFlow::Node getAPositiveEndpoint() { result instanceof NosqlInjection::Sink }
/** An ATM configuration to find misclassified endpoints of type `getEndpointType()`. */
class ExtractMisclassifiedEndpointsATMConfig extends ATMConfig {
ExtractMisclassifiedEndpointsATMConfig() { this = "ExtractMisclassifiedEndpointsATMConfig" }
class ExtractMisclassifiedEndpointsAtmConfig extends AtmConfig {
ExtractMisclassifiedEndpointsAtmConfig() { this = "ExtractMisclassifiedEndpointsATMConfig" }
override predicate isEffectiveSink(DataFlow::Node sinkCandidate) {
sinkCandidate = getAPositiveEndpoint()
@@ -31,7 +31,7 @@ class ExtractMisclassifiedEndpointsATMConfig extends ATMConfig {
/** Get an endpoint from `getAPositiveEndpoint()` that is incorrectly excluded from the results. */
DataFlow::Node getAMisclassifedEndpoint() {
any(ExtractMisclassifiedEndpointsATMConfig config).isEffectiveSink(result) and
any(ExtractMisclassifiedEndpointsAtmConfig config).isEffectiveSink(result) and
not any(ScoringResults results).shouldResultBeIncluded(_, result)
}

View File

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

View File

@@ -1,3 +1,13 @@
## 0.0.12
### Major Analysis Improvements
* Added support for TypeScript 4.6.
### Minor Analysis Improvements
* Added sources from the [`jszip`](https://www.npmjs.com/package/jszip) library to the `js/zipslip` query.
## 0.0.11
## 0.0.10

View File

@@ -4,15 +4,16 @@
import semmle.javascript.Externs
/** Holds if `et` is a root interface of the DOM type hierarchy. */
predicate isDOMRootType(ExternalType et) {
exists(string n | n = et.getName() | n = "EventTarget" or n = "StyleSheet")
}
/** DEPRECATED: Alias for isDomRootType */
deprecated predicate isDOMRootType = isDomRootType/1;
/** Holds if `p` is declared as a property of a DOM class or interface. */
pragma[nomagic]
predicate isDOMProperty(string p) {
predicate isDomProperty(string p) {
exists(ExternalMemberDecl emd | emd.getName() = p |
isDOMRootType(emd.getDeclaringType().getASupertype*())
isDomRootType(emd.getDeclaringType().getASupertype*())
)
}
/** DEPRECATED: Alias for isDomProperty */
deprecated predicate isDOMProperty = isDomProperty/1;

View File

@@ -143,7 +143,7 @@ predicate hasNoEffect(Expr e) {
// don't complain about declarations
not isDeclaration(e) and
// exclude DOM properties, which sometimes have magical auto-update properties
not isDOMProperty(e.(PropAccess).getPropertyName()) and
not isDomProperty(e.(PropAccess).getPropertyName()) and
// exclude xUnit.js annotations
not e instanceof XUnitAnnotation and
// exclude common patterns that are most likely intentional

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Added sources from the [`jszip`](https://www.npmjs.com/package/jszip) library to the `js/zipslip` query.

View File

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

View File

@@ -0,0 +1,5 @@
---
category: deprecated
---
* Many classes/predicates/modules that had upper-case acronyms have been renamed to follow our style-guide.
The old name still exists as a deprecated alias.

View File

@@ -0,0 +1,5 @@
---
category: deprecated
---
* Some modules that started with a lowercase letter have been renamed to follow our style-guide.
The old name still exists as a deprecated alias.

View File

@@ -0,0 +1,5 @@
---
category: deprecated
---
* Some predicates from `DefUse.qll`, `DataFlow.qll`, `TaintTracking.qll`, `DOM.qll`, `Definitions.qll` that weren't used by any query have been deprecated.
The documentation for each predicate points to an alternative.

View File

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

View File

@@ -0,0 +1,9 @@
## 0.0.12
### Major Analysis Improvements
* Added support for TypeScript 4.6.
### Minor Analysis Improvements
* Added sources from the [`jszip`](https://www.npmjs.com/package/jszip) library to the `js/zipslip` query.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.0.11
lastReleaseVersion: 0.0.12

View File

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

View File

@@ -185,11 +185,6 @@ class AmdModuleDefinition extends CallExpr {
}
}
/**
* DEPRECATED: Use `AmdModuleDefinition` instead.
*/
deprecated class AMDModuleDefinition = AmdModuleDefinition;
/** An AMD dependency, considered as a path expression. */
private class AmdDependencyPath extends PathExprCandidate {
AmdDependencyPath() {
@@ -327,8 +322,3 @@ class AmdModule extends Module {
result = getDefine().getModuleExpr().flow()
}
}
/**
* DEPRECATED: Use `AmdModule` instead.
*/
deprecated class AMDModule = AmdModule;

View File

@@ -22,7 +22,7 @@ private import semmle.javascript.internal.CachedStages
* abs(-42);
* ```
*/
class ASTNode extends @ast_node, NodeInStmtContainer {
class AstNode extends @ast_node, NodeInStmtContainer {
override Location getLocation() { hasLocation(this, result) }
override File getFile() {
@@ -84,7 +84,7 @@ class ASTNode extends @ast_node, NodeInStmtContainer {
* _Note_: The indices of child nodes are considered an implementation detail and may
* change between versions of the extractor.
*/
ASTNode getChild(int i) {
AstNode getChild(int i) {
result = this.getChildExpr(i) or
result = this.getChildStmt(i) or
properties(result, this, i, _, _) or
@@ -101,7 +101,7 @@ class ASTNode extends @ast_node, NodeInStmtContainer {
TypeExpr getChildTypeExpr(int i) { typeexprs(result, _, this, i, _) }
/** Gets a child node of this node. */
ASTNode getAChild() { result = this.getChild(_) }
AstNode getAChild() { result = this.getChild(_) }
/** Gets a child expression of this node. */
Expr getAChildExpr() { result = this.getChildExpr(_) }
@@ -120,7 +120,7 @@ class ASTNode extends @ast_node, NodeInStmtContainer {
/** Gets the parent node of this node, if any. */
cached
ASTNode getParent() { Stages::Ast::ref() and this = result.getAChild() }
AstNode getParent() { Stages::Ast::ref() and this = result.getAChild() }
/** Gets the first control flow node belonging to this syntactic entity. */
ControlFlowNode getFirstControlFlowNode() { result = this }
@@ -184,6 +184,9 @@ class ASTNode extends @ast_node, NodeInStmtContainer {
}
}
/** DEPRECATED: Alias for AstNode */
deprecated class ASTNode = AstNode;
/**
* Holds if the given file is a `.d.ts` file.
*/
@@ -334,7 +337,10 @@ class EventHandlerCode extends @event_handler, CodeInAttribute { }
* <a href="javascript:alert('hi')">Click me</a>
* ```
*/
class JavaScriptURL extends @javascript_url, CodeInAttribute { }
class JavaScriptUrl extends @javascript_url, CodeInAttribute { }
/** DEPRECATED: Alias for JavaScriptUrl */
deprecated class JavaScriptURL = JavaScriptUrl;
/**
* A toplevel syntactic entity containing Closure-style externs definitions.
@@ -361,7 +367,7 @@ class Externs extends TopLevel {
* i = 9
* ```
*/
class ExprOrStmt extends @expr_or_stmt, ControlFlowNode, ASTNode { }
class ExprOrStmt extends @expr_or_stmt, ControlFlowNode, AstNode { }
/**
* A program element that contains statements, but isn't itself
@@ -375,7 +381,7 @@ class ExprOrStmt extends @expr_or_stmt, ControlFlowNode, ASTNode { }
* }
* ```
*/
class StmtContainer extends @stmt_container, ASTNode {
class StmtContainer extends @stmt_container, AstNode {
/** Gets the innermost enclosing container in which this container is nested. */
cached
StmtContainer getEnclosingContainer() { none() }
@@ -405,7 +411,7 @@ class StmtContainer extends @stmt_container, ASTNode {
* For scripts or modules, this is the container itself; for functions,
* it is the function body.
*/
ASTNode getBody() { result = this }
AstNode getBody() { result = this }
/**
* Gets the (unique) entry node of the control flow graph for this toplevel or function.
@@ -470,7 +476,7 @@ module AST {
* function id(x) { return x; } // function declaration
* ```
*/
class ValueNode extends ASTNode, @dataflownode {
class ValueNode extends AstNode, @dataflownode {
/** Gets type inference results for this element. */
DataFlow::AnalyzedNode analyze() { result = DataFlow::valueNode(this).analyze() }

View File

@@ -13,11 +13,6 @@ class ArrayAccess = IndexExpr;
class AssignOp = CompoundAssignExpr;
/**
* DEPRECATED: The name `BlockStmt` is now preferred in all languages.
*/
deprecated class Block = BlockStmt;
class BoolLiteral = BooleanLiteral;
class CaseStmt = Case;
@@ -67,302 +62,3 @@ class ThisAccess = ThisExpr;
class VariableAccess = VarAccess;
class XorBitwiseExpr = XOrExpr;
// Aliases for deprecated predicates from the dbscheme
/**
* Alias for the predicate `is_externs` defined in the .dbscheme.
* Use `TopLevel#isExterns()` instead.
*/
deprecated predicate isExterns(TopLevel toplevel) { is_externs(toplevel) }
/**
* Alias for the predicate `is_module` defined in the .dbscheme.
* Use the `Module` class in `Module.qll` instead.
*/
deprecated predicate isModule(TopLevel toplevel) { is_module(toplevel) }
/**
* Alias for the predicate `is_nodejs` defined in the .dbscheme.
* Use `NodeModule` from `NodeJS.qll` instead.
*/
deprecated predicate isNodejs(TopLevel toplevel) { is_nodejs(toplevel) }
/**
* Alias for the predicate `is_es2015_module` defined in the .dbscheme.
* Use `ES2015Module` from `ES2015Modules.qll` instead.
*/
deprecated predicate isES2015Module(TopLevel toplevel) { is_es2015_module(toplevel) }
/**
* Alias for the predicate `is_closure_module` defined in the .dbscheme.
*/
deprecated predicate isClosureModule(TopLevel toplevel) { is_closure_module(toplevel) }
/**
* Alias for the predicate `stmt_containers` defined in the .dbscheme.
* Use `ASTNode#getContainer()` instead.
*/
deprecated predicate stmtContainers(Stmt stmt, StmtContainer container) {
stmt_containers(stmt, container)
}
/**
* Alias for the predicate `jump_targets` defined in the .dbscheme.
* Use `JumpStmt#getTarget()` instead.
*/
deprecated predicate jumpTargets(Stmt jump, Stmt target) { jump_targets(jump, target) }
/**
* Alias for the predicate `is_instantiated` defined in the .dbscheme.
* Use `NamespaceDeclaration#isInstantiated() instead.`
*/
deprecated predicate isInstantiated(NamespaceDeclaration decl) { is_instantiated(decl) }
/**
* Alias for the predicate `has_declare_keyword` defined in the .dbscheme.
*/
deprecated predicate hasDeclareKeyword(ASTNode stmt) { has_declare_keyword(stmt) }
/**
* Alias for the predicate `is_for_await_of` defined in the .dbscheme.
* Use `ForOfStmt#isAwait()` instead.
*/
deprecated predicate isForAwaitOf(ForOfStmt forof) { is_for_await_of(forof) }
/**
* Alias for the predicate `enclosing_stmt` defined in the .dbscheme.
* Use `ExprOrType#getEnclosingStmt` instead.
*/
deprecated predicate enclosingStmt(ExprOrType expr, Stmt stmt) { enclosing_stmt(expr, stmt) }
/**
* Alias for the predicate `expr_containers` defined in the .dbscheme.
* Use `ASTNode#getContainer()` instead.
*/
deprecated predicate exprContainers(ExprOrType expr, StmtContainer container) {
expr_containers(expr, container)
}
/**
* Alias for the predicate `array_size` defined in the .dbscheme.
* Use `ArrayExpr#getSize()` instead.
*/
deprecated predicate arraySize(Expr ae, int sz) { array_size(ae, sz) }
/**
* Alias for the predicate `is_delegating` defined in the .dbscheme.
* Use `YieldExpr#isDelegating()` instead.
*/
deprecated predicate isDelegating(YieldExpr yield) { is_delegating(yield) }
/**
* Alias for the predicate `is_arguments_object` defined in the .dbscheme.
* Use the `ArgumentsVariable` class instead.
*/
deprecated predicate isArgumentsObject(Variable id) { is_arguments_object(id) }
/**
* Alias for the predicate `is_computed` defined in the .dbscheme.
* Use the `isComputed()` method on the `MemberDeclaration`/`Property`/`PropertyPattern` class instead.
*/
deprecated predicate isComputed(Property prop) { is_computed(prop) }
/**
* Alias for the predicate `is_method` defined in the .dbscheme.
* Use the `isMethod()` method on the `MemberDeclaration`/`Property` class instead.
*/
deprecated predicate isMethod(Property prop) { is_method(prop) }
/**
* Alias for the predicate `is_static` defined in the .dbscheme.
* Use `MemberDeclaration#isStatic()` instead.
*/
deprecated predicate isStatic(Property prop) { is_static(prop) }
/**
* Alias for the predicate `is_abstract_member` defined in the .dbscheme.
* Use `MemberDeclaration#isAbstract()` instead.
*/
deprecated predicate isAbstractMember(Property prop) { is_abstract_member(prop) }
/**
* Alias for the predicate `is_const_enum` defined in the .dbscheme.
* Use `EnumDeclaration#isConst()` instead.
*/
deprecated predicate isConstEnum(EnumDeclaration id) { is_const_enum(id) }
/**
* Alias for the predicate `is_abstract_class` defined in the .dbscheme.
* Use `ClassDefinition#isAbstract()` instead.
*/
deprecated predicate isAbstractClass(ClassDeclStmt id) { is_abstract_class(id) }
/**
* Alias for the predicate `has_public_keyword` defined in the .dbscheme.
* Use `MemberDeclaration#hasPublicKeyword() instead.
*/
deprecated predicate hasPublicKeyword(Property prop) { has_public_keyword(prop) }
/**
* Alias for the predicate `has_private_keyword` defined in the .dbscheme.
* Use `MemberDeclaration#isPrivate() instead.
*/
deprecated predicate hasPrivateKeyword(Property prop) { has_private_keyword(prop) }
/**
* Alias for the predicate `has_protected_keyword` defined in the .dbscheme.
* Use `MemberDeclaration#isProtected() instead.
*/
deprecated predicate hasProtectedKeyword(Property prop) { has_protected_keyword(prop) }
/**
* Alias for the predicate `has_readonly_keyword` defined in the .dbscheme.
* Use `FieldDeclaration#isReadonly()` instead.
*/
deprecated predicate hasReadonlyKeyword(Property prop) { has_readonly_keyword(prop) }
/**
* Alias for the predicate `has_type_keyword` defined in the .dbscheme.
* Use the `isTypeOnly` method on the `ImportDeclaration`/`ExportDeclaration` classes instead.
*/
deprecated predicate hasTypeKeyword(ASTNode id) { has_type_keyword(id) }
/**
* Alias for the predicate `is_optional_member` defined in the .dbscheme.
* Use `FieldDeclaration#isOptional()` instead.
*/
deprecated predicate isOptionalMember(Property id) { is_optional_member(id) }
/**
* Alias for the predicate `has_definite_assignment_assertion` defined in the .dbscheme.
* Use the `hasDefiniteAssignmentAssertion` method on the `FieldDeclaration`/`VariableDeclarator` classes instead.
*/
deprecated predicate hasDefiniteAssignmentAssertion(ASTNode id) {
has_definite_assignment_assertion(id)
}
/**
* Alias for the predicate `is_optional_parameter_declaration` defined in the .dbscheme.
* Use `Parameter#isDeclaredOptional()` instead.
*/
deprecated predicate isOptionalParameterDeclaration(Parameter parameter) {
is_optional_parameter_declaration(parameter)
}
/**
* Alias for the predicate `has_asserts_keyword` defined in the .dbscheme.
* Use `PredicateTypeExpr#hasAssertsKeyword() instead.
*/
deprecated predicate hasAssertsKeyword(PredicateTypeExpr node) { has_asserts_keyword(node) }
/**
* Alias for the predicate `js_parse_errors` defined in the .dbscheme.
* Use the `JSParseError` class instead.
*/
deprecated predicate jsParseErrors(JSParseError id, TopLevel toplevel, string message, string line) {
js_parse_errors(id, toplevel, message, line)
}
/**
* Alias for the predicate `regexp_parse_errors` defined in the .dbscheme.
* Use the `RegExpParseError` class instead.
*/
deprecated predicate regexpParseErrors(RegExpParseError id, RegExpTerm regexp, string message) {
regexp_parse_errors(id, regexp, message)
}
/**
* Alias for the predicate `is_greedy` defined in the .dbscheme.
* Use `RegExpQuantifier#isGreedy` instead.
*/
deprecated predicate isGreedy(RegExpQuantifier id) { is_greedy(id) }
/**
* Alias for the predicate `range_quantifier_lower_bound` defined in the .dbscheme.
* Use `RegExpRange#getLowerBound()` instead.
*/
deprecated predicate rangeQuantifierLowerBound(RegExpRange id, int lo) {
range_quantifier_lower_bound(id, lo)
}
/**
* Alias for the predicate `range_quantifier_upper_bound` defined in the .dbscheme.
* Use `RegExpRange#getUpperBound() instead.
*/
deprecated predicate rangeQuantifierUpperBound(RegExpRange id, int hi) {
range_quantifier_upper_bound(id, hi)
}
/**
* Alias for the predicate `is_capture` defined in the .dbscheme.
* Use `RegExpGroup#isCapture()` instead.
*/
deprecated predicate isCapture(RegExpGroup id, int number) { is_capture(id, number) }
/**
* Alias for the predicate `is_named_capture` defined in the .dbscheme.
* Use `RegExpGroup#isNamed()` instead.
*/
deprecated predicate isNamedCapture(RegExpGroup id, string name) { is_named_capture(id, name) }
/**
* Alias for the predicate `is_inverted` defined in the .dbscheme.
* Use `RegExpCharacterClass#isInverted()` instead.
*/
deprecated predicate isInverted(RegExpCharacterClass id) { is_inverted(id) }
/**
* Alias for the predicate `regexp_const_value` defined in the .dbscheme.
* Use `RegExpConstant#getValue()` instead.
*/
deprecated predicate regexpConstValue(RegExpConstant id, string value) {
regexp_const_value(id, value)
}
/**
* Alias for the predicate `char_class_escape` defined in the .dbscheme.
* Use `RegExpCharacterClassEscape#getValue()` instead.
*/
deprecated predicate charClassEscape(RegExpCharacterClassEscape id, string value) {
char_class_escape(id, value)
}
/**
* Alias for the predicate `named_backref` defined in the .dbscheme.
* Use `RegExpBackRef#getName()` instead.
*/
deprecated predicate namedBackref(RegExpBackRef id, string name) { named_backref(id, name) }
/**
* Alias for the predicate `unicode_property_escapename` defined in the .dbscheme.
* Use `RegExpUnicodePropertyEscape#getName()` instead.
*/
deprecated predicate unicodePropertyEscapeName(RegExpUnicodePropertyEscape id, string name) {
unicode_property_escapename(id, name)
}
/**
* Alias for the predicate `unicode_property_escapevalue` defined in the .dbscheme.
* Use `RegExpUnicodePropertyEscape#getValue()` instead.
*/
deprecated predicate unicodePropertyEscapeValue(RegExpUnicodePropertyEscape id, string value) {
unicode_property_escapevalue(id, value)
}
/**
* Alias for the predicate `is_generator` defined in the .dbscheme.
* Use `Function#isGenerator()` instead.
*/
deprecated predicate isGenerator(Function fun) { is_generator(fun) }
/**
* Alias for the predicate `has_rest_parameter` defined in the .dbscheme.
* Use `Function#hasRestParameter()` instead.
*/
deprecated predicate hasRestParameter(Function fun) { has_rest_parameter(fun) }
/**
* Alias for the predicate `is_async` defined in the .dbscheme.
* Use `Function#isAsync()` instead.
*/
deprecated predicate isAsync(Function fun) { is_async(fun) }

View File

@@ -109,7 +109,7 @@ module API {
*/
cached
Node getMember(string m) {
Stages::APIStage::ref() and
Stages::ApiStage::ref() and
result = this.getASuccessor(Label::member(m))
}
@@ -119,7 +119,7 @@ module API {
*/
cached
Node getUnknownMember() {
Stages::APIStage::ref() and
Stages::ApiStage::ref() and
result = this.getASuccessor(Label::unknownMember())
}
@@ -129,7 +129,7 @@ module API {
*/
cached
Node getAMember() {
Stages::APIStage::ref() and
Stages::ApiStage::ref() and
result = this.getMember(_)
or
result = this.getUnknownMember()
@@ -148,7 +148,7 @@ module API {
*/
cached
Node getInstance() {
Stages::APIStage::ref() and
Stages::ApiStage::ref() and
result = this.getASuccessor(Label::instance())
}
@@ -160,7 +160,7 @@ module API {
*/
cached
Node getParameter(int i) {
Stages::APIStage::ref() and
Stages::ApiStage::ref() and
result = this.getASuccessor(Label::parameter(i))
}
@@ -182,7 +182,7 @@ module API {
*/
cached
Node getReceiver() {
Stages::APIStage::ref() and
Stages::ApiStage::ref() and
result = this.getASuccessor(Label::receiver())
}
@@ -196,7 +196,7 @@ module API {
*/
cached
Node getAParameter() {
Stages::APIStage::ref() and
Stages::ApiStage::ref() and
result = this.getParameter(_)
or
result = this.getReceiver()
@@ -210,7 +210,7 @@ module API {
*/
cached
Node getReturn() {
Stages::APIStage::ref() and
Stages::ApiStage::ref() and
result = this.getASuccessor(Label::return())
}
@@ -220,7 +220,7 @@ module API {
*/
cached
Node getPromised() {
Stages::APIStage::ref() and
Stages::ApiStage::ref() and
result = this.getASuccessor(Label::promised())
}
@@ -229,7 +229,7 @@ module API {
*/
cached
Node getPromisedError() {
Stages::APIStage::ref() and
Stages::ApiStage::ref() and
result = this.getASuccessor(Label::promisedError())
}
@@ -892,7 +892,7 @@ module API {
*/
cached
predicate edge(TApiNode pred, Label::ApiLabel lbl, TApiNode succ) {
Stages::APIStage::ref() and
Stages::ApiStage::ref() and
exists(string m |
pred = MkRoot() and
lbl = Label::moduleLabel(m)
@@ -1251,7 +1251,7 @@ private predicate exports(string m, string prop, DataFlow::Node rhs) {
/** Gets the definition of module `m`. */
private Module importableModule(string m) {
exists(NPMPackage pkg, PackageJSON json | json = pkg.getPackageJSON() and not json.isPrivate() |
exists(NpmPackage pkg, PackageJson json | json = pkg.getPackageJson() and not json.isPrivate() |
result = pkg.getMainModule() and
not result.isExterns() and
m = pkg.getPackageName()

View File

@@ -152,15 +152,12 @@ private module ArrayDataFlow {
/**
* A node that reads or writes an element from an array inside a for-loop.
*/
private class ArrayIndexingAccess extends DataFlow::Node {
DataFlow::PropRef read;
private class ArrayIndexingAccess extends DataFlow::Node instanceof DataFlow::PropRef {
ArrayIndexingAccess() {
read = this and
TTNumber() =
unique(InferredType type | type = read.getPropertyNameExpr().flow().analyze().getAType()) and
unique(InferredType type | type = super.getPropertyNameExpr().flow().analyze().getAType()) and
exists(VarAccess i, ExprOrVarDecl init |
i = read.getPropertyNameExpr() and init = any(ForStmt f).getInit()
i = super.getPropertyNameExpr() and init = any(ForStmt f).getInit()
|
i.getVariable().getADefinition() = init or
i.getVariable().getADefinition().(VariableDeclarator).getDeclStmt() = init

View File

@@ -347,7 +347,7 @@ class ControlFlowNode extends @cfg_node, Locatable, NodeInStmtContainer {
then result = "function in " + any(MethodDeclaration mem | mem.getBody() = this)
else
if this instanceof @decorator_list
then result = "parameter decorators of " + this.(ASTNode).getParent().(Function).describe()
then result = "parameter decorators of " + this.(AstNode).getParent().(Function).describe()
else result = toString()
}
}

View File

@@ -48,7 +48,7 @@ class CanonicalName extends @symbol {
string getExternalModuleName() {
symbol_module(this, result)
or
exists(PackageJSON pkg |
exists(PackageJson pkg |
getModule() = pkg.getMainModule() and
result = pkg.getPackageName()
)
@@ -160,7 +160,7 @@ class CanonicalName extends @symbol {
/**
* Gets a definition of the entity with this canonical name.
*/
ASTNode getADefinition() { none() }
AstNode getADefinition() { none() }
/**
* Gets a use that refers to the entity with this canonical name.

View File

@@ -32,7 +32,7 @@ module CharacterEscapes {
* Holds if `n` is delimited by `delim` and contains `rawStringNode` with the raw string value `raw`.
*/
private predicate hasRawStringAndQuote(
DataFlow::ValueNode n, string delim, ASTNode rawStringNode, string raw
DataFlow::ValueNode n, string delim, AstNode rawStringNode, string raw
) {
rawStringNode = n.asExpr() and
raw = rawStringNode.(StringLiteral).getRawValue() and
@@ -52,7 +52,7 @@ module CharacterEscapes {
*
* The character is the `i`th character of `rawStringNode`'s raw string value.
*/
string getAnIdentityEscapedCharacter(DataFlow::Node n, ASTNode rawStringNode, int i) {
string getAnIdentityEscapedCharacter(DataFlow::Node n, AstNode rawStringNode, int i) {
exists(string delim, string raw, string additionalEscapeChars |
hasRawStringAndQuote(n, delim, rawStringNode, raw) and
if rawStringNode instanceof RegExpLiteral
@@ -80,7 +80,7 @@ module CharacterEscapes {
* The character is the `i`th character of the raw string value of `rawStringNode`.
*/
string getALikelyRegExpPatternMistake(
RegExpPatternSource src, string mistake, ASTNode rawStringNode, int i
RegExpPatternSource src, string mistake, AstNode rawStringNode, int i
) {
result = getAnIdentityEscapedCharacter(src, rawStringNode, i) and
(

View File

@@ -76,10 +76,10 @@ module DOM {
/**
* A JSX element, viewed as an `ElementDefinition`.
*/
private class JsxElementDefinition extends ElementDefinition, @jsx_element instanceof JSXElement {
override string getName() { result = JSXElement.super.getName() }
private class JsxElementDefinition extends ElementDefinition, @jsx_element instanceof JsxElement {
override string getName() { result = JsxElement.super.getName() }
override AttributeDefinition getAttribute(int i) { result = JSXElement.super.getAttribute(i) }
override AttributeDefinition getAttribute(int i) { result = JsxElement.super.getAttribute(i) }
override ElementDefinition getParent() { result = super.getJsxParent() }
}
@@ -139,7 +139,7 @@ module DOM {
* A JSX attribute, viewed as an `AttributeDefinition`.
*/
private class JsxAttributeDefinition extends AttributeDefinition, @jsx_attribute {
JSXAttribute attr;
JsxAttribute attr;
JsxAttributeDefinition() { this = attr }
@@ -323,7 +323,7 @@ module DOM {
private class DefaultRange extends Range {
DefaultRange() {
this.asExpr().(VarAccess).getVariable() instanceof DOMGlobalVariable
this.asExpr().(VarAccess).getVariable() instanceof DomGlobalVariable
or
exists(DataFlow::PropRead read |
this = read and
@@ -392,7 +392,7 @@ module DOM {
*/
private DataFlow::SourceNode domEventSource() {
// e.g. <form onSubmit={e => e.target}/>
exists(JSXAttribute attr | attr.getName().matches("on%") |
exists(JsxAttribute attr | attr.getName().matches("on%") |
result = attr.getValue().flow().getABoundFunctionValue(0).getParameter(0)
)
or

View File

@@ -249,8 +249,9 @@ class VarUse extends ControlFlowNode, @varref {
/**
* Holds if the definition of `v` in `def` reaches `use` along some control flow path
* without crossing another definition of `v`.
* DEPRECATED: Use the `SSA.qll` library instead.
*/
predicate definitionReaches(Variable v, VarDef def, VarUse use) {
deprecated predicate definitionReaches(Variable v, VarDef def, VarUse use) {
v = use.getVariable() and
exists(BasicBlock bb, int i, int next | next = nextDefAfter(bb, v, i, def) |
exists(int j | j in [i + 1 .. next - 1] | bb.useAt(j, v, use))
@@ -265,16 +266,20 @@ predicate definitionReaches(Variable v, VarDef def, VarUse use) {
/**
* Holds if the definition of local variable `v` in `def` reaches `use` along some control flow path
* without crossing another definition of `v`.
* DEPRECATED: Use the `SSA.qll` library instead.
*/
predicate localDefinitionReaches(LocalVariable v, VarDef def, VarUse use) {
deprecated predicate localDefinitionReaches(LocalVariable v, VarDef def, VarUse use) {
exists(SsaExplicitDefinition ssa |
ssa.defines(def, v) and
ssa = getAPseudoDefinitionInput*(use.getSsaVariable().getDefinition())
)
}
/** Holds if `nd` is a pseudo-definition and the result is one of its inputs. */
private SsaDefinition getAPseudoDefinitionInput(SsaDefinition nd) {
/**
* Holds if `nd` is a pseudo-definition and the result is one of its inputs.
* DEPRECATED: Use the `SSA.qll` library instead.
*/
deprecated private SsaDefinition getAPseudoDefinitionInput(SsaDefinition nd) {
result = nd.(SsaPseudoDefinition).getAnInput()
}
@@ -282,7 +287,7 @@ private SsaDefinition getAPseudoDefinitionInput(SsaDefinition nd) {
* Holds if `d` is a definition of `v` at index `i` in `bb`, and the result is the next index
* in `bb` after `i` at which the same variable is defined, or `bb.length()` if there is none.
*/
private int nextDefAfter(BasicBlock bb, Variable v, int i, VarDef d) {
deprecated private int nextDefAfter(BasicBlock bb, Variable v, int i, VarDef d) {
bb.defAt(i, v, d) and
result =
min(int jj |
@@ -296,8 +301,9 @@ private int nextDefAfter(BasicBlock bb, Variable v, int i, VarDef d) {
*
* This is the case if there is a path from `earlier` to `later` that does not cross
* another definition of `v`.
* DEPRECATED: Use the `SSA.qll` library instead.
*/
predicate localDefinitionOverwrites(LocalVariable v, VarDef earlier, VarDef later) {
deprecated predicate localDefinitionOverwrites(LocalVariable v, VarDef earlier, VarDef later) {
exists(BasicBlock bb, int i, int next | next = nextDefAfter(bb, v, i, earlier) |
bb.defAt(next, v, later)
or

View File

@@ -181,16 +181,7 @@ class DynamicPropRead extends DataFlow::SourceNode, DataFlow::ValueNode {
* dst[x][y] = src[y];
* ```
*/
predicate hasDominatingAssignment() {
exists(DataFlow::PropWrite write, BasicBlock bb, int i, int j, SsaVariable ssaVar |
write = getBase().getALocalSource().getAPropertyWrite() and
bb.getNode(i) = write.getWriteNode() and
bb.getNode(j) = astNode and
i < j and
write.getPropertyNameExpr() = ssaVar.getAUse() and
astNode.getIndex() = ssaVar.getAUse()
)
}
predicate hasDominatingAssignment() { AccessPath::DominatingPaths::hasDominatingWrite(this) }
}
/**

View File

@@ -14,7 +14,10 @@ module E4X {
* *
* ```
*/
class XMLAnyName extends Expr, @e4x_xml_anyname { }
class XmlAnyName extends Expr, @e4x_xml_anyname { }
/** DEPRECATED: Alias for XmlAnyName */
deprecated class XMLAnyName = XmlAnyName;
/**
* An E4X qualified identifier.
@@ -29,7 +32,7 @@ module E4X {
* Note that qualified identifiers are not currently supported by the parser, so snapshots
* will not usually contain any.
*/
class XMLQualifiedIdentifier extends Expr, @e4x_xml_qualident {
class XmlQualifiedIdentifier extends Expr, @e4x_xml_qualident {
/**
* Gets the left operand of this qualified identifier, which is either
* an identifier or a wildcard.
@@ -54,6 +57,9 @@ module E4X {
}
}
/** DEPRECATED: Alias for XmlQualifiedIdentifier */
deprecated class XMLQualifiedIdentifier = XmlQualifiedIdentifier;
/**
* An E4X attribute selector.
*
@@ -64,7 +70,7 @@ module E4X {
* @[p]
* ```
*/
class XMLAttributeSelector extends Expr, @e4x_xml_attribute_selector {
class XmlAttributeSelector extends Expr, @e4x_xml_attribute_selector {
/**
* Gets the selected attribute, which is either a static name (that is, a
* wildcard identifier or a possibly qualified name), or an arbitrary
@@ -83,6 +89,9 @@ module E4X {
}
}
/** DEPRECATED: Alias for XmlAttributeSelector */
deprecated class XMLAttributeSelector = XmlAttributeSelector;
/**
* An E4X filter expression.
*
@@ -92,7 +101,7 @@ module E4X {
* employees.(@id == 0 || @id == 1)
* ```
*/
class XMLFilterExpression extends Expr, @e4x_xml_filter_expression {
class XmlFilterExpression extends Expr, @e4x_xml_filter_expression {
/**
* Gets the left operand of this filter expression.
*/
@@ -108,6 +117,9 @@ module E4X {
}
}
/** DEPRECATED: Alias for XmlFilterExpression */
deprecated class XMLFilterExpression = XmlFilterExpression;
/**
* An E4X "dot-dot" expression.
*
@@ -117,7 +129,7 @@ module E4X {
* e..name
* ```
*/
class XMLDotDotExpression extends Expr, @e4x_xml_dotdotexpr {
class XmlDotDotExpression extends Expr, @e4x_xml_dotdotexpr {
/**
* Gets the base expression of this dot-dot expression.
*/
@@ -132,4 +144,7 @@ module E4X {
result = getBase().getFirstControlFlowNode()
}
}
/** DEPRECATED: Alias for XmlDotDotExpression */
deprecated class XMLDotDotExpression = XmlDotDotExpression;
}

View File

@@ -647,13 +647,6 @@ abstract class ReExportDeclaration extends ExportDeclaration {
/** Gets the path of the module from which this declaration re-exports. */
abstract ConstantString getImportedPath();
/**
* DEPRECATED. Use `getReExportedES2015Module()` instead.
*
* Gets the module from which this declaration re-exports.
*/
deprecated ES2015Module getImportedModule() { result = getReExportedModule() }
/** Gets the module from which this declaration re-exports, if it is an ES2015 module. */
ES2015Module getReExportedES2015Module() { result = getReExportedModule() }

View File

@@ -2744,7 +2744,7 @@ class Decorator extends @decorator, Expr {
* }
* ```
*/
class Decoratable extends ASTNode {
class Decoratable extends AstNode {
Decoratable() {
this instanceof ClassDefinition or
this instanceof Property or

View File

@@ -64,7 +64,7 @@ import javascript
* Object.prototype.hasOwnProperty = function(p) {};
* </pre>
*/
abstract class ExternalDecl extends ASTNode {
abstract class ExternalDecl extends AstNode {
/** Gets the name of this declaration. */
abstract string getName();
@@ -125,7 +125,7 @@ abstract class ExternalVarDecl extends ExternalDecl {
*
* The result can be either a function or an expression.
*/
abstract ASTNode getInit();
abstract AstNode getInit();
/**
* Gets a JSDoc tag associated with this declaration.
@@ -179,7 +179,7 @@ class ExternalGlobalFunctionDecl extends ExternalGlobalDecl, FunctionDeclStmt {
/** Gets the name of this declaration. */
override string getName() { result = FunctionDeclStmt.super.getName() }
override ASTNode getInit() { result = this }
override AstNode getInit() { result = this }
}
/**
@@ -336,7 +336,7 @@ class ExternalInstanceMemberDecl extends ExternalMemberDecl {
* function(p) {}; // external function entity
* </pre>
*/
class ExternalEntity extends ASTNode {
class ExternalEntity extends AstNode {
ExternalEntity() { exists(ExternalVarDecl d | d.getInit() = this) }
/** Gets the variable declaration to which this entity belongs. */

View File

@@ -7,31 +7,6 @@ private import semmle.javascript.dataflow.InferredTypes
private import semmle.javascript.dataflow.internal.FlowSteps as FlowSteps
private import semmle.javascript.internal.CachedStages
deprecated module GlobalAccessPath {
/**
* DEPRECATED. Instead use `AccessPath::getAReferenceTo` with the result and parameter reversed.
*/
pragma[inline]
string fromReference(DataFlow::Node node) { node = AccessPath::getAReferenceTo(result) }
/**
* DEPRECATED. Instead use `AccessPath::getAnAssignmentTo` with the result and parameter reversed.
*/
pragma[inline]
string fromRhs(DataFlow::Node node) { node = AccessPath::getAnAssignmentTo(result) }
/**
* DEPRECATED. Use `AccessPath::getAReferenceOrAssignmentTo`.
*/
pragma[inline]
string getAccessPath(DataFlow::Node node) {
result = fromReference(node)
or
not exists(fromReference(node)) and
result = fromRhs(node)
}
}
/**
* Provides predicates for associating access paths with data flow nodes.
*
@@ -557,7 +532,7 @@ module AccessPath {
*/
cached
predicate hasDominatingWrite(DataFlow::PropRead read) {
Stages::FlowSteps::ref() and
Stages::TypeTracking::ref() and
// within the same basic block.
exists(ReachableBasicBlock bb, Root root, string path, int ranking |
read.asExpr() = rankedAccessPath(bb, root, path, ranking, AccessPathRead()) and
@@ -569,6 +544,21 @@ module AccessPath {
read.asExpr() = getAccessTo(root, path, AccessPathRead()) and
getAWriteBlock(root, path).strictlyDominates(read.getBasicBlock())
)
or
// Dynamic write where the same variable is used to index the read and write (in the same basic block)
// For example, this is true for `dst[x]` on line 2 below:
// ```js
// dst[x] = {};
// dst[x][y] = src[y];
// ```
exists(DataFlow::PropWrite write, BasicBlock bb, int i, int j, SsaVariable ssaVar |
write = read.getBase().getALocalSource().getAPropertyWrite() and
bb.getNode(i) = write.getWriteNode() and
bb.getNode(j) = read.asExpr() and
i < j and
write.getPropertyNameExpr() = ssaVar.getAUse() and
read.getPropertyNameExpr() = ssaVar.getAUse()
)
}
}
}

View File

@@ -55,7 +55,7 @@ class JSDoc extends @jsdoc, Locatable {
* }
* </pre>
*/
abstract class Documentable extends ASTNode {
abstract class Documentable extends AstNode {
/** Gets the JSDoc comment for this element, if any. */
cached
JSDoc getDocumentation() {

View File

@@ -19,14 +19,14 @@ import javascript
* { "value": 0 }
* ```
*/
class JSONValue extends @json_value, Locatable {
class JsonValue extends @json_value, Locatable {
override Location getLocation() { json_locations(this, result) }
/** Gets the parent value to which this value belongs, if any. */
JSONValue getParent() { json(this, _, result, _, _) }
JsonValue getParent() { json(this, _, result, _, _) }
/** Gets the `i`th child value of this value. */
JSONValue getChild(int i) { json(result, _, this, i, _) }
JsonValue getChild(int i) { json(result, _, this, i, _) }
/** Holds if this JSON value is the top level element in its enclosing file. */
predicate isTopLevel() { not exists(getParent()) }
@@ -42,23 +42,26 @@ class JSONValue extends @json_value, Locatable {
}
/** If this is an object, gets the value of property `name`. */
JSONValue getPropValue(string name) { json_properties(this, name, result) }
JsonValue getPropValue(string name) { json_properties(this, name, result) }
/** If this is an array, gets the value of the `i`th element. */
JSONValue getElementValue(int i) { result = this.(JSONArray).getChild(i) }
JsonValue getElementValue(int i) { result = this.(JsonArray).getChild(i) }
/** If this is a string constant, gets the value of the string. */
string getStringValue() { result = this.(JSONString).getValue() }
string getStringValue() { result = this.(JsonString).getValue() }
/** If this is an integer constant, gets its numeric value. */
int getIntValue() { result = this.(JSONNumber).getValue().toInt() }
int getIntValue() { result = this.(JsonNumber).getValue().toInt() }
/** If this is a boolean constant, gets its boolean value. */
boolean getBooleanValue() { result.toString() = this.(JSONBoolean).getValue() }
boolean getBooleanValue() { result.toString() = this.(JsonBoolean).getValue() }
override string getAPrimaryQlClass() { result = "JSONValue" }
override string getAPrimaryQlClass() { result = "JsonValue" }
}
/** DEPRECATED: Alias for JsonValue */
deprecated class JSONValue = JsonValue;
/**
* A JSON-encoded primitive value.
*
@@ -72,7 +75,7 @@ class JSONValue extends @json_value, Locatable {
* "a string"
* ```
*/
abstract class JSONPrimitiveValue extends JSONValue {
abstract class JsonPrimitiveValue extends JsonValue {
/** Gets a string representation of the encoded value. */
string getValue() { json_literals(result, _, this) }
@@ -80,6 +83,9 @@ abstract class JSONPrimitiveValue extends JSONValue {
string getRawValue() { json_literals(_, result, this) }
}
/** DEPRECATED: Alias for JsonPrimitiveValue */
deprecated class JSONPrimitiveValue = JsonPrimitiveValue;
/**
* A JSON-encoded null value.
*
@@ -89,10 +95,13 @@ abstract class JSONPrimitiveValue extends JSONValue {
* null
* ```
*/
class JSONNull extends @json_null, JSONPrimitiveValue {
override string getAPrimaryQlClass() { result = "JSONNull" }
class JsonNull extends @json_null, JsonPrimitiveValue {
override string getAPrimaryQlClass() { result = "JsonNull" }
}
/** DEPRECATED: Alias for JsonNull */
deprecated class JSONNull = JsonNull;
/**
* A JSON-encoded Boolean value.
*
@@ -103,10 +112,13 @@ class JSONNull extends @json_null, JSONPrimitiveValue {
* false
* ```
*/
class JSONBoolean extends @json_boolean, JSONPrimitiveValue {
override string getAPrimaryQlClass() { result = "JSONBoolean" }
class JsonBoolean extends @json_boolean, JsonPrimitiveValue {
override string getAPrimaryQlClass() { result = "JsonBoolean" }
}
/** DEPRECATED: Alias for JsonBoolean */
deprecated class JSONBoolean = JsonBoolean;
/**
* A JSON-encoded number.
*
@@ -117,10 +129,13 @@ class JSONBoolean extends @json_boolean, JSONPrimitiveValue {
* 1.0
* ```
*/
class JSONNumber extends @json_number, JSONPrimitiveValue {
override string getAPrimaryQlClass() { result = "JSONNumber" }
class JsonNumber extends @json_number, JsonPrimitiveValue {
override string getAPrimaryQlClass() { result = "JsonNumber" }
}
/** DEPRECATED: Alias for JsonNumber */
deprecated class JSONNumber = JsonNumber;
/**
* A JSON-encoded string value.
*
@@ -130,10 +145,13 @@ class JSONNumber extends @json_number, JSONPrimitiveValue {
* "a string"
* ```
*/
class JSONString extends @json_string, JSONPrimitiveValue {
override string getAPrimaryQlClass() { result = "JSONString" }
class JsonString extends @json_string, JsonPrimitiveValue {
override string getAPrimaryQlClass() { result = "JsonString" }
}
/** DEPRECATED: Alias for JsonString */
deprecated class JSONString = JsonString;
/**
* A JSON-encoded array.
*
@@ -143,13 +161,16 @@ class JSONString extends @json_string, JSONPrimitiveValue {
* [ 1, 2, 3 ]
* ```
*/
class JSONArray extends @json_array, JSONValue {
override string getAPrimaryQlClass() { result = "JSONArray" }
class JsonArray extends @json_array, JsonValue {
override string getAPrimaryQlClass() { result = "JsonArray" }
/** Gets the string value of the `i`th element of this array. */
string getElementStringValue(int i) { result = getElementValue(i).getStringValue() }
}
/** DEPRECATED: Alias for JsonArray */
deprecated class JSONArray = JsonArray;
/**
* A JSON-encoded object.
*
@@ -159,18 +180,24 @@ class JSONArray extends @json_array, JSONValue {
* { "value": 0 }
* ```
*/
class JSONObject extends @json_object, JSONValue {
override string getAPrimaryQlClass() { result = "JSONObject" }
class JsonObject extends @json_object, JsonValue {
override string getAPrimaryQlClass() { result = "JsonObject" }
/** Gets the string value of property `name` of this object. */
string getPropStringValue(string name) { result = getPropValue(name).getStringValue() }
}
/** DEPRECATED: Alias for JsonObject */
deprecated class JSONObject = JsonObject;
/**
* An error reported by the JSON parser.
*/
class JSONParseError extends @json_parse_error, Error {
class JsonParseError extends @json_parse_error, Error {
override Location getLocation() { json_locations(this, result) }
override string getMessage() { json_errors(this, result) }
}
/** DEPRECATED: Alias for JsonParseError */
deprecated class JSONParseError = JsonParseError;

View File

@@ -15,7 +15,7 @@ import javascript
* <><h1>Title</h1>Some <b>text</b></>
* ```
*/
class JSXNode extends Expr, @jsx_element {
class JsxNode extends Expr, @jsx_element {
/** Gets the `i`th element in the body of this element or fragment. */
Expr getBodyElement(int i) { i >= 0 and result = getChildExpr(-i - 2) }
@@ -25,11 +25,14 @@ class JSXNode extends Expr, @jsx_element {
/**
* Gets the parent JSX element or fragment of this element.
*/
JSXNode getJsxParent() { this = result.getABodyElement() }
JsxNode getJsxParent() { this = result.getABodyElement() }
override string getAPrimaryQlClass() { result = "JSXNode" }
override string getAPrimaryQlClass() { result = "JsxNode" }
}
/** DEPRECATED: Alias for JsxNode */
deprecated class JSXNode = JsxNode;
/**
* A JSX element.
*
@@ -40,39 +43,45 @@ class JSXNode extends Expr, @jsx_element {
* <Welcome name={user.name}/>
* ```
*/
class JSXElement extends JSXNode {
JSXName name;
class JsxElement extends JsxNode {
JsxName name;
JSXElement() { name = getChildExpr(-1) }
JsxElement() { name = getChildExpr(-1) }
/** Gets the expression denoting the name of this element. */
JSXName getNameExpr() { result = name }
JsxName getNameExpr() { result = name }
/** Gets the name of this element. */
string getName() { result = name.getValue() }
/** Gets the `i`th attribute of this element. */
JSXAttribute getAttribute(int i) { properties(result, this, i, _, _) }
JsxAttribute getAttribute(int i) { properties(result, this, i, _, _) }
/** Gets an attribute of this element. */
JSXAttribute getAnAttribute() { result = getAttribute(_) }
JsxAttribute getAnAttribute() { result = getAttribute(_) }
/** Gets the attribute of this element with the given name, if any. */
JSXAttribute getAttributeByName(string n) { result = getAnAttribute() and result.getName() = n }
JsxAttribute getAttributeByName(string n) { result = getAnAttribute() and result.getName() = n }
override ControlFlowNode getFirstControlFlowNode() {
result = getNameExpr().getFirstControlFlowNode()
}
override string getAPrimaryQlClass() { result = "JSXElement" }
override string getAPrimaryQlClass() { result = "JsxElement" }
/**
* Holds if this JSX element is a HTML element.
* That is, the name starts with a lowercase letter.
*/
predicate isHTMLElement() { getName().regexpMatch("[a-z].*") }
predicate isHtmlElement() { getName().regexpMatch("[a-z].*") }
/** DEPRECATED: Alias for isHtmlElement */
deprecated predicate isHTMLElement() { isHtmlElement() }
}
/** DEPRECATED: Alias for JsxElement */
deprecated class JSXElement = JsxElement;
/**
* A JSX fragment.
*
@@ -82,8 +91,8 @@ class JSXElement extends JSXNode {
* <><h1>Title</h1>Some <b>text</b></>
* ```
*/
class JSXFragment extends JSXNode {
JSXFragment() { not exists(getChildExpr(-1)) }
class JsxFragment extends JsxNode {
JsxFragment() { not exists(getChildExpr(-1)) }
override ControlFlowNode getFirstControlFlowNode() {
result = getBodyElement(0).getFirstControlFlowNode()
@@ -91,9 +100,12 @@ class JSXFragment extends JSXNode {
not exists(getABodyElement()) and result = this
}
override string getAPrimaryQlClass() { result = "JSXFragment" }
override string getAPrimaryQlClass() { result = "JsxFragment" }
}
/** DEPRECATED: Alias for JsxFragment */
deprecated class JSXFragment = JsxFragment;
/**
* An attribute of a JSX element, including spread attributes.
*
@@ -105,13 +117,13 @@ class JSXFragment extends JSXNode {
* <div {...attrs}></div> // `{...attrs}` is a (spread) attribute
* ```
*/
class JSXAttribute extends ASTNode, @jsx_attribute {
class JsxAttribute extends AstNode, @jsx_attribute {
/**
* Gets the expression denoting the name of this attribute.
*
* This is not defined for spread attributes.
*/
JSXName getNameExpr() { result = getChildExpr(0) }
JsxName getNameExpr() { result = getChildExpr(0) }
/**
* Gets the name of this attribute.
@@ -127,7 +139,7 @@ class JSXAttribute extends ASTNode, @jsx_attribute {
string getStringValue() { result = getValue().getStringValue() }
/** Gets the JSX element to which this attribute belongs. */
JSXElement getElement() { this = result.getAnAttribute() }
JsxElement getElement() { this = result.getAnAttribute() }
override ControlFlowNode getFirstControlFlowNode() {
result = getNameExpr().getFirstControlFlowNode()
@@ -137,9 +149,12 @@ class JSXAttribute extends ASTNode, @jsx_attribute {
override string toString() { properties(this, _, _, _, result) }
override string getAPrimaryQlClass() { result = "JSXAttribute" }
override string getAPrimaryQlClass() { result = "JsxAttribute" }
}
/** DEPRECATED: Alias for JsxAttribute */
deprecated class JSXAttribute = JsxAttribute;
/**
* A spread attribute of a JSX element.
*
@@ -149,8 +164,8 @@ class JSXAttribute extends ASTNode, @jsx_attribute {
* <div {...attrs}></div> // `{...attrs}` is a spread attribute
* ```
*/
class JSXSpreadAttribute extends JSXAttribute {
JSXSpreadAttribute() { not exists(getNameExpr()) }
class JsxSpreadAttribute extends JsxAttribute {
JsxSpreadAttribute() { not exists(getNameExpr()) }
override SpreadElement getValue() {
// override for more precise result type
@@ -158,6 +173,9 @@ class JSXSpreadAttribute extends JSXAttribute {
}
}
/** DEPRECATED: Alias for JsxSpreadAttribute */
deprecated class JSXSpreadAttribute = JsxSpreadAttribute;
/**
* A namespace-qualified name such as `n:a`.
*
@@ -167,7 +185,7 @@ class JSXSpreadAttribute extends JSXAttribute {
* html:href
* ```
*/
class JSXQualifiedName extends Expr, @jsx_qualified_name {
class JsxQualifiedName extends Expr, @jsx_qualified_name {
/** Gets the namespace component of this qualified name. */
Identifier getNamespace() { result = getChildExpr(0) }
@@ -178,9 +196,12 @@ class JSXQualifiedName extends Expr, @jsx_qualified_name {
result = getNamespace().getFirstControlFlowNode()
}
override string getAPrimaryQlClass() { result = "JSXQualifiedName" }
override string getAPrimaryQlClass() { result = "JsxQualifiedName" }
}
/** DEPRECATED: Alias for JsxQualifiedName */
deprecated class JSXQualifiedName = JsxQualifiedName;
/**
* A name of an JSX element or attribute (which is
* always an identifier, a dot expression, or a qualified
@@ -194,12 +215,12 @@ class JSXQualifiedName extends Expr, @jsx_qualified_name {
* data.path
* ```
*/
class JSXName extends Expr {
JSXName() {
class JsxName extends Expr {
JsxName() {
this instanceof Identifier or
this instanceof ThisExpr or
this.(DotExpr).getBase() instanceof JSXName or
this instanceof JSXQualifiedName
this.(DotExpr).getBase() instanceof JsxName or
this instanceof JsxQualifiedName
}
/**
@@ -209,10 +230,10 @@ class JSXName extends Expr {
result = this.(Identifier).getName()
or
exists(DotExpr dot | dot = this |
result = dot.getBase().(JSXName).getValue() + "." + dot.getPropertyName()
result = dot.getBase().(JsxName).getValue() + "." + dot.getPropertyName()
)
or
exists(JSXQualifiedName qual | qual = this |
exists(JsxQualifiedName qual | qual = this |
result = qual.getNamespace().getName() + ":" + qual.getName().getName()
)
or
@@ -221,6 +242,9 @@ class JSXName extends Expr {
}
}
/** DEPRECATED: Alias for JsxName */
deprecated class JSXName = JsxName;
/**
* An interpolating expression that interpolates nothing.
*
@@ -230,10 +254,13 @@ class JSXName extends Expr {
* { /* TBD *&#47; }
* </pre>
*/
class JSXEmptyExpr extends Expr, @jsx_empty_expr {
override string getAPrimaryQlClass() { result = "JSXEmptyExpr" }
class JsxEmptyExpr extends Expr, @jsx_empty_expr {
override string getAPrimaryQlClass() { result = "JsxEmptyExpr" }
}
/** DEPRECATED: Alias for JsxEmptyExpr */
deprecated class JSXEmptyExpr = JsxEmptyExpr;
/**
* A legacy `@jsx` pragma.
*
@@ -243,12 +270,18 @@ class JSXEmptyExpr extends Expr, @jsx_empty_expr {
* @jsx React.DOM
* ```
*/
class JSXPragma extends JSDocTag {
JSXPragma() { getTitle() = "jsx" }
class JsxPragma extends JSDocTag {
JsxPragma() { getTitle() = "jsx" }
/**
* Gets the DOM name specified by the pragma; for `@jsx React.DOM`,
* the result is `React.DOM`.
*/
string getDOMName() { result = getDescription().trim() }
string getDomName() { result = getDescription().trim() }
/** DEPRECATED: Alias for getDomName */
deprecated string getDOMName() { result = getDomName() }
}
/** DEPRECATED: Alias for JsxPragma */
deprecated class JSXPragma = JsxPragma;

View File

@@ -64,7 +64,7 @@ class JSON2CSVTaintStep extends TaintTracking::SharedTaintStep {
* This is not quite a `JSON.stringify` call, as it e.g. does not wrap keys in double quotes.
* It's therefore modeled as a taint-step rather than as a `JSON.stringify` call.
*/
class PrettyJSONTaintStep extends TaintTracking::SharedTaintStep {
class PrettyJsonTaintStep extends TaintTracking::SharedTaintStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(API::CallNode call |
call = API::moduleImport("prettyjson").getMember("render").getACall()
@@ -74,3 +74,6 @@ class PrettyJSONTaintStep extends TaintTracking::SharedTaintStep {
)
}
}
/** DEPRECATED: Alias for PrettyJsonTaintStep */
deprecated class PrettyJSONTaintStep = PrettyJsonTaintStep;

View File

@@ -27,76 +27,6 @@ abstract class Module extends TopLevel {
/** Gets a symbol exported by this module. */
string getAnExportedSymbol() { exists(this.getAnExportedValue(result)) }
/**
* DEPRECATED. Use `getAnExportedValue` instead.
*
* Holds if this module explicitly exports symbol `name` at the
* program element `export`.
*
* Note that in some module systems (notably CommonJS and AMD)
* modules are arbitrary objects that export all their
* properties. This predicate only considers properties
* that are explicitly defined on the module object.
*
* Symbols defined in another module that are re-exported by
* this module are only sometimes considered.
*/
deprecated predicate exports(string name, ASTNode export) {
this instanceof AmdModule and
exists(DataFlow::PropWrite pwn | export = pwn.getAstNode() |
pwn.getBase().analyze().getAValue() = this.(AmdModule).getDefine().getAModuleExportsValue() and
name = pwn.getPropertyName()
)
or
this instanceof Closure::ClosureModule and
exists(DataFlow::PropWrite write, Expr base |
write.getAstNode() = export and
write.writes(base.flow(), name, _) and
(
base = this.(Closure::ClosureModule).getExportsVariable().getAReference()
or
base = this.(Closure::ClosureModule).getExportsVariable().getAnAssignedExpr()
)
)
or
this instanceof NodeModule and
(
// a property write whose base is `exports` or `module.exports`
exists(DataFlow::PropWrite pwn | export = pwn.getAstNode() |
pwn.getBase() = this.(NodeModule).getAModuleExportsNode() and
name = pwn.getPropertyName()
)
or
// a re-export using spread-operator. E.g. `const foo = require("./foo"); module.exports = {bar: bar, ...foo};`
exists(ObjectExpr obj | obj = this.(NodeModule).getAModuleExportsNode().asExpr() |
obj.getAProperty()
.(SpreadProperty)
.getInit()
.(SpreadElement)
.getOperand()
.flow()
.getALocalSource()
.asExpr()
.(Import)
.getImportedModule()
.exports(name, export)
)
or
// an externs definition (where appropriate)
exists(PropAccess pacc | export = pacc |
pacc.getBase() = this.(NodeModule).getAModuleExportsNode().asExpr() and
name = pacc.getPropertyName() and
this.isExterns() and
exists(pacc.getDocumentation())
)
)
or
this instanceof ES2015Module and
exists(ExportDeclaration ed | ed = this.(ES2015Module).getAnExport() and ed = export |
ed.exportsAs(_, name)
)
}
/**
* Get a value that is explicitly exported from this module with under `name`.
*
@@ -188,7 +118,7 @@ abstract class Module extends TopLevel {
* An import in a module, which may be an ECMAScript 2015-style
* `import` statement, a CommonJS-style `require` import, or an AMD dependency.
*/
abstract class Import extends ASTNode {
abstract class Import extends AstNode {
/** Gets the module in which this import appears. */
abstract Module getEnclosingModule();
@@ -275,26 +205,13 @@ abstract class Import extends ASTNode {
abstract DataFlow::Node getImportedModuleNode();
}
/**
* DEPRECATED. Use `PathExpr` instead.
*
* A path expression that appears in a module and is resolved relative to it.
*/
abstract deprecated class PathExprInModule extends PathExpr {
PathExprInModule() {
this.(Expr).getTopLevel() instanceof Module
or
this.(Comment).getTopLevel() instanceof Module
}
}
/**
* Gets a module imported from another package in the same repository.
*
* No support for importing from folders inside the other package.
*/
private Module resolveNeighbourPackage(PathString importPath) {
exists(PackageJSON json | importPath = json.getPackageName() and result = json.getMainModule())
exists(PackageJson json | importPath = json.getPackageName() and result = json.getMainModule())
or
exists(string package |
result.getFile().getParentContainer() = getPackageFolder(package) and
@@ -307,7 +224,7 @@ private Module resolveNeighbourPackage(PathString importPath) {
*/
pragma[noinline]
private Folder getPackageFolder(string package) {
exists(PackageJSON json |
exists(PackageJson json |
json.getPackageName() = package and
result = json.getFile().getParentContainer()
)

View File

@@ -6,8 +6,8 @@ import javascript
private import NodeModuleResolutionImpl
/** A `package.json` configuration object. */
class PackageJSON extends JSONObject {
PackageJSON() {
class PackageJson extends JsonObject {
PackageJson() {
this.getJsonFile().getBaseName() = "package.json" and
this.isTopLevel()
}
@@ -22,7 +22,7 @@ class PackageJSON extends JSONObject {
string getDescription() { result = this.getPropStringValue("description") }
/** Gets the array of keywords for this package. */
JSONArray getKeywords() { result = this.getPropValue("keywords") }
JsonArray getKeywords() { result = this.getPropValue("keywords") }
/** Gets a keyword for this package. */
string getAKeyword() { result = this.getKeywords().getElementStringValue(_) }
@@ -45,7 +45,7 @@ class PackageJSON extends JSONObject {
}
/** Gets the array of files for this package. */
JSONArray getFiles() { result = this.getPropValue("files") }
JsonArray getFiles() { result = this.getPropValue("files") }
/** Gets a file for this package. */
string getAFile() { result = this.getFiles().getElementStringValue(_) }
@@ -67,16 +67,16 @@ class PackageJSON extends JSONObject {
}
/** Gets information about the directories of this package. */
JSONObject getDirectories() { result = this.getPropValue("directories") }
JsonObject getDirectories() { result = this.getPropValue("directories") }
/** Gets repository information for this package. */
RepositoryInfo getRepository() { result = this.getPropValue("repository") }
/** Gets information about the scripts of this package. */
JSONObject getScripts() { result = this.getPropValue("scripts") }
JsonObject getScripts() { result = this.getPropValue("scripts") }
/** Gets configuration information for this package. */
JSONObject getConfig() { result = this.getPropValue("config") }
JsonObject getConfig() { result = this.getPropValue("config") }
/** Gets the dependencies of this package. */
PackageDependencies getDependencies() { result = this.getPropValue("dependencies") }
@@ -131,10 +131,10 @@ class PackageJSON extends JSONObject {
PackageDependencies getEngines() { result = this.getPropValue("engines") }
/** Holds if this package has strict engine requirements. */
predicate isEngineStrict() { this.getPropValue("engineStrict").(JSONBoolean).getValue() = "true" }
predicate isEngineStrict() { this.getPropValue("engineStrict").(JsonBoolean).getValue() = "true" }
/** Gets information about operating systems supported by this package. */
JSONArray getOSs() { result = this.getPropValue("os") }
JsonArray getOSs() { result = this.getPropValue("os") }
/** Gets an operating system supported by this package. */
string getWhitelistedOS() {
@@ -150,7 +150,7 @@ class PackageJSON extends JSONObject {
}
/** Gets information about platforms supported by this package. */
JSONArray getCPUs() { result = this.getPropValue("cpu") }
JsonArray getCPUs() { result = this.getPropValue("cpu") }
/** Gets a platform supported by this package. */
string getWhitelistedCPU() {
@@ -166,13 +166,13 @@ class PackageJSON extends JSONObject {
}
/** Holds if this package prefers to be installed globally. */
predicate isPreferGlobal() { this.getPropValue("preferGlobal").(JSONBoolean).getValue() = "true" }
predicate isPreferGlobal() { this.getPropValue("preferGlobal").(JsonBoolean).getValue() = "true" }
/** Holds if this is a private package. */
predicate isPrivate() { this.getPropValue("private").(JSONBoolean).getValue() = "true" }
predicate isPrivate() { this.getPropValue("private").(JsonBoolean).getValue() = "true" }
/** Gets publishing configuration information about this package. */
JSONValue getPublishConfig() { result = this.getPropValue("publishConfig") }
JsonValue getPublishConfig() { result = this.getPropValue("publishConfig") }
/**
* Gets the main module of this package.
@@ -182,13 +182,16 @@ class PackageJSON extends JSONObject {
}
}
/** DEPRECATED: Alias for PackageJson */
deprecated class PackageJSON = PackageJson;
/**
* A representation of bug tracker information for an NPM package.
*/
class BugTrackerInfo extends JSONValue {
class BugTrackerInfo extends JsonValue {
BugTrackerInfo() {
exists(PackageJSON pkg | pkg.getPropValue("bugs") = this) and
(this instanceof JSONObject or this instanceof JSONString)
exists(PackageJson pkg | pkg.getPropValue("bugs") = this) and
(this instanceof JsonObject or this instanceof JsonString)
}
/** Gets the bug tracker URL. */
@@ -204,13 +207,13 @@ class BugTrackerInfo extends JSONValue {
/**
* A representation of contributor information for an NPM package.
*/
class ContributorInfo extends JSONValue {
class ContributorInfo extends JsonValue {
ContributorInfo() {
exists(PackageJSON pkg |
exists(PackageJson pkg |
this = pkg.getPropValue("author") or
this = pkg.getPropValue("contributors").getElementValue(_)
) and
(this instanceof JSONObject or this instanceof JSONString)
(this instanceof JsonObject or this instanceof JsonString)
}
/**
@@ -244,8 +247,8 @@ class ContributorInfo extends JSONValue {
/**
* A representation of repository information for an NPM package.
*/
class RepositoryInfo extends JSONObject {
RepositoryInfo() { exists(PackageJSON pkg | this = pkg.getPropValue("repository")) }
class RepositoryInfo extends JsonObject {
RepositoryInfo() { exists(PackageJson pkg | this = pkg.getPropValue("repository")) }
/** Gets the repository type. */
string getType() { result = this.getPropStringValue("type") }
@@ -257,9 +260,9 @@ class RepositoryInfo extends JSONObject {
/**
* A representation of package dependencies for an NPM package.
*/
class PackageDependencies extends JSONObject {
class PackageDependencies extends JsonObject {
PackageDependencies() {
exists(PackageJSON pkg, string name |
exists(PackageJson pkg, string name |
name.regexpMatch("(.+D|d)ependencies|engines") and
this = pkg.getPropValue(name)
)
@@ -272,11 +275,11 @@ class PackageDependencies extends JSONObject {
/**
* An NPM package.
*/
class NPMPackage extends @folder {
class NpmPackage extends @folder {
/** The `package.json` file of this package. */
PackageJSON pkg;
PackageJson pkg;
NPMPackage() { pkg.getJsonFile().getParentContainer() = this }
NpmPackage() { pkg.getJsonFile().getParentContainer() = this }
/** Gets a textual representation of this package. */
string toString() { result = this.(Folder).toString() }
@@ -285,10 +288,13 @@ class NPMPackage extends @folder {
string getPath() { result = this.(Folder).getAbsolutePath() }
/** Gets the `package.json` object of this package. */
PackageJSON getPackageJSON() { result = pkg }
PackageJson getPackageJson() { result = pkg }
/** DEPRECATED: Alias for getPackageJson */
deprecated PackageJSON getPackageJSON() { result = this.getPackageJson() }
/** Gets the name of this package. */
string getPackageName() { result = this.getPackageJSON().getPackageName() }
string getPackageName() { result = this.getPackageJson().getPackageName() }
/** Gets the `node_modules` folder of this package. */
Folder getNodeModulesFolder() {
@@ -325,6 +331,9 @@ class NPMPackage extends @folder {
predicate declaresDependency(string p, string v) { pkg.declaresDependency(p, v) }
}
/** DEPRECATED: Alias for NpmPackage */
deprecated class NPMPackage = NpmPackage;
/**
* Gets the parent folder of `c`, provided that they belong to the same NPM
* package; that is, `c` must not be a `node_modules` folder.

View File

@@ -60,7 +60,7 @@ File loadAsFile(Require req, int rootPriority, int priority) {
*/
File loadAsDirectory(Require req, int rootPriority, int priority) {
exists(Folder dir | dir = req.getImportedPath().resolve(rootPriority) |
result = resolveMainModule(dir.(NPMPackage).getPackageJSON(), priority) or
result = resolveMainModule(dir.(NpmPackage).getPackageJson(), priority) or
result = tryExtensions(dir, "index", priority - (numberOfExtensions() + 1))
)
}
@@ -90,7 +90,7 @@ private string getStem(string name) { result = name.regexpCapture("(.+?)(?:\\.([
/**
* Gets the main module described by `pkg` with the given `priority`.
*/
File resolveMainModule(PackageJSON pkg, int priority) {
File resolveMainModule(PackageJson pkg, int priority) {
exists(PathExpr main | main = MainModulePath::of(pkg) |
result = main.resolve() and priority = 0
or
@@ -144,14 +144,17 @@ private string getASrcFolderName() { result = ["ts", "js", "src", "lib"] }
* module of the package.
*/
class MainModulePath extends PathExpr, @json_string {
PackageJSON pkg;
PackageJson pkg;
MainModulePath() { this = pkg.getPropValue(["main", "module"]) }
/** Gets the `package.json` file in which this path occurs. */
PackageJSON getPackageJSON() { result = pkg }
PackageJson getPackageJson() { result = pkg }
override string getValue() { result = this.(JSONString).getValue() }
/** DEPRECATED: Alias for getPackageJson */
deprecated PackageJSON getPackageJSON() { result = getPackageJson() }
override string getValue() { result = this.(JsonString).getValue() }
override Folder getAdditionalSearchRoot(int priority) {
priority = 0 and
@@ -160,7 +163,7 @@ class MainModulePath extends PathExpr, @json_string {
}
module MainModulePath {
MainModulePath of(PackageJSON pkg) { result.getPackageJSON() = pkg }
MainModulePath of(PackageJson pkg) { result.getPackageJson() = pkg }
}
/**
@@ -169,17 +172,20 @@ module MainModulePath {
* For performance reasons this only exists if there is no "main" field in the `package.json` file.
*/
private class FilesPath extends PathExpr, @json_string {
PackageJSON pkg;
PackageJson pkg;
FilesPath() {
this = pkg.getPropValue("files").(JSONArray).getElementValue(_) and
this = pkg.getPropValue("files").(JsonArray).getElementValue(_) and
not exists(MainModulePath::of(pkg))
}
/** Gets the `package.json` file in which this path occurs. */
PackageJSON getPackageJSON() { result = pkg }
PackageJson getPackageJson() { result = pkg }
override string getValue() { result = this.(JSONString).getValue() }
/** DEPRECATED: Alias for getPackageJson */
deprecated PackageJSON getPackageJSON() { result = getPackageJson() }
override string getValue() { result = this.(JsonString).getValue() }
override Folder getAdditionalSearchRoot(int priority) {
priority = 0 and
@@ -188,5 +194,5 @@ private class FilesPath extends PathExpr, @json_string {
}
private module FilesPath {
FilesPath of(PackageJSON pkg) { result.getPackageJSON() = pkg }
FilesPath of(PackageJson pkg) { result.getPackageJson() = pkg }
}

View File

@@ -52,7 +52,7 @@ private import NodeModuleResolutionImpl as NodeModule
private DataFlow::Node getAValueExportedByPackage() {
// The base case, an export from a named `package.json` file.
result =
getAnExportFromModule(any(PackageJSON pack | exists(pack.getPackageName())).getMainModule())
getAnExportFromModule(any(PackageJson pack | exists(pack.getPackageName())).getMainModule())
or
// module.exports.bar.baz = result;
exists(DataFlow::PropWrite write |
@@ -133,7 +133,7 @@ private DataFlow::Node getAValueExportedByPackage() {
DataFlow::globalVarRef("define").getACall().getArgument(1) = prev.getALocalUse() and
func.getFile() =
min(int j, File f |
f = NodeModule::resolveMainModule(any(PackageJSON pack | exists(pack.getPackageName())), j)
f = NodeModule::resolveMainModule(any(PackageJson pack | exists(pack.getPackageName())), j)
|
f order by j
)

View File

@@ -212,7 +212,7 @@ private module TypeScriptOutDir {
* Gets a folder of TypeScript files that is compiled to JavaScript files in `outdir` relative to a `parent`.
*/
string getOriginalTypeScriptFolder(string outdir, Folder parent) {
exists(JSONObject tsconfig |
exists(JsonObject tsconfig |
outdir = removeLeadingSlash(getOutDir(tsconfig, parent)) and
result = removeLeadingSlash(getEffectiveRootDirFromTSConfig(tsconfig))
)
@@ -229,7 +229,7 @@ private module TypeScriptOutDir {
/**
* Gets the `outDir` option from a tsconfig file from the folder `parent`.
*/
private string getOutDir(JSONObject tsconfig, Folder parent) {
private string getOutDir(JsonObject tsconfig, Folder parent) {
tsconfig.getFile().getBaseName().regexpMatch("tsconfig.*\\.json") and
tsconfig.isTopLevel() and
tsconfig.getFile().getParentContainer() = parent and
@@ -241,7 +241,7 @@ private module TypeScriptOutDir {
* Based on the tsconfig.json file `tsconfig`.
*/
pragma[inline]
private string getEffectiveRootDirFromTSConfig(JSONObject tsconfig) {
private string getEffectiveRootDirFromTSConfig(JsonObject tsconfig) {
// if an explicit "rootDir" option exists, then use that.
result = getRootDir(tsconfig)
or
@@ -273,7 +273,7 @@ private module TypeScriptOutDir {
* Can have multiple results if the includes are from multiple folders.
*/
pragma[inline]
private string getARootDirFromInclude(JSONObject tsconfig) {
private string getARootDirFromInclude(JsonObject tsconfig) {
result =
getRootFolderFromPath(tsconfig.getPropValue("include").getElementValue(_).getStringValue())
}
@@ -282,7 +282,7 @@ private module TypeScriptOutDir {
* Gets the value of the "rootDir" option from a tsconfig.json.
*/
pragma[inline]
private string getRootDir(JSONObject tsconfig) {
private string getRootDir(JsonObject tsconfig) {
result = tsconfig.getPropValue("compilerOptions").getPropValue("rootDir").getStringValue()
}
}

View File

@@ -54,26 +54,26 @@ private string getQlClass(Locatable el) {
*/
private newtype TPrintAstNode =
// JavaScript / TypeScript
TElementNode(ASTNode el) { shouldPrint(el, _) and not isNotNeeded(el) } or
TElementNode(AstNode el) { shouldPrint(el, _) and not isNotNeeded(el) } or
TParametersNode(Function f) { shouldPrint(f, _) and not isNotNeeded(f) } or
TTypeParametersNode(TypeParameterized f) { shouldPrint(f, _) and not isNotNeeded(f) } or
TJSXAttributesNode(JSXElement n) { shouldPrint(n, _) and not isNotNeeded(n) } or
TJSXBodyElementsNode(JSXNode n) { shouldPrint(n, _) and not isNotNeeded(n) } or
TJsxAttributesNode(JsxElement n) { shouldPrint(n, _) and not isNotNeeded(n) } or
TJsxBodyElementsNode(JsxNode n) { shouldPrint(n, _) and not isNotNeeded(n) } or
TInvokeArgumentsNode(InvokeExpr n) { shouldPrint(n, _) and not isNotNeeded(n) } or
TInvokeTypeArgumentsNode(InvokeExpr invk) { shouldPrint(invk, _) and not isNotNeeded(invk) } or
// JSON
TJSONNode(JSONValue value) { shouldPrint(value, _) and not isNotNeeded(value) } or
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
THTMLElementNode(HTML::Element e) { shouldPrint(e, _) and not isNotNeeded(e) } or
THTMLAttributesNodes(HTML::Element e) { shouldPrint(e, _) and not isNotNeeded(e) } or
THTMLAttributeNode(HTML::Attribute attr) { shouldPrint(attr, _) and not isNotNeeded(attr) } or
THTMLScript(Script script) { shouldPrint(script, _) and not isNotNeeded(script) } or
THTMLCodeInAttr(CodeInAttribute attr) { shouldPrint(attr, _) and not isNotNeeded(attr) } or
THtmlElementNode(HTML::Element e) { shouldPrint(e, _) and not isNotNeeded(e) } or
THtmlAttributesNodes(HTML::Element e) { shouldPrint(e, _) and not isNotNeeded(e) } or
THtmlAttributeNode(HTML::Attribute attr) { shouldPrint(attr, _) and not isNotNeeded(attr) } or
THtmlScript(Script script) { shouldPrint(script, _) and not isNotNeeded(script) } or
THtmlCodeInAttr(CodeInAttribute attr) { shouldPrint(attr, _) and not isNotNeeded(attr) } or
TRegExpTermNode(RegExpTerm term) {
shouldPrint(term, _) and
term.isUsedAsRegExp() and
@@ -168,7 +168,7 @@ private module PrintJavaScript {
* For example by aggregating all the parameters of a function under a single child node.
*/
class ElementNode extends PrintAstNode, TElementNode {
ASTNode element;
AstNode element;
ElementNode() {
this = TElementNode(element) and
@@ -183,10 +183,10 @@ private module PrintJavaScript {
/**
* Gets the `ASTNode` represented by this node.
*/
final ASTNode getElement() { result = element }
final AstNode getElement() { result = element }
override PrintAstNode getChild(int childIndex) {
exists(ASTNode el | result.(ElementNode).getElement() = el |
exists(AstNode el | result.(ElementNode).getElement() = el |
el = this.getChildNode(childIndex)
)
}
@@ -195,16 +195,16 @@ private module PrintJavaScript {
* Gets the `i`th child of `element`.
* Can be overriden in subclasses to get more specific behavior for `getChild()`.
*/
ASTNode getChildNode(int childIndex) { result = getLocationSortedChild(element, childIndex) }
AstNode getChildNode(int childIndex) { result = getLocationSortedChild(element, childIndex) }
}
/** Provides predicates for pretty printing `ASTNode`s. */
/** Provides predicates for pretty printing `AstNode`s. */
private module PrettyPrinting {
/**
* Gets a pretty string representation of `element`.
* Either the result is `ASTNode::toString`, or a custom made string representation of `element`.
*/
string print(ASTNode element) {
string print(AstNode element) {
shouldPrint(element, _) and
(
result = element.toString().regexpReplaceAll("(\\\\n|\\\\r|\\\\t| )+", " ") and
@@ -217,7 +217,7 @@ private module PrintJavaScript {
/**
* Gets a string representing `a`.
*/
private string repr(ASTNode a) {
private string repr(AstNode a) {
shouldPrint(a, _) and
(
exists(DeclStmt decl | decl = a |
@@ -252,9 +252,9 @@ private module PrintJavaScript {
}
}
private ASTNode getLocationSortedChild(ASTNode parent, int i) {
private AstNode getLocationSortedChild(AstNode parent, int i) {
result =
rank[i](ASTNode child, int childIndex |
rank[i](AstNode child, int childIndex |
child = parent.getChild(childIndex)
|
child
@@ -370,62 +370,77 @@ private module PrintJavaScript {
* 2: An aggregate node for all the attributes (for example `href={foo}` in `<Name href={foo} />`).
* 3: An aggregate node for all the body element (for example `foo` in `<span>foo</span>`).
*/
class JSXNodeNode extends ElementNode {
override JSXNode element;
class JsxNodeNode extends ElementNode {
override JsxNode element;
override PrintAstNode getChild(int childIndex) {
childIndex = 0 and result.(ElementNode).getElement() = element.(JSXElement).getNameExpr()
childIndex = 0 and result.(ElementNode).getElement() = element.(JsxElement).getNameExpr()
or
childIndex = 1 and
exists(element.getABodyElement()) and
result.(JSXBodyElementsNode).getJSXNode() = element
result.(JsxBodyElementsNode).getJsxNode() = element
or
childIndex = 2 and
exists(element.(JSXElement).getAttribute(_)) and
result.(JSXAttributesNode).getJSXElement() = element
exists(element.(JsxElement).getAttribute(_)) and
result.(JsxAttributesNode).getJsxElement() = element
}
}
/** DEPRECATED: Alias for JsxNodeNode */
deprecated class JSXNodeNode = JsxNodeNode;
/**
* An aggregate node representing all the attributes in a `JSXNode`.
*/
class JSXAttributesNode extends PrintAstNode, TJSXAttributesNode {
JSXElement n;
class JsxAttributesNode extends PrintAstNode, TJsxAttributesNode {
JsxElement n;
JSXAttributesNode() { this = TJSXAttributesNode(n) and exists(n.getAttribute(_)) }
JsxAttributesNode() { this = TJsxAttributesNode(n) and exists(n.getAttribute(_)) }
override string toString() { result = "(Attributes)" }
/**
* Gets the `JSXElement` for which this node represents the attributes.
*/
JSXElement getJSXElement() { result = n }
JsxElement getJsxElement() { result = n }
/** DEPRECATED: Alias for getJsxElement */
deprecated JSXElement getJSXElement() { result = this.getJsxElement() }
override PrintAstNode getChild(int childIndex) {
result.(ElementNode).getElement() = n.getAttribute(childIndex)
}
}
/** DEPRECATED: Alias for JsxAttributesNode */
deprecated class JSXAttributesNode = JsxAttributesNode;
/**
* An aggregate node representing all the body elements in a `JSXNode`.
*/
class JSXBodyElementsNode extends PrintAstNode, TJSXBodyElementsNode {
JSXNode n;
class JsxBodyElementsNode extends PrintAstNode, TJsxBodyElementsNode {
JsxNode n;
JSXBodyElementsNode() { this = TJSXBodyElementsNode(n) and exists(n.getBodyElement(_)) }
JsxBodyElementsNode() { this = TJsxBodyElementsNode(n) and exists(n.getBodyElement(_)) }
override string toString() { result = "(Body)" }
/**
* Gets the `JSXNode` for which this node represents the body elements.
*/
JSXNode getJSXNode() { result = n }
JsxNode getJsxNode() { result = n }
/** DEPRECATED: Alias for getJsxNode */
deprecated JSXNode getJSXNode() { result = this.getJsxNode() }
override PrintAstNode getChild(int childIndex) {
result.(ElementNode).getElement() = n.getBodyElement(childIndex)
}
}
/** DEPRECATED: Alias for JsxBodyElementsNode */
deprecated class JSXBodyElementsNode = JsxBodyElementsNode;
/**
* A node representing any `ASTNode` that has type-parameters.
*
@@ -484,7 +499,7 @@ private module PrintJavaScript {
class ParameterNode extends ElementNode {
override Parameter element;
override ASTNode getChildNode(int childIndex) {
override AstNode getChildNode(int childIndex) {
childIndex = 0 and result = element.getTypeAnnotation()
or
childIndex = 1 and result = element.getDefault()
@@ -535,14 +550,14 @@ private module PrintJavaScript {
/**
* Classes for printing JSON AST.
*/
private module PrintJSON {
private module PrintJson {
/**
* A print node representing a JSON value in a .json file.
*/
class JSONNode extends PrintAstNode, TJSONNode {
JSONValue value;
class JsonNode extends PrintAstNode, TJsonNode {
JsonValue value;
JSONNode() { this = TJSONNode(value) }
JsonNode() { this = TJsonNode(value) }
override string toString() { result = getQlClass(value) + PrettyPrinting::print(value) }
@@ -551,22 +566,25 @@ private module PrintJSON {
/**
* Gets the `JSONValue` represented by this node.
*/
final JSONValue getValue() { result = value }
final JsonValue getValue() { result = value }
override PrintAstNode getChild(int childIndex) {
exists(JSONValue child | result.(JSONNode).getValue() = child |
exists(JsonValue child | result.(JsonNode).getValue() = child |
child = value.getChild(childIndex)
)
}
}
/** DEPRECATED: Alias for JsonNode */
deprecated class JSONNode = JsonNode;
/** Provied predicates for pretty printing JSON. */
private module PrettyPrinting {
/**
* Gets a string representation of `n`.
* Either using the default `JSONValue::toString`, or a custom printing of the JSON value.
*/
string print(JSONValue n) {
string print(JsonValue n) {
shouldPrint(n, _) and
(
result = n.toString().regexpReplaceAll("(\\\\n|\\\\r|\\\\t| )+", " ") and
@@ -577,20 +595,20 @@ private module PrintJSON {
}
/** Gets a string representing `n`. */
private string repr(JSONValue n) {
private string repr(JsonValue n) {
shouldPrint(n, _) and
(
exists(JSONObject obj, string name, JSONValue prop | obj = n |
exists(JsonObject obj, string name, JsonValue prop | obj = n |
prop = obj.getPropValue(name) and
prop = obj.getChild(0) and
result = "{" + name + ": ...}"
)
or
n instanceof JSONObject and not exists(n.getChild(_)) and result = "{}"
n instanceof JsonObject and not exists(n.getChild(_)) and result = "{}"
or
result = n.(JSONPrimitiveValue).getRawValue()
result = n.(JsonPrimitiveValue).getRawValue()
or
exists(JSONArray arr | arr = n |
exists(JsonArray arr | arr = n |
result = "[]" and not exists(arr.getChild(_))
or
result = "[" + repr(arr.getChild(0)) + "]" and not exists(arr.getChild(1))
@@ -605,14 +623,14 @@ private module PrintJSON {
/**
* Classes for printing YAML AST.
*/
module PrintYAML {
module PrintYaml {
/**
* A print node representing a YAML value in a .yml file.
*/
class YAMLNodeNode extends PrintAstNode, TYAMLNode {
class YamlNodeNode extends PrintAstNode, TYamlNode {
YAMLNode node;
YAMLNodeNode() { this = TYAMLNode(node) }
YamlNodeNode() { this = TYamlNode(node) }
override string toString() { result = getQlClass(node) + node.toString() }
@@ -624,33 +642,39 @@ module PrintYAML {
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)
)
}
}
/** DEPRECATED: Alias for YamlNodeNode */
deprecated class YAMLNodeNode = YamlNodeNode;
/**
* A print node representing a `YAMLMapping`.
*
* Each child of this node aggregates the key and value of a mapping.
*/
class YAMLMappingNode extends YAMLNodeNode {
class YamlMappingNode extends YamlNodeNode {
override YAMLMapping node;
override PrintAstNode getChild(int childIndex) {
exists(YAMLMappingMapNode map | map = result | map.maps(node, childIndex))
exists(YamlMappingMapNode map | map = result | map.maps(node, childIndex))
}
}
/** DEPRECATED: Alias for YamlMappingNode */
deprecated class YAMLMappingNode = YamlMappingNode;
/**
* A print node representing the `i`th mapping in `mapping`.
*/
class YAMLMappingMapNode extends PrintAstNode, TYAMLMappingNode {
class YamlMappingMapNode extends PrintAstNode, TYamlMappingNode {
YAMLMapping mapping;
int i;
YAMLMappingMapNode() { this = TYAMLMappingNode(mapping, i) }
YamlMappingMapNode() { this = TYamlMappingNode(mapping, i) }
override string toString() {
result = "(Mapping " + i + ")" and not exists(mapping.getKeyNode(i).(YAMLScalar).getValue())
@@ -667,24 +691,30 @@ module PrintYAML {
}
override PrintAstNode getChild(int childIndex) {
childIndex = 0 and result.(YAMLNodeNode).getValue() = mapping.getKeyNode(i)
childIndex = 0 and result.(YamlNodeNode).getValue() = mapping.getKeyNode(i)
or
childIndex = 1 and result.(YAMLNodeNode).getValue() = mapping.getValueNode(i)
childIndex = 1 and result.(YamlNodeNode).getValue() = mapping.getValueNode(i)
}
}
/** DEPRECATED: Alias for YamlMappingMapNode */
deprecated class YAMLMappingMapNode = YamlMappingMapNode;
}
/** DEPRECATED: Alias for PrintYaml */
deprecated module PrintYAML = PrintYaml;
/**
* Classes for printing HTML AST.
*/
module PrintHTML {
module PrintHtml {
/**
* A print node representing an HTML node in a .html file.
*/
class HTMLElementNode extends PrintAstNode, THTMLElementNode {
class HtmlElementNode extends PrintAstNode, THtmlElementNode {
HTML::Element element;
HTMLElementNode() { this = THTMLElementNode(element) }
HtmlElementNode() { this = THtmlElementNode(element) }
override string toString() { result = getQlClass(element) + "<" + element.getName() + " ..." }
@@ -696,36 +726,42 @@ module PrintHTML {
final HTML::Element getElement() { result = element }
override PrintAstNode getChild(int childIndex) {
childIndex = -1 and result.(HTMLAttributesNodes).getElement() = element
childIndex = -1 and result.(HtmlAttributesNodes).getElement() = element
or
exists(HTML::Element child | result.(HTMLElementNode).getElement() = child |
exists(HTML::Element child | result.(HtmlElementNode).getElement() = child |
child = element.getChild(childIndex)
)
}
}
/** DEPRECATED: Alias for HtmlElementNode */
deprecated class HTMLElementNode = HtmlElementNode;
/**
* A print node representing an HTML node in a .html file.
*/
class HTMLScriptElementNode extends HTMLElementNode {
class HtmlScriptElementNode extends HtmlElementNode {
override HTML::ScriptElement element;
override PrintAstNode getChild(int childIndex) {
childIndex = -200 and result.(HTMLScript).getScript() = element.getScript()
childIndex = -200 and result.(HtmlScript).getScript() = element.getScript()
or
result = super.getChild(childIndex)
}
}
/** DEPRECATED: Alias for HtmlScriptElementNode */
deprecated class HTMLScriptElementNode = HtmlScriptElementNode;
/**
* A print node representing the code inside a `<script>` element.
*/
class HTMLScript extends PrintAstNode, THTMLScript {
class HtmlScript extends PrintAstNode, THtmlScript {
Script script;
HTMLScript() {
this = THTMLScript(script) and
any(HTMLScriptElementNode se).getElement().(HTML::ScriptElement).getScript() = script
HtmlScript() {
this = THtmlScript(script) and
any(HtmlScriptElementNode se).getElement().(HTML::ScriptElement).getScript() = script
}
override string toString() { result = "(Script)" }
@@ -742,15 +778,18 @@ module PrintHTML {
}
}
/** DEPRECATED: Alias for HtmlScript */
deprecated class HTMLScript = HtmlScript;
/**
* A print node representing the code inside an attribute.
*/
class HTMLCodeInAttr extends PrintAstNode, THTMLCodeInAttr {
class HtmlCodeInAttr extends PrintAstNode, THtmlCodeInAttr {
CodeInAttribute attr;
HTMLCodeInAttr() {
this = THTMLCodeInAttr(attr) and
any(HTMLAttributeNode an).getAttribute().getCodeInAttribute() = attr
HtmlCodeInAttr() {
this = THtmlCodeInAttr(attr) and
any(HtmlAttributeNode an).getAttribute().getCodeInAttribute() = attr
}
override string toString() { result = "(Script)" }
@@ -767,14 +806,17 @@ module PrintHTML {
}
}
/** DEPRECATED: Alias for HtmlCodeInAttr */
deprecated class HTMLCodeInAttr = HtmlCodeInAttr;
/**
* An aggregate node representing all the attributes of an HTMLElement.
*/
class HTMLAttributesNodes extends PrintAstNode, THTMLAttributesNodes {
class HtmlAttributesNodes extends PrintAstNode, THtmlAttributesNodes {
HTML::Element element;
HTMLAttributesNodes() {
this = THTMLAttributesNodes(element) and exists(element.getAttribute(_))
HtmlAttributesNodes() {
this = THtmlAttributesNodes(element) and exists(element.getAttribute(_))
}
override string toString() { result = "(Attributes)" }
@@ -785,17 +827,20 @@ module PrintHTML {
HTML::Element getElement() { result = element }
override PrintAstNode getChild(int childIndex) {
result.(HTMLAttributeNode).getAttribute() = element.getAttribute(childIndex)
result.(HtmlAttributeNode).getAttribute() = element.getAttribute(childIndex)
}
}
/** DEPRECATED: Alias for HtmlAttributesNodes */
deprecated class HTMLAttributesNodes = HtmlAttributesNodes;
/**
* A print node representing an HTML attribute in a .html file.
*/
class HTMLAttributeNode extends PrintAstNode, THTMLAttributeNode {
class HtmlAttributeNode extends PrintAstNode, THtmlAttributeNode {
HTML::Attribute attr;
HTMLAttributeNode() { this = THTMLAttributeNode(attr) }
HtmlAttributeNode() { this = THtmlAttributeNode(attr) }
override string toString() { result = getQlClass(attr) + attr.toString() }
@@ -807,11 +852,17 @@ module PrintHTML {
final HTML::Attribute getAttribute() { result = attr }
override PrintAstNode getChild(int childIndex) {
childIndex = 0 and result.(HTMLCodeInAttr).getCode() = attr.getCodeInAttribute()
childIndex = 0 and result.(HtmlCodeInAttr).getCode() = attr.getCodeInAttribute()
}
}
/** DEPRECATED: Alias for HtmlAttributeNode */
deprecated class HTMLAttributeNode = HtmlAttributeNode;
}
/** DEPRECATED: Alias for PrintHtml */
deprecated module PrintHTML = PrintHtml;
/** Holds if `node` belongs to the output tree, and its property `key` has the given `value`. */
query predicate nodes(PrintAstNode node, string key, string value) { value = node.getProperty(key) }

View File

@@ -434,11 +434,6 @@ module PromiseFlow {
}
}
/**
* DEPRECATED. Use `TaintTracking::promiseStep` instead.
*/
deprecated predicate promiseTaintStep = TaintTracking::promiseStep/2;
private class PromiseTaintStep extends TaintTracking::SharedTaintStep {
override predicate promiseStep(DataFlow::Node pred, DataFlow::Node succ) {
// from `x` to `new Promise((res, rej) => res(x))`

View File

@@ -663,15 +663,6 @@ class RegExpNormalConstant extends RegExpConstant, @regexp_normal_constant {
override string getAPrimaryQlClass() { result = "RegExpNormalConstant" }
}
/**
* DEPRECATED. Use `RegExpNormalConstant` instead.
*
* This class used to represent an individual normal character but has been superseded by
* `RegExpNormalConstant`, which represents a sequence of normal characters.
* There is no longer a separate node for each individual character in a constant.
*/
deprecated class RegExpNormalChar = RegExpNormalConstant;
/**
* A hexadecimal character escape in a regular expression.
*
@@ -1306,8 +1297,8 @@ module RegExp {
/**
* A meta character used by HTML.
*/
private class HTMLMetaCharacter extends MetaCharacter {
HTMLMetaCharacter() { this = ["<", "'", "\""] }
private class HtmlMetaCharacter extends MetaCharacter {
HtmlMetaCharacter() { this = ["<", "'", "\""] }
}
/**

View File

@@ -10,17 +10,20 @@ class SourceMappingComment extends Comment {
string url;
SourceMappingComment() {
exists(string sourceMappingURLRegex |
sourceMappingURLRegex = "[@#]\\s*sourceMappingURL\\s*=\\s*(.*)\\s*"
exists(string sourceMappingUrlRegex |
sourceMappingUrlRegex = "[@#]\\s*sourceMappingURL\\s*=\\s*(.*)\\s*"
|
// either a line comment whose entire text matches the regex...
url = this.(SlashSlashComment).getText().regexpCapture(sourceMappingURLRegex, 1)
url = this.(SlashSlashComment).getText().regexpCapture(sourceMappingUrlRegex, 1)
or
// ...or a block comment one of whose lines matches the regex
url = this.(SlashStarComment).getLine(_).regexpCapture("//" + sourceMappingURLRegex, 1)
url = this.(SlashStarComment).getLine(_).regexpCapture("//" + sourceMappingUrlRegex, 1)
)
}
/** Gets the URL of the source map referenced by this comment. */
string getSourceMappingURL() { result = url }
string getSourceMappingUrl() { result = url }
/** DEPRECATED: Alias for getSourceMappingUrl */
deprecated string getSourceMappingURL() { result = getSourceMappingUrl() }
}

View File

@@ -248,7 +248,7 @@ private class MaybeDirective extends ExprStmt {
*/
class Directive extends MaybeDirective {
Directive() {
exists(StmtContainer sc, ASTNode body, int i |
exists(StmtContainer sc, AstNode body, int i |
// directives must be toplevel statements in their container
body = sc.getBody() and
this = body.getChildStmt(i) and
@@ -502,7 +502,7 @@ class JumpStmt extends TJumpStmt, Stmt {
* Note that this predicate does not take `finally` clauses
* into account, which may interrupt the jump.
*/
abstract ASTNode getTarget();
abstract AstNode getTarget();
}
/**
@@ -583,7 +583,7 @@ class WithStmt extends @with_stmt, ControlStmt {
exists(Variable v | v = acc.getVariable() |
v instanceof GlobalVariable
or
exists(ASTNode scopeElt | scopeElt = v.getScope().getScopeElement() |
exists(AstNode scopeElt | scopeElt = v.getScope().getScopeElement() |
scopeElt = this.getParent+()
)
)
@@ -676,7 +676,7 @@ class ThrowStmt extends @throw_stmt, JumpStmt {
* `try` statement in whose body the throw statement occurs. If there is no such
* `try` statement, the target defaults to the enclosing statement container.
*/
override ASTNode getTarget() {
override AstNode getTarget() {
if exists(TryStmt ts | this.getParentStmt+() = ts.getBody())
then
this.getParentStmt+() = result.(TryStmt).getBody() and
@@ -802,7 +802,7 @@ class DoWhileStmt extends @do_while_stmt, LoopStmt {
* var i = 1;
* ```
*/
class ExprOrVarDecl extends ASTNode {
class ExprOrVarDecl extends AstNode {
ExprOrVarDecl() {
this instanceof Expr or
this instanceof DeclStmt

View File

@@ -98,7 +98,7 @@ class NamespaceDeclaration extends NamespaceDefinition, StmtContainer, @namespac
* Note that imports and type parameters are not type definitions. Consider using `TypeDecl` to capture
* a wider class of type declarations.
*/
class TypeDefinition extends ASTNode, @type_definition {
class TypeDefinition extends AstNode, @type_definition {
/**
* Gets the identifier naming the type.
*/
@@ -376,7 +376,7 @@ class ConstructorTypeExpr extends FunctionTypeExpr, @constructor_typeexpr { }
class PlainFunctionTypeExpr extends FunctionTypeExpr, @plain_function_typeexpr { }
/** A possibly qualified identifier that declares or refers to a type. */
abstract class TypeRef extends ASTNode { }
abstract class TypeRef extends AstNode { }
/** An identifier declaring a type name, that is, the name of a class, interface, type parameter, or import. */
class TypeDecl extends Identifier, TypeRef, LexicalDecl {
@@ -1291,7 +1291,7 @@ class ExpressionWithTypeArguments extends @expression_with_type_arguments, Expr
/**
* A program element that supports type parameters, that is, a function, class, interface, type alias, mapped type, or `infer` type.
*/
class TypeParameterized extends @type_parameterized, ASTNode {
class TypeParameterized extends @type_parameterized, AstNode {
/** Gets the `n`th type parameter declared on this function or type. */
TypeParameter getTypeParameter(int n) { none() } // Overridden in subtypes.
@@ -1394,7 +1394,7 @@ class NonNullAssertion extends Expr, @non_null_assertion {
/**
* A possibly qualified identifier that refers to or declares a local name for a namespace.
*/
abstract class NamespaceRef extends ASTNode { }
abstract class NamespaceRef extends AstNode { }
/**
* An identifier that declares a local name for a namespace, that is,
@@ -1602,7 +1602,7 @@ class EnumDeclaration extends NamespaceDefinition, @enum_declaration, AST::Value
* enum Color { red = 1, green, blue }
* ```
*/
class EnumMember extends ASTNode, @enum_member {
class EnumMember extends AstNode, @enum_member {
/**
* Gets the name of the enum member, such as `off` in `enum State { on, off }`.
*
@@ -1754,20 +1754,6 @@ class ReferenceImport extends LineComment {
* Gets the name of the attribute, i.e. "`path`" or "`types`".
*/
string getAttributeName() { result = attribute }
/**
* DEPRECATED. This is no longer supported.
*
* Gets the file referenced by this import.
*/
deprecated File getImportedFile() { none() }
/**
* DEPRECATED. This is no longer supported.
*
* Gets the top-level of the referenced file.
*/
deprecated TopLevel getImportedTopLevel() { none() }
}
/**
@@ -1853,11 +1839,6 @@ class Type extends @type {
*/
Type getChild(int i) { type_child(result, this, i) }
/**
* DEPRECATED. Property lookup on types is no longer supported.
*/
deprecated Type getProperty(string name) { none() }
/**
* Gets the type of the string index signature on this type,
* such as `T` in the type `{ [s: string]: T }`.
@@ -1960,21 +1941,6 @@ class Type extends @type {
*/
int getNumConstructorSignature() { result = count(this.getAConstructorSignature()) }
/**
* DEPRECATED. Method lookup on types is no longer supported.
*/
deprecated FunctionCallSignatureType getMethod(string name) { none() }
/**
* DEPRECATED. Method lookup on types is no longer supported.
*/
deprecated FunctionCallSignatureType getMethodOverload(string name, int n) { none() }
/**
* DEPRECATED. Method lookup on types is no longer supported.
*/
deprecated FunctionCallSignatureType getAMethodOverload(string name) { none() }
/**
* Repeatedly unfolds union and intersection types and gets any of the underlying types,
* or this type itself if it is not a union or intersection.

View File

@@ -14,7 +14,7 @@ class Scope extends @scope {
Scope getAnInnerScope() { result.getOuterScope() = this }
/** Gets the program element this scope is associated with, if any. */
ASTNode getScopeElement() { scopenodes(result, this) }
AstNode getScopeElement() { scopenodes(result, this) }
/** Gets the location of the program element this scope is associated with, if any. */
Location getLocation() { result = this.getScopeElement().getLocation() }
@@ -32,7 +32,7 @@ class Scope extends @scope {
/**
* A program element that induces a scope.
*/
class ScopeElement extends ASTNode {
class ScopeElement extends AstNode {
Scope s;
ScopeElement() { this = s.getScopeElement() }
@@ -581,7 +581,7 @@ class ObjectPattern extends DestructuringPattern, @object_pattern {
* }
* ```
*/
class PropertyPattern extends @property, ASTNode {
class PropertyPattern extends @property, AstNode {
PropertyPattern() {
// filter out ordinary properties
exists(ObjectPattern obj | properties(this, obj, _, _, _))

View File

@@ -4,21 +4,14 @@
import semmle.files.FileSystem
private class TXMLLocatable =
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) }
/**
* DEPRECATED: Use `getLocation()` instead.
*
* Gets the source location for this element.
*/
deprecated Location getALocation() { result = this.getLocation() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
@@ -83,21 +76,6 @@ class XMLParent extends @xmlparent {
/** Gets the number of places in the body of this XML parent where text occurs. */
int getNumberOfCharacterSets() { result = count(int pos | xmlChars(_, _, this, pos, _, _)) }
/**
* DEPRECATED: Internal.
*
* Append the character sequences of this XML parent from left to right, separated by a space,
* up to a specified (zero-based) index.
*/
deprecated string charsSetUpTo(int n) {
n = 0 and xmlChars(_, result, this, 0, _, _)
or
n > 0 and
exists(string chars | xmlChars(_, chars, this, n, _, _) |
result = this.charsSetUpTo(n - 1) + " " + chars
)
}
/**
* Gets the result of appending all the character sequences of this XML parent from
* left to right, separated by a space.

View File

@@ -166,20 +166,6 @@ abstract class Configuration extends string {
)
}
/**
* DEPRECATED: Use `isBarrierEdge` instead.
*
* Holds if flow from `src` to `trg` is prohibited.
*/
deprecated predicate isBarrier(DataFlow::Node src, DataFlow::Node trg) { none() }
/**
* DEPRECATED: Use `isBarrierEdge` instead.
*
* Holds if flow with label `lbl` cannot flow from `src` to `trg`.
*/
deprecated predicate isBarrier(DataFlow::Node src, DataFlow::Node trg, FlowLabel lbl) { none() }
/**
* Holds if flow from `pred` to `succ` is prohibited.
*/
@@ -535,13 +521,6 @@ private predicate isLabeledBarrierEdge(
*/
abstract class LabeledBarrierGuardNode extends BarrierGuardNode {
override predicate blocks(boolean outcome, Expr e) { none() }
/**
* DEPRECATED: Use `blocks(outcome, e, label)` or `sanitizes(outcome, e, label)` instead.
*
* Overriding this predicate has no effect.
*/
deprecated FlowLabel getALabel() { none() }
}
/**

View File

@@ -78,7 +78,7 @@ module DataFlow {
}
/** Gets the AST node corresponding to this data flow node, if any. */
ASTNode getAstNode() { none() }
AstNode getAstNode() { none() }
/** Gets the basic block to which this node belongs. */
BasicBlock getBasicBlock() { none() }
@@ -332,7 +332,7 @@ module DataFlow {
override File getFile() { result = ssa.getBasicBlock().getFile() }
override ASTNode getAstNode() { none() }
override AstNode getAstNode() { none() }
}
/**
@@ -353,11 +353,11 @@ module DataFlow {
.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
override string toString() { result = prop.(ASTNode).toString() }
override string toString() { result = prop.(AstNode).toString() }
override File getFile() { result = prop.(ASTNode).getFile() }
override File getFile() { result = prop.(AstNode).getFile() }
override ASTNode getAstNode() { result = prop }
override AstNode getAstNode() { result = prop }
}
/**
@@ -382,7 +382,7 @@ module DataFlow {
override File getFile() { result = pattern.getFile() }
override ASTNode getAstNode() { result = rest }
override AstNode getAstNode() { result = rest }
}
/**
@@ -407,7 +407,7 @@ module DataFlow {
override File getFile() { result = pattern.getFile() }
override ASTNode getAstNode() { result = elt }
override AstNode getAstNode() { result = elt }
}
/**
@@ -436,7 +436,7 @@ module DataFlow {
override File getFile() { result = arr.getFile() }
override ASTNode getAstNode() { result = elt }
override AstNode getAstNode() { result = elt }
}
/**
@@ -445,9 +445,8 @@ module DataFlow {
*/
private class ReflectiveCallNode extends Node, TReflectiveCallNode {
MethodCallExpr call;
string kind;
ReflectiveCallNode() { this = TReflectiveCallNode(call, kind) }
ReflectiveCallNode() { this = TReflectiveCallNode(call, _) }
override BasicBlock getBasicBlock() { result = call.getBasicBlock() }
@@ -720,7 +719,7 @@ module DataFlow {
* the JSX element it is in.
*/
private class JsxAttributeAsPropWrite extends PropWrite, PropNode {
override JSXAttribute prop;
override JsxAttribute prop;
override Node getBase() { result = valueNode(prop.getElement()) }
@@ -1308,7 +1307,7 @@ module DataFlow {
* This predicate is only defined for expressions, properties, and for statements that declare
* a function, a class, or a TypeScript namespace or enum.
*/
ValueNode valueNode(ASTNode nd) { result.getAstNode() = nd }
ValueNode valueNode(AstNode nd) { result.getAstNode() = nd }
/**
* Gets the data flow node corresponding to `e`.
@@ -1670,11 +1669,11 @@ module DataFlow {
or
exists(Expr e | e = nd.asExpr() and cause = "heap" |
e instanceof PropAccess or
e instanceof E4X::XMLAnyName or
e instanceof E4X::XMLAttributeSelector or
e instanceof E4X::XMLDotDotExpression or
e instanceof E4X::XMLFilterExpression or
e instanceof E4X::XMLQualifiedIdentifier or
e instanceof E4X::XmlAnyName or
e instanceof E4X::XmlAttributeSelector or
e instanceof E4X::XmlDotDotExpression or
e instanceof E4X::XmlFilterExpression or
e instanceof E4X::XmlQualifiedIdentifier or
e instanceof Angular2::PipeRefExpr
)
or
@@ -1716,9 +1715,8 @@ module DataFlow {
import Sources
import TypeInference
import Configuration
import TrackedNodes
import TypeTracking
import internal.FunctionWrapperSteps
predicate localTaintStep = TaintTracking::localTaintStep/2;
deprecated predicate localTaintStep = TaintTracking::localTaintStep/2;
}

View File

@@ -1403,13 +1403,6 @@ module PartialInvokeNode {
*/
DataFlow::SourceNode getBoundFunction(DataFlow::Node callback, int boundArgs) { none() }
/**
* DEPRECATED. Use the one-argument version of `getBoundReceiver` instead.
*
* Gets the node holding the receiver to be passed to the bound function, if specified.
*/
deprecated DataFlow::Node getBoundReceiver() { none() }
/**
* Gets the node holding the receiver to be passed to `callback`.
*/
@@ -1541,16 +1534,6 @@ module PartialInvokeNode {
}
}
/**
* DEPRECATED. Subclasses should extend `PartialInvokeNode::Range` instead,
* and predicates should use `PartialInvokeNode` instead.
*
* An invocation that is modeled as a partial function application.
*
* This contributes additional argument-passing flow edges that should be added to all data flow configurations.
*/
deprecated class AdditionalPartialInvokeNode = PartialInvokeNode::Range;
/**
* An invocation of the `RegExp` constructor.
*

View File

@@ -180,7 +180,7 @@ private class NpmPackagePortal extends Portal, MkNpmPackagePortal {
private module NpmPackagePortal {
/** Gets an import of `imported` inside package `importer`. */
pragma[noinline]
private DataFlow::SourceNode getAModuleImport(NPMPackage importer, string imported) {
private DataFlow::SourceNode getAModuleImport(NpmPackage importer, string imported) {
result = DataFlow::moduleImport(imported) and
result.getTopLevel() = importer.getAModule()
}
@@ -188,7 +188,7 @@ private module NpmPackagePortal {
/** Gets an import of `member` from `imported` inside package `importer`. */
pragma[noinline]
private DataFlow::SourceNode getAModuleMemberImport(
NPMPackage importer, string imported, string member
NpmPackage importer, string imported, string member
) {
result = DataFlow::moduleMember(imported, member) and
result.getTopLevel() = importer.getAModule()
@@ -196,7 +196,7 @@ private module NpmPackagePortal {
/** Holds if `imp` is an import of package `pkgName`. */
predicate imports(DataFlow::SourceNode imp, string pkgName) {
exists(NPMPackage pkg |
exists(NpmPackage pkg |
imp = getAModuleImport(pkg, pkgName) and
pkgName.regexpMatch("[^./].*")
)
@@ -204,7 +204,7 @@ private module NpmPackagePortal {
/** Holds if `imp` imports `member` from package `pkgName`. */
predicate imports(DataFlow::SourceNode imp, string pkgName, string member) {
exists(NPMPackage pkg |
exists(NpmPackage pkg |
imp = getAModuleMemberImport(pkg, pkgName, member) and
pkgName.regexpMatch("[^./].*")
)
@@ -212,7 +212,7 @@ private module NpmPackagePortal {
/** Gets the main module of package `pkgName`. */
Module packageMain(string pkgName) {
exists(PackageJSON pkg |
exists(PackageJson pkg |
// don't construct portals for private packages
not pkg.isPrivate() and
// don't construct portals for vendored-in packages

View File

@@ -146,7 +146,8 @@ class SourceNode extends DataFlow::Node {
* that is, `o.m(...)` or `o[p](...)`.
*/
DataFlow::CallNode getAChainedMethodCall(string methodName) {
result = getAMethodCall*().getAMethodCall(methodName)
// the direct call to `getAMethodCall` is needed in case the base is not a `DataFlow::CallNode`.
result = [getAMethodCall+().getAMethodCall(methodName), getAMethodCall(methodName)]
}
/**
@@ -301,13 +302,13 @@ module SourceNode {
*/
class DefaultRange extends Range {
DefaultRange() {
exists(ASTNode astNode | this = DataFlow::valueNode(astNode) |
exists(AstNode astNode | this = DataFlow::valueNode(astNode) |
astNode instanceof PropAccess or
astNode instanceof Function or
astNode instanceof ClassDefinition or
astNode instanceof ObjectExpr or
astNode instanceof ArrayExpr or
astNode instanceof JSXNode or
astNode instanceof JsxNode or
astNode instanceof GlobalVarAccess or
astNode instanceof ExternalModuleReference or
astNode instanceof RegExpLiteral or
@@ -395,7 +396,3 @@ SourceNode moduleVarNode(Module m) { result.(ModuleVarNode).getModule() = m }
/** Gets the CommonJS/AMD `exports` variable for module `m`. */
SourceNode exportsVarNode(Module m) { result.(ExportsVarNode).getModule() = m }
deprecated class DefaultSourceNode extends SourceNode {
DefaultSourceNode() { this instanceof SourceNode::DefaultRange }
}

View File

@@ -62,24 +62,6 @@ module TaintTracking {
*/
predicate isSanitizer(DataFlow::Node node) { none() }
/**
* DEPRECATED: Use `isSanitizerEdge` instead.
*
* Holds if the edge from `source` to `sink` is a taint sanitizer.
*/
deprecated predicate isSanitizer(DataFlow::Node source, DataFlow::Node sink) { none() }
/**
* DEPRECATED: Use `isSanitizerEdge` instead.
*
* Holds if the edge from `source` to `sink` is a taint sanitizer for data labelled with `lbl`.
*/
deprecated predicate isSanitizer(
DataFlow::Node source, DataFlow::Node sink, DataFlow::FlowLabel lbl
) {
none()
}
/** Holds if the edge from `pred` to `succ` is a taint sanitizer. */
predicate isSanitizerEdge(DataFlow::Node pred, DataFlow::Node succ) { none() }
@@ -447,9 +429,10 @@ module TaintTracking {
/**
* Holds if `pred -> succ` is a taint propagating data flow edge through a string operation.
* DEPRECATED: Use `stringConcatenationStep` and `stringManipulationStep` instead.
*/
pragma[inline]
predicate stringStep(DataFlow::Node pred, DataFlow::Node succ) {
deprecated predicate stringStep(DataFlow::Node pred, DataFlow::Node succ) {
stringConcatenationStep(pred, succ) or
stringManipulationStep(pred, succ)
}
@@ -551,7 +534,10 @@ module TaintTracking {
or
// reading from a tainted object yields a tainted result
succ.(DataFlow::PropRead).getBase() = pred and
not AccessPath::DominatingPaths::hasDominatingWrite(succ) and
not (
AccessPath::DominatingPaths::hasDominatingWrite(succ) and
exists(succ.(DataFlow::PropRead).getPropertyName())
) and
not isSafeClientSideUrlProperty(succ) and
not ClassValidator::isAccessToSanitizedField(succ)
or
@@ -570,11 +556,10 @@ module TaintTracking {
}
/**
* DEPRECATED. Use the predicate `TaintTracking::persistentStorageStep` instead.
*
* A taint propagating data flow edge through persistent storage.
* Use `TaintTracking::persistentStorageStep` instead of accessing this class.
*/
deprecated class PersistentStorageTaintStep extends SharedTaintStep {
private class PersistentStorageTaintStep extends SharedTaintStep {
override predicate persistentStorageStep(DataFlow::Node pred, DataFlow::Node succ) {
exists(PersistentReadAccess read |
pred = read.getAWrite().getValue() and
@@ -583,8 +568,6 @@ module TaintTracking {
}
}
deprecated predicate arrayFunctionTaintStep = ArrayTaintTracking::arrayFunctionTaintStep/3;
/**
* A taint propagating data flow edge for assignments of the form `o[k] = v`, where
* one of the following holds:
@@ -1175,9 +1158,6 @@ module TaintTracking {
polarity = guard.asExpr().(EqualityTest).getPolarity()
}
/** DEPRECATED. This class has been renamed to `MembershipTestSanitizer`. */
deprecated class StringInclusionSanitizer = MembershipTestSanitizer;
/**
* A test of form `x.length === "0"`, preventing `x` from being tainted.
*/
@@ -1200,9 +1180,6 @@ module TaintTracking {
override predicate appliesTo(Configuration cfg) { any() }
}
/** DEPRECATED. This class has been renamed to `MembershipTestSanitizer`. */
deprecated class InclusionSanitizer = MembershipTestSanitizer;
/**
* A check of the form `whitelist.includes(x)` or equivalent, which sanitizes `x` in its "then" branch.
*/
@@ -1244,38 +1221,6 @@ module TaintTracking {
override predicate appliesTo(Configuration cfg) { any() }
}
/** Gets a variable that is defined exactly once. */
private Variable singleDef() { strictcount(result.getADefinition()) = 1 }
/**
* A check of the form `if(x == 'some-constant')`, which sanitizes `x` in its "then" branch.
*
* DEPRECATED: use `MembershipTestSanitizer` instead.
*/
deprecated class ConstantComparison extends SanitizerGuardNode, DataFlow::ValueNode {
Expr x;
override EqualityTest astNode;
ConstantComparison() {
exists(Expr const | astNode.hasOperands(x, const) |
// either the other operand is a constant
const instanceof ConstantExpr
or
// or it's an access to a variable that probably acts as a symbolic constant
const = singleDef().getAnAccess()
)
}
override predicate sanitizes(boolean outcome, Expr e) {
outcome = astNode.getPolarity() and x = e
}
/**
* Holds if this guard applies to the flow in `cfg`.
*/
predicate appliesTo(Configuration cfg) { any() }
}
/**
* An equality test on `e.origin` or `e.source` where `e` is a `postMessage` event object,
* considered as a sanitizer for `e`.
@@ -1301,8 +1246,9 @@ module TaintTracking {
/**
* Holds if taint propagates from `pred` to `succ` in one local (intra-procedural) step.
* DEPRECATED: Use `TaintTracking::sharedTaintStep` and `DataFlow::Node::getALocalSource()` instead.
*/
predicate localTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
deprecated predicate localTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
DataFlow::localFlowStep(pred, succ) or
sharedTaintStep(pred, succ)
}

View File

@@ -1,425 +0,0 @@
/**
* DEPRECATED: Use `TypeTracking.qll` instead.
*
* The following `TrackedNode` usage is usually equivalent to the type tracking usage below.
*
* ```
* class MyTrackedNode extends TrackedNode {
* MyTrackedNode() { isInteresting(this) }
* }
*
* DataFlow::Node getMyTrackedNodeLocation(MyTrackedNode n) {
* n.flowsTo(result)
* }
* ```
*
* ```
* DataFlow::SourceNode getMyTrackedNodeLocation(DataFlow::SourceNode start, DataFlow::TypeTracker t) {
* t.start() and
* isInteresting(result) and
* result = start
* or
* exists (DataFlow::TypeTracker t2 |
* result = getMyTrackedNodeLocation(start, t2).track(t2, t)
* )
* }
*
* DataFlow::SourceNode getMyTrackedNodeLocation(DataFlow::SourceNode n) {
* result = getMyTrackedNodeLocation(n, DataFlow::TypeTracker::end())
* }
* ```
*
* In rare cases, additional tracking is required, for instance when tracking string constants, and the following type tracking formulation is required instead.
*
* ```
* DataFlow::Node getMyTrackedNodeLocation(DataFlow::Node start, DataFlow::TypeTracker t) {
* t.start() and
* isInteresting(result) and
* result = start
* or
* exists(DataFlow::TypeTracker t2 |
* t = t2.smallstep(getMyTrackedNodeLocation(start, t2), result)
* )
* }
*
* DataFlow::Node getMyTrackedNodeLocation(DataFlow::Node n) {
* result = getMyTrackedNodeLocation(n, DataFlow::TypeTracker::end())
* }
* ```
*
* Provides support for inter-procedural tracking of a customizable
* set of data flow nodes.
*/
private import javascript
private import internal.FlowSteps as FlowSteps
/**
* A data flow node that should be tracked inter-procedurally.
*
* To track additional values, extends this class with additional
* subclasses.
*/
abstract deprecated class TrackedNode extends DataFlow::Node {
/**
* Holds if this node flows into `sink` in zero or more (possibly
* inter-procedural) steps.
*/
predicate flowsTo(DataFlow::Node sink) { NodeTracking::flowsTo(this, sink, _) }
}
/**
* An expression whose value should be tracked inter-procedurally.
*
* To track additional expressions, extends this class with additional
* subclasses.
*/
abstract deprecated class TrackedExpr extends Expr {
predicate flowsTo(Expr sink) {
exists(TrackedExprNode ten | ten.asExpr() = this | ten.flowsTo(DataFlow::valueNode(sink)))
}
}
/**
* Turn all `TrackedExpr`s into `TrackedNode`s.
*/
deprecated private class TrackedExprNode extends TrackedNode {
TrackedExprNode() { asExpr() instanceof TrackedExpr }
}
/**
* A simplified copy of `Configuration.qll` that implements tracking
* of `TrackedNode`s without barriers or additional flow steps.
*/
private module NodeTracking {
private import internal.FlowSteps
/**
* Holds if data can flow in one step from `pred` to `succ`, taking
* additional steps into account.
*/
pragma[inline]
predicate localFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
pred = succ.getAPredecessor()
or
DataFlow::SharedFlowStep::step(pred, succ)
or
localExceptionStep(pred, succ)
}
/**
* Holds if there is a flow step from `pred` to `succ` described by `summary`.
*
* Summary steps through function calls are not taken into account.
*/
deprecated private predicate basicFlowStep(
DataFlow::Node pred, DataFlow::Node succ, PathSummary summary
) {
isRelevant(pred) and
(
// Local flow
localFlowStep(pred, succ) and
summary = PathSummary::level()
or
// Flow through properties of objects
propertyFlowStep(pred, succ) and
summary = PathSummary::level()
or
// Flow through global variables
globalFlowStep(pred, succ) and
summary = PathSummary::level()
or
// Flow into function
callStep(pred, succ) and
summary = PathSummary::call()
or
// Flow out of function
returnStep(pred, succ) and
summary = PathSummary::return()
)
}
/**
* Holds if `nd` may be reachable from a tracked node.
*
* No call/return matching is done, so this is a relatively coarse over-approximation.
*/
deprecated private predicate isRelevant(DataFlow::Node nd) {
nd instanceof TrackedNode
or
exists(DataFlow::Node mid | isRelevant(mid) |
basicFlowStep(mid, nd, _)
or
basicStoreStep(mid, nd, _)
or
basicLoadStep(mid, nd, _)
or
exploratoryCallbackStep(mid, nd)
or
nd = mid.(DataFlow::FunctionNode).getAParameter()
)
}
/**
* Holds if `pred` is an input to `f` which is passed to `succ` at `invk`; that is,
* either `pred` is an argument of `f` and `succ` the corresponding parameter, or
* `pred` is a variable definition whose value is captured by `f` at `succ`.
*/
deprecated private predicate callInputStep(
Function f, DataFlow::Node invk, DataFlow::Node pred, DataFlow::Node succ
) {
isRelevant(pred) and
(
argumentPassing(invk, pred, f, succ)
or
exists(LocalVariable variable, SsaDefinition def |
pred = DataFlow::capturedVariableNode(variable) and
calls(invk, f) and
captures(f, variable, def) and
succ = DataFlow::ssaDefinitionNode(def)
)
)
}
/**
* Holds if `input`, which is either an argument to `f` at `invk` or a definition
* that is captured by `f`, may flow to `nd` (possibly through callees, but not containing
* any unmatched calls or returns) along a path summarized by `summary`.
*/
deprecated private predicate reachableFromInput(
Function f, DataFlow::Node invk, DataFlow::Node input, DataFlow::Node nd, PathSummary summary
) {
callInputStep(f, invk, input, nd) and
summary = PathSummary::level()
or
exists(DataFlow::Node mid, PathSummary oldSummary, PathSummary newSummary |
reachableFromInput(f, invk, input, mid, oldSummary) and
flowStep(mid, nd, newSummary) and
newSummary.isLevel() and
summary = oldSummary.append(newSummary)
)
}
/**
* Holds if `nd` may flow into a return statement of `f`
* (possibly through callees) along a path summarized by `summary`.
*/
deprecated private predicate reachesReturn(Function f, DataFlow::Node nd, PathSummary summary) {
returnExpr(f, nd, _) and
summary = PathSummary::level()
or
exists(DataFlow::Node mid, PathSummary oldSummary, PathSummary newSummary |
flowStep(nd, mid, oldSummary) and
reachesReturn(f, mid, newSummary) and
summary = oldSummary.append(newSummary)
)
}
/**
* Holds if a function invoked at `invk` may return an expression into which `input`,
* which is either an argument or a definition captured by the function, flows,
* possibly through callees.
*/
deprecated private predicate flowThroughCall(DataFlow::Node input, DataFlow::Node output) {
exists(Function f, DataFlow::ValueNode ret |
ret.asExpr() = f.getAReturnedExpr() and
reachableFromInput(f, output, input, ret, _)
)
or
exists(Function f, DataFlow::Node invk, DataFlow::Node ret |
DataFlow::exceptionalFunctionReturnNode(ret, f) and
DataFlow::exceptionalInvocationReturnNode(output, invk.asExpr()) and
calls(invk, f) and
reachableFromInput(f, invk, input, ret, _)
)
}
/**
* Holds if `pred` may flow into property `prop` of `succ` along a path summarized by `summary`.
*/
deprecated private predicate storeStep(
DataFlow::Node pred, DataFlow::SourceNode succ, string prop, PathSummary summary
) {
basicStoreStep(pred, succ, prop) and
summary = PathSummary::level()
or
exists(Function f, DataFlow::Node mid | not f.isAsyncOrGenerator() |
// `f` stores its parameter `pred` in property `prop` of a value that flows back to the caller,
// and `succ` is an invocation of `f`
reachableFromInput(f, succ, pred, mid, summary) and
(
returnedPropWrite(f, _, prop, mid)
or
succ instanceof DataFlow::NewNode and
receiverPropWrite(f, prop, mid)
)
)
}
/**
* Holds if property `prop` of `pred` may flow into `succ` along a path summarized by
* `summary`.
*/
deprecated private predicate loadStep(
DataFlow::Node pred, DataFlow::Node succ, string prop, PathSummary summary
) {
basicLoadStep(pred, succ, prop) and
summary = PathSummary::level()
or
exists(Function f, DataFlow::SourceNode parm | not f.isAsyncOrGenerator() |
argumentPassing(succ, pred, f, parm) and
reachesReturn(f, parm.getAPropertyRead(prop), summary)
)
}
/**
* Holds if `rhs` is the right-hand side of a write to property `prop`, and `nd` is reachable
* from the base of that write (possibly through callees) along a path summarized by `summary`.
*/
deprecated private predicate reachableFromStoreBase(
string prop, DataFlow::Node rhs, DataFlow::Node nd, PathSummary summary
) {
storeStep(rhs, nd, prop, summary)
or
exists(DataFlow::Node mid, PathSummary oldSummary, PathSummary newSummary |
reachableFromStoreBase(prop, rhs, mid, oldSummary) and
flowStep(mid, nd, newSummary) and
summary = oldSummary.append(newSummary)
)
}
/**
* 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` along a path summarized by `summary`.
*
* In other words, `pred` may flow to `succ` through a property.
*/
deprecated private predicate flowThroughProperty(
DataFlow::Node pred, DataFlow::Node succ, PathSummary summary
) {
exists(string prop, DataFlow::Node base, PathSummary oldSummary, PathSummary newSummary |
reachableFromStoreBase(prop, pred, base, oldSummary) and
loadStep(base, succ, prop, newSummary) and
summary = oldSummary.append(newSummary)
)
}
/**
* Holds if `arg` and `cb` are passed as arguments to a function which in turn
* invokes `cb`, passing `arg` as its `i`th argument. `arg` flows along a path summarized
* by `summary`, while `cb` is only tracked locally.
*/
deprecated private predicate summarizedHigherOrderCall(
DataFlow::Node arg, DataFlow::Node cb, int i, PathSummary summary
) {
exists(
Function f, DataFlow::InvokeNode outer, DataFlow::InvokeNode inner, int j,
DataFlow::Node innerArg, DataFlow::SourceNode cbParm, PathSummary oldSummary
|
reachableFromInput(f, outer, arg, innerArg, oldSummary) and
argumentPassing(outer, cb, f, cbParm) and
innerArg = inner.getArgument(j)
|
// direct higher-order call
cbParm.flowsTo(inner.getCalleeNode()) and
i = j and
summary = oldSummary
or
// indirect higher-order call
exists(DataFlow::Node cbArg, PathSummary newSummary |
cbParm.flowsTo(cbArg) and
summarizedHigherOrderCall(innerArg, cbArg, i, newSummary) and
summary = oldSummary.append(PathSummary::call()).append(newSummary)
)
)
}
/**
* Holds if `arg` is passed as the `i`th argument to `callback` through a callback invocation.
*
* This can be a summarized call, that is, `arg` and `callback` flow into a call,
* `f(arg, callback)`, which performs the invocation.
*
* Alternatively, the callback can flow into a call `f(callback)` which itself provides the `arg`.
* That is, `arg` refers to a value defined in `f` or one of its callees.
*/
deprecated predicate higherOrderCall(
DataFlow::Node arg, DataFlow::SourceNode callback, int i, PathSummary summary
) {
// Summarized call
exists(DataFlow::Node cb |
summarizedHigherOrderCall(arg, cb, i, summary) and
callback.flowsTo(cb)
)
or
// Local invocation of a parameter
isRelevant(arg) and
exists(DataFlow::InvokeNode invoke |
arg = invoke.getArgument(i) and
invoke = callback.(DataFlow::ParameterNode).getACall() and
summary = PathSummary::call()
)
or
// Forwarding of the callback parameter (but not the argument).
// We use a return summary since flow moves back towards the call site.
// This ensures that an argument that is only tainted in some contexts cannot flow
// out to every callback.
exists(DataFlow::Node cbArg, DataFlow::SourceNode innerCb, PathSummary oldSummary |
higherOrderCall(arg, innerCb, i, oldSummary) and
callStep(cbArg, innerCb) and
callback.flowsTo(cbArg) and
summary = PathSummary::return().append(oldSummary)
)
}
/**
* Holds if `pred` is passed as an argument to a function `f` which also takes a
* callback parameter `cb` and then invokes `cb`, passing `pred` into parameter `succ`
* of `cb`. `arg` flows along a path summarized by `summary`, while `cb` is only tracked
* locally.
*/
deprecated private predicate flowIntoHigherOrderCall(
DataFlow::Node pred, DataFlow::Node succ, PathSummary summary
) {
exists(DataFlow::FunctionNode cb, int i, PathSummary oldSummary |
higherOrderCall(pred, cb, i, oldSummary) and
succ = cb.getParameter(i) and
summary = oldSummary.append(PathSummary::call())
)
}
/**
* Holds if there is a flow step from `pred` to `succ` described by `summary`.
*/
deprecated private predicate flowStep(
DataFlow::Node pred, DataFlow::Node succ, PathSummary summary
) {
basicFlowStep(pred, succ, summary)
or
// Flow through a function that returns a value that depends on one of its arguments
// or a captured variable
flowThroughCall(pred, succ) and
summary = PathSummary::level()
or
// Flow through a property write/read pair
flowThroughProperty(pred, succ, summary)
or
// Flow into higher-order call
flowIntoHigherOrderCall(pred, succ, summary)
}
/**
* Holds if there is a path from `source` to `nd` along a path summarized by
* `summary`.
*/
deprecated predicate flowsTo(TrackedNode source, DataFlow::Node nd, PathSummary summary) {
source = nd and
summary = PathSummary::level()
or
exists(DataFlow::Node pred, PathSummary oldSummary, PathSummary newSummary |
flowsTo(source, pred, oldSummary) and
flowStep(pred, nd, newSummary) and
summary = oldSummary.append(newSummary)
)
}
}

View File

@@ -129,8 +129,8 @@ private class AnalyzedEnumDeclaration extends DataFlow::AnalyzedValueNode {
/**
* Flow analysis for JSX elements and fragments.
*/
private class AnalyzedJSXNode extends DataFlow::AnalyzedValueNode {
override JSXNode astNode;
private class AnalyzedJsxNode extends DataFlow::AnalyzedValueNode {
override JsxNode astNode;
override AbstractValue getALocalValue() { result = TAbstractOtherObject() }
}
@@ -138,8 +138,8 @@ private class AnalyzedJSXNode extends DataFlow::AnalyzedValueNode {
/**
* Flow analysis for qualified JSX names.
*/
private class AnalyzedJSXQualifiedName extends DataFlow::AnalyzedValueNode {
override JSXQualifiedName astNode;
private class AnalyzedJsxQualifiedName extends DataFlow::AnalyzedValueNode {
override JsxQualifiedName astNode;
override AbstractValue getALocalValue() { result = TAbstractOtherObject() }
}
@@ -147,8 +147,8 @@ private class AnalyzedJSXQualifiedName extends DataFlow::AnalyzedValueNode {
/**
* Flow analysis for empty JSX expressions.
*/
private class AnalyzedJSXEmptyExpression extends DataFlow::AnalyzedValueNode {
override JSXEmptyExpr astNode;
private class AnalyzedJsxEmptyExpression extends DataFlow::AnalyzedValueNode {
override JsxEmptyExpr astNode;
override AbstractValue getALocalValue() { result = TAbstractUndefined() }
}

View File

@@ -380,9 +380,10 @@ private class AnalyzedExportAssign extends AnalyzedPropertyWrite, DataFlow::Valu
*/
private class AnalyzedClosureExportAssign extends AnalyzedPropertyWrite, DataFlow::ValueNode {
override AssignExpr astNode;
Closure::ClosureModule mod;
AnalyzedClosureExportAssign() { astNode.getLhs() = mod.getExportsVariable().getAReference() }
AnalyzedClosureExportAssign() {
astNode.getLhs() = any(Closure::ClosureModule mod).getExportsVariable().getAReference()
}
override predicate writes(AbstractValue baseVal, string propName, DataFlow::AnalyzedNode source) {
baseVal = TAbstractModuleObject(astNode.getTopLevel()) and

View File

@@ -302,12 +302,11 @@ private class TypeInferredMethodWithAnalyzedReturnFlow extends CallWithNonLocalA
* Propagates receivers into locally defined callbacks of partial invocations.
*/
private class AnalyzedThisInPartialInvokeCallback extends AnalyzedNode, DataFlow::ThisNode {
DataFlow::PartialInvokeNode call;
DataFlow::Node receiver;
AnalyzedThisInPartialInvokeCallback() {
exists(DataFlow::Node callbackArg |
receiver = call.getBoundReceiver(callbackArg) and
receiver = any(DataFlow::PartialInvokeNode call).getBoundReceiver(callbackArg) and
getBinder().flowsTo(callbackArg)
)
}

View File

@@ -138,7 +138,7 @@ class AnalyzedVarDef extends VarDef {
/**
* Gets the toplevel syntactic unit to which this definition belongs.
*/
TopLevel getTopLevel() { result = this.(ASTNode).getTopLevel() }
TopLevel getTopLevel() { result = this.(AstNode).getTopLevel() }
}
/**

View File

@@ -35,9 +35,12 @@ abstract class Dependency extends Locatable {
* the source tree, or a package that is referenced as a dependency
* in a `package.json` file.
*/
abstract class NPMDependency extends Dependency {
abstract class NpmDependency extends Dependency {
/** Gets the name of the NPM package this module belongs to. */
abstract string getNPMPackageName();
abstract string getNpmPackageName();
/** DEPRECATED: Alias for getNpmPackageName */
deprecated string getNPMPackageName() { result = this.getNpmPackageName() }
/** Gets the version of the NPM package this module belongs to. */
abstract string getVersion();
@@ -46,7 +49,7 @@ abstract class NPMDependency extends Dependency {
abstract Import getAnImport();
override predicate info(string id, string v) {
id = this.getNPMPackageName() and
id = this.getNpmPackageName() and
v = this.getVersion()
}
@@ -59,6 +62,9 @@ abstract class NPMDependency extends Dependency {
}
}
/** DEPRECATED: Alias for NpmDependency */
deprecated class NPMDependency = NpmDependency;
/**
* Gets a variable into which something is imported by `i`.
*/
@@ -83,23 +89,26 @@ private Expr propAccessOn(Expr e) { result.(PropAccess).getBase() = e }
* included in the database (as opposed to an `ExternalNPMDependency`
* which is only referenced in a `package.json` file).
*/
class BundledNPMDependency extends NPMDependency {
BundledNPMDependency() {
exists(NPMPackage pkg | this = pkg.getAModule() |
class BundledNpmDependency extends NpmDependency {
BundledNpmDependency() {
exists(NpmPackage pkg | this = pkg.getAModule() |
// exclude packages marked "private": they have no globally unique ID
not pkg.getPackageJSON().isPrivate()
not pkg.getPackageJson().isPrivate()
)
}
/** Gets the package to which this module belongs. */
private NPMPackage getPackage() { this = result.getAModule() }
private NpmPackage getPackage() { this = result.getAModule() }
/** Gets the `package.json` of the package to which this module belongs. */
private PackageJSON getPackageJSON() { result = this.getPackage().getPackageJSON() }
private PackageJson getPackageJson() { result = this.getPackage().getPackageJson() }
override string getNPMPackageName() { result = this.getPackageJSON().getPackageName() }
override string getNpmPackageName() { result = this.getPackageJson().getPackageName() }
override string getVersion() { result = this.getPackageJSON().getVersion() }
/** DEPRECATED: Alias for getNpmPackageName */
deprecated override string getNPMPackageName() { result = this.getNpmPackageName() }
override string getVersion() { result = this.getPackageJson().getVersion() }
override Import getAnImport() {
this = result.getImportedModule() and
@@ -108,27 +117,33 @@ class BundledNPMDependency extends NPMDependency {
}
}
/** DEPRECATED: Alias for BundledNpmDependency */
deprecated class BundledNPMDependency = BundledNpmDependency;
/**
* An NPM package referenced in a `package.json` file.
*/
class ExternalNPMDependency extends NPMDependency {
ExternalNPMDependency() {
exists(PackageJSON pkgjson |
this.(JSONString) = pkgjson.getADependenciesObject(_).getPropValue(_)
class ExternalNpmDependency extends NpmDependency {
ExternalNpmDependency() {
exists(PackageJson pkgjson |
this.(JsonString) = pkgjson.getADependenciesObject(_).getPropValue(_)
)
}
/** Gets the NPM package declaring this dependency. */
private NPMPackage getDeclaringPackage() {
this = result.getPackageJSON().getADependenciesObject(_).getPropValue(_)
private NpmPackage getDeclaringPackage() {
this = result.getPackageJson().getADependenciesObject(_).getPropValue(_)
}
override string getNPMPackageName() {
override string getNpmPackageName() {
exists(PackageDependencies pkgdeps | this = pkgdeps.getPropValue(result))
}
/** DEPRECATED: Alias for getNpmPackageName */
deprecated override string getNPMPackageName() { result = this.getNpmPackageName() }
private string getVersionNumber() {
exists(string versionRange | versionRange = this.(JSONString).getValue() |
exists(string versionRange | versionRange = this.(JsonString).getValue() |
// extract a concrete version from the version range; currently,
// we handle exact versions as well as `<=`, `>=`, `~` and `^` ranges
result = versionRange.regexpCapture("(?:[><]=|[=~^])?v?(\\d+(\\.\\d+){1,2})", 1)
@@ -151,13 +166,16 @@ class ExternalNPMDependency extends NPMDependency {
}
}
/** DEPRECATED: Alias for ExternalNpmDependency */
deprecated class ExternalNPMDependency = ExternalNpmDependency;
/**
* Holds if import `i` may refer to the declared dependency `dep` of package `pkg`,
* where the result value is the nesting depth of the file containing `i` within `pkg`.
*/
private int importsDependency(Import i, NPMPackage pkg, NPMDependency dep) {
private int importsDependency(Import i, NpmPackage pkg, NpmDependency dep) {
exists(string name |
dep = pkg.getPackageJSON().getADependenciesObject(_).getPropValue(name) and
dep = pkg.getPackageJson().getADependenciesObject(_).getPropValue(name) and
not exists(i.getImportedModule()) and
i.getImportedPath().getComponent(0) = name and
i.getEnclosingModule() = pkg.getAModule() and

View File

@@ -125,9 +125,9 @@ abstract class FrameworkLibraryWithMarkerComment extends FrameworkLibrary {
* A framework library that is referenced by URLs that have a certain
* pattern.
*/
abstract class FrameworkLibraryWithURLRegex extends FrameworkLibrary {
abstract class FrameworkLibraryWithUrlRegex extends FrameworkLibrary {
bindingset[this]
FrameworkLibraryWithURLRegex() { this = this }
FrameworkLibraryWithUrlRegex() { this = this }
/**
* Gets a regular expression that can be used to identify a URL referring
@@ -136,9 +136,15 @@ abstract class FrameworkLibraryWithURLRegex extends FrameworkLibrary {
* The first capture group of this regular expression should match
* the version number.
*/
abstract string getAURLRegex();
abstract string getAUrlRegex();
/** DEPRECATED: Alias for getAUrlRegex */
deprecated string getAURLRegex() { result = this.getAUrlRegex() }
}
/** DEPRECATED: Alias for FrameworkLibraryWithUrlRegex */
deprecated class FrameworkLibraryWithURLRegex = FrameworkLibraryWithUrlRegex;
/**
* A framework library that is referenced by URLs containing the name
* of the framework (or an alias) and a version string.
@@ -154,14 +160,14 @@ abstract class FrameworkLibraryWithURLRegex extends FrameworkLibrary {
*
* See `variantRegex()` below for a discussion of variant suffixes.
*/
abstract class FrameworkLibraryWithGenericURL extends FrameworkLibraryWithURLRegex {
abstract class FrameworkLibraryWithGenericUrl extends FrameworkLibraryWithUrlRegex {
bindingset[this]
FrameworkLibraryWithGenericURL() { this = this }
FrameworkLibraryWithGenericUrl() { this = this }
/** Gets an alternative name of this library. */
string getAnAlias() { none() }
override string getAURLRegex() {
override string getAUrlRegex() {
exists(string id | id = this.getId() or id = this.getAnAlias() |
result = ".*(?:^|/)" + id + "-(" + semverRegex() + ")" + variantRegex() + "\\.js" or
result =
@@ -169,8 +175,14 @@ abstract class FrameworkLibraryWithGenericURL extends FrameworkLibraryWithURLReg
"\\.js"
)
}
/** DEPRECATED: Alias for getAUrlRegex */
deprecated override string getAURLRegex() { result = this.getAUrlRegex() }
}
/** DEPRECATED: Alias for FrameworkLibraryWithGenericUrl */
deprecated class FrameworkLibraryWithGenericURL = FrameworkLibraryWithGenericUrl;
/**
* Gets a regular expression identifying suffixes that are commonly appended
* to the name of a library to distinguish minor variants.
@@ -264,20 +276,23 @@ private predicate matchMarkerComment(
/**
* A reference to a `FrameworkLibraryWithURL`.
*/
class FrameworkLibraryReferenceWithURL extends FrameworkLibraryReference {
FrameworkLibraryReferenceWithURL() { matchURL(this, _, _) }
class FrameworkLibraryReferenceWithUrl extends FrameworkLibraryReference {
FrameworkLibraryReferenceWithUrl() { matchUrl(this, _, _) }
override predicate info(FrameworkLibrary fl, string v) { matchURL(this, fl, v) }
override predicate info(FrameworkLibrary fl, string v) { matchUrl(this, fl, v) }
}
/** DEPRECATED: Alias for FrameworkLibraryReferenceWithUrl */
deprecated class FrameworkLibraryReferenceWithURL = FrameworkLibraryReferenceWithUrl;
/**
* Holds if the value of `src` attribute `attr` matches the URL pattern of library
* `fl` at `version`.
*/
private predicate matchURL(HTML::Attribute attr, FrameworkLibraryWithURLRegex fl, string version) {
private predicate matchUrl(HTML::Attribute attr, FrameworkLibraryWithUrlRegex fl, string version) {
attr.getName() = "src" and
attr.getElement() instanceof HTML::ScriptElement and
version = attr.getValue().regexpCapture(fl.getAURLRegex(), 1)
version = attr.getValue().regexpCapture(fl.getAUrlRegex(), 1)
}
/**
@@ -288,7 +303,7 @@ private string versionRegex() { result = "\\d+\\.\\d+[A-Za-z0-9.+_-]*" }
/**
* The jQuery framework.
*/
private class JQuery extends FrameworkLibraryWithGenericURL {
private class JQuery extends FrameworkLibraryWithGenericUrl {
JQuery() { this = "jquery" }
override string getAnEntryPoint() { result = "$" or result = "jQuery" }
@@ -331,7 +346,7 @@ private class JQueryInstance extends FrameworkLibraryInstance {
/**
* The jQuery Mobile framework.
*/
private class JQueryMobile extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class JQueryMobile extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
JQueryMobile() { this = "jquery-mobile" }
override string getAnAlias() { result = "jquery.mobile" }
@@ -344,7 +359,7 @@ private class JQueryMobile extends FrameworkLibraryWithGenericURL, FrameworkLibr
/**
* The jQuery UI framework.
*/
private class JQueryUI extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class JQueryUI extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
JQueryUI() { this = "jquery-ui" }
override string getAMarkerCommentRegex() { result = "(?s).*jQuery UI - v?(<VERSION>).*" }
@@ -355,7 +370,7 @@ private class JQueryUI extends FrameworkLibraryWithGenericURL, FrameworkLibraryW
/**
* The jQuery TextExt framework.
*/
private class JQueryTextExt extends FrameworkLibraryWithGenericURL,
private class JQueryTextExt extends FrameworkLibraryWithGenericUrl,
FrameworkLibraryWithMarkerComment {
JQueryTextExt() { this = "jquery-textext" }
@@ -371,7 +386,7 @@ private class JQueryTextExt extends FrameworkLibraryWithGenericURL,
/**
* The jQuery DataTables framework.
*/
private class JQueryDataTables extends FrameworkLibraryWithGenericURL,
private class JQueryDataTables extends FrameworkLibraryWithGenericUrl,
FrameworkLibraryWithMarkerComment {
JQueryDataTables() { this = "jquery-dataTables" }
@@ -385,7 +400,7 @@ private class JQueryDataTables extends FrameworkLibraryWithGenericURL,
/**
* The jQuery jsTree framework.
*/
private class JQueryJsTree extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class JQueryJsTree extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
JQueryJsTree() { this = "jquery-jstree" }
override string getAnAlias() { result = "jquery.jstree" }
@@ -396,7 +411,7 @@ private class JQueryJsTree extends FrameworkLibraryWithGenericURL, FrameworkLibr
/**
* The jQuery Snippet framework.
*/
private class JQuerySnippet extends FrameworkLibraryWithGenericURL,
private class JQuerySnippet extends FrameworkLibraryWithGenericUrl,
FrameworkLibraryWithMarkerComment {
JQuerySnippet() { this = "jquery-snippet" }
@@ -410,7 +425,7 @@ private class JQuerySnippet extends FrameworkLibraryWithGenericURL,
/**
* The Bootstrap framework.
*/
private class Bootstrap extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class Bootstrap extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
Bootstrap() { this = "bootstrap" }
override string getAMarkerCommentRegex() {
@@ -423,7 +438,7 @@ private class Bootstrap extends FrameworkLibraryWithGenericURL, FrameworkLibrary
/**
* The Modernizr framework.
*/
private class Modernizr extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class Modernizr extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
Modernizr() { this = "modernizr" }
override string getAMarkerCommentRegex() {
@@ -436,7 +451,7 @@ private class Modernizr extends FrameworkLibraryWithGenericURL, FrameworkLibrary
/**
* The MooTools framework.
*/
private class MooTools extends FrameworkLibraryWithGenericURL {
private class MooTools extends FrameworkLibraryWithGenericUrl {
MooTools() { this = "mootools" }
override string getAnEntryPoint() { /* not easily detectable */ none() }
@@ -479,7 +494,7 @@ private class MooToolsInstance extends FrameworkLibraryInstance {
/**
* The Prototype framework.
*/
private class Prototype extends FrameworkLibraryWithGenericURL {
private class Prototype extends FrameworkLibraryWithGenericUrl {
Prototype() { this = "prototype" }
override string getAnEntryPoint() { /* not easily detectable */ none() }
@@ -518,7 +533,7 @@ private class PrototypeInstance extends FrameworkLibraryInstance {
/**
* The Scriptaculous framework.
*/
private class Scriptaculous extends FrameworkLibraryWithGenericURL {
private class Scriptaculous extends FrameworkLibraryWithGenericUrl {
Scriptaculous() { this = "scriptaculous" }
override string getAnEntryPoint() { /* not easily detectable */ none() }
@@ -557,7 +572,7 @@ private class ScriptaculousInstance extends FrameworkLibraryInstance {
/**
* The Underscore framework.
*/
private class Underscore extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class Underscore extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
Underscore() { this = "underscore" }
override string getAMarkerCommentRegex() { result = "^\\s*Underscore.js (<VERSION>).*" }
@@ -568,7 +583,7 @@ private class Underscore extends FrameworkLibraryWithGenericURL, FrameworkLibrar
/**
* The Lodash framework.
*/
private class Lodash extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class Lodash extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
Lodash() { this = "lodash" }
override string getAMarkerCommentRegex() {
@@ -581,7 +596,7 @@ private class Lodash extends FrameworkLibraryWithGenericURL, FrameworkLibraryWit
}
/** The Dojo framework. */
private class Dojo extends FrameworkLibraryWithGenericURL {
private class Dojo extends FrameworkLibraryWithGenericUrl {
Dojo() { this = "dojo" }
override string getAnEntryPoint() { result = "dojo" }
@@ -613,7 +628,7 @@ private class DojoInstance extends FrameworkLibraryInstance {
/**
* The ExtJS framework.
*/
private class ExtJS extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class ExtJS extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
ExtJS() { this = "extjs" }
override string getAMarkerCommentRegex() {
@@ -629,7 +644,7 @@ private class ExtJS extends FrameworkLibraryWithGenericURL, FrameworkLibraryWith
/**
* The YUI framework.
*/
private class YUI extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class YUI extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
YUI() { this = "yui" }
override string getAMarkerCommentRegex() { result = "(?s).*YUI (<VERSION>) \\(build \\d+\\).*" }
@@ -640,7 +655,7 @@ private class YUI extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMa
/**
* The Knockout framework.
*/
private class Knockout extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class Knockout extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
Knockout() { this = "knockout" }
override string getAMarkerCommentRegex() {
@@ -653,7 +668,7 @@ private class Knockout extends FrameworkLibraryWithGenericURL, FrameworkLibraryW
/**
* The AngularJS framework.
*/
private class AngularJS extends FrameworkLibraryWithGenericURL {
private class AngularJS extends FrameworkLibraryWithGenericUrl {
AngularJS() { this = "angularjs" }
override string getAnAlias() { result = "angular" or result = "angular2" }
@@ -691,7 +706,7 @@ private class AngularJSInstance extends FrameworkLibraryInstance {
/**
* The Angular UI bootstrap framework.
*/
private class AngularUIBootstrap extends FrameworkLibraryWithGenericURL {
private class AngularUIBootstrap extends FrameworkLibraryWithGenericUrl {
AngularUIBootstrap() { this = "angular-ui-bootstrap" }
override string getAnAlias() { result = "ui-bootstrap" }
@@ -722,7 +737,7 @@ private class AngularUIBootstrapInstance extends FrameworkLibraryInstance {
/**
* The React framework.
*/
private class React extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class React extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
React() { this = "react" }
override string getAMarkerCommentRegex() {
@@ -733,15 +748,15 @@ private class React extends FrameworkLibraryWithGenericURL, FrameworkLibraryWith
/**
* The Microsoft AJAX Framework.
*/
private class MicrosoftAJAXFramework extends FrameworkLibrary {
MicrosoftAJAXFramework() { this = "microsoft-ajax-framework" }
private class MicrosoftAjaxFramework extends FrameworkLibrary {
MicrosoftAjaxFramework() { this = "microsoft-ajax-framework" }
}
/**
* Holds if comments `c1` and `c2` in toplevel `tl` are marker comments for the given
* `version` of the Microsoft AJAX Framework.
*/
private predicate microsoftAJAXFrameworkMarkerComments(
private predicate microsoftAjaxFrameworkMarkerComments(
Comment c1, Comment c2, TopLevel tl, string version
) {
tl = c1.getTopLevel() and
@@ -753,19 +768,19 @@ private predicate microsoftAJAXFrameworkMarkerComments(
/**
* A copy of the Microsoft AJAX Framework.
*/
private class MicrosoftAJAXFrameworkInstance extends FrameworkLibraryInstance {
MicrosoftAJAXFrameworkInstance() { microsoftAJAXFrameworkMarkerComments(_, _, this, _) }
private class MicrosoftAjaxFrameworkInstance extends FrameworkLibraryInstance {
MicrosoftAjaxFrameworkInstance() { microsoftAjaxFrameworkMarkerComments(_, _, this, _) }
override predicate info(FrameworkLibrary fl, string v) {
fl instanceof MicrosoftAJAXFramework and
microsoftAJAXFrameworkMarkerComments(_, _, this, v)
fl instanceof MicrosoftAjaxFramework and
microsoftAjaxFrameworkMarkerComments(_, _, this, v)
}
}
/**
* The Polymer framework.
*/
private class Polymer extends FrameworkLibraryWithGenericURL {
private class Polymer extends FrameworkLibraryWithGenericUrl {
Polymer() { this = "polymer" }
override string getAnEntryPoint() { result = "Polymer" }
@@ -800,7 +815,7 @@ private class PolymerInstance extends FrameworkLibraryInstance {
/**
* The Vue.js framework.
*/
private class VueJS extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class VueJS extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
VueJS() { this = "vue" }
override string getAMarkerCommentRegex() { result = "(?s).*Vue\\.js v(<VERSION>).*" }
@@ -811,7 +826,7 @@ private class VueJS extends FrameworkLibraryWithGenericURL, FrameworkLibraryWith
/**
* The Swagger UI framework.
*/
private class SwaggerUI extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class SwaggerUI extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
SwaggerUI() { this = "swagger-ui" }
override string getAMarkerCommentRegex() {
@@ -822,7 +837,7 @@ private class SwaggerUI extends FrameworkLibraryWithGenericURL, FrameworkLibrary
/**
* The Backbone.js framework.
*/
private class BackboneJS extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class BackboneJS extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
BackboneJS() { this = "backbone" }
override string getAMarkerCommentRegex() { result = "(?s).*Backbone\\.js (<VERSION>).*" }
@@ -833,7 +848,7 @@ private class BackboneJS extends FrameworkLibraryWithGenericURL, FrameworkLibrar
/**
* The Ember.js framework.
*/
private class EmberJS extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class EmberJS extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
EmberJS() { this = "ember" }
override string getAMarkerCommentRegex() {
@@ -846,7 +861,7 @@ private class EmberJS extends FrameworkLibraryWithGenericURL, FrameworkLibraryWi
/**
* The QUnit.js framework.
*/
private class QUnitJS extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class QUnitJS extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
QUnitJS() { this = "qunit" }
override string getAMarkerCommentRegex() { result = "(?s).*QUnit\\s*(<VERSION>).*" }
@@ -857,28 +872,28 @@ private class QUnitJS extends FrameworkLibraryWithGenericURL, FrameworkLibraryWi
/**
* The Mocha framework.
*/
private class Mocha extends FrameworkLibraryWithGenericURL {
private class Mocha extends FrameworkLibraryWithGenericUrl {
Mocha() { this = "mocha" }
}
/**
* The Jasmine framework.
*/
private class Jasmine extends FrameworkLibraryWithGenericURL {
private class Jasmine extends FrameworkLibraryWithGenericUrl {
Jasmine() { this = "jasmine" }
}
/**
* The Chai framework.
*/
private class Chai extends FrameworkLibraryWithGenericURL {
private class Chai extends FrameworkLibraryWithGenericUrl {
Chai() { this = "chai" }
}
/**
* The Sinon.JS framework.
*/
private class SinonJS extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class SinonJS extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
SinonJS() { this = "sinon" }
override string getAnAlias() { result = "sinon-ie" or result = "sinon-timers" }
@@ -889,7 +904,7 @@ private class SinonJS extends FrameworkLibraryWithGenericURL, FrameworkLibraryWi
/**
* The TinyMCE framework.
*/
private class TinyMCE extends FrameworkLibraryWithGenericURL {
private class TinyMCE extends FrameworkLibraryWithGenericUrl {
TinyMCE() { this = "tinymce" }
override string getAnAlias() { result = "jquery.tinymce" or result = "tinymce.jquery" }
@@ -898,7 +913,7 @@ private class TinyMCE extends FrameworkLibraryWithGenericURL {
/**
* The Require.js framework.
*/
private class RequireJS extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class RequireJS extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
RequireJS() { this = "requirejs" }
override string getAnAlias() { result = "require.js" }
@@ -917,7 +932,7 @@ private class ApplicationInsightsInstance extends FrameworkLibraryInstance {
this.(TopLevel)
.getFile()
.getAbsolutePath()
.regexpCapture(any(ApplicationInsights t).getAURLRegex(), 1)
.regexpCapture(any(ApplicationInsights t).getAUrlRegex(), 1)
}
override predicate info(FrameworkLibrary fl, string v) {
@@ -929,16 +944,19 @@ private class ApplicationInsightsInstance extends FrameworkLibraryInstance {
/**
* The Microsoft ApplicationInsights framework.
*/
private class ApplicationInsights extends FrameworkLibraryWithURLRegex {
private class ApplicationInsights extends FrameworkLibraryWithUrlRegex {
ApplicationInsights() { this = "ApplicationInsights" }
override string getAURLRegex() { result = ".*(?:^|/)ai\\.(" + semverRegex() + ")-build\\d+\\.js" }
override string getAUrlRegex() { result = ".*(?:^|/)ai\\.(" + semverRegex() + ")-build\\d+\\.js" }
/** DEPRECATED: Alias for getAUrlRegex */
deprecated override string getAURLRegex() { result = this.getAUrlRegex() }
}
/**
* The twitter-text framework.
*/
private class TwitterText extends FrameworkLibraryWithGenericURL, FrameworkLibraryWithMarkerComment {
private class TwitterText extends FrameworkLibraryWithGenericUrl, FrameworkLibraryWithMarkerComment {
TwitterText() { this = "twitter-text" }
override string getAMarkerCommentRegex() { result = "(?s).*twitter-text\\s*(<VERSION>).*" }
@@ -947,10 +965,13 @@ private class TwitterText extends FrameworkLibraryWithGenericURL, FrameworkLibra
/**
* The classic version of twitter-text, as seen in the wild.
*/
private class TwitterTextClassic extends FrameworkLibraryWithURLRegex {
private class TwitterTextClassic extends FrameworkLibraryWithUrlRegex {
TwitterTextClassic() { this = "twitter-text" }
override string getAURLRegex() { result = ".*(?:^|/)twitter_text" + variantRegex() + "\\.js" }
override string getAUrlRegex() { result = ".*(?:^|/)twitter_text" + variantRegex() + "\\.js" }
/** DEPRECATED: Alias for getAUrlRegex */
deprecated override string getAURLRegex() { result = this.getAUrlRegex() }
}
/**
@@ -961,7 +982,7 @@ private class TwitterTextClassicInstance extends FrameworkLibraryInstance {
this.(TopLevel)
.getFile()
.getAbsolutePath()
.regexpMatch(any(TwitterTextClassic t).getAURLRegex())
.regexpMatch(any(TwitterTextClassic t).getAUrlRegex())
}
override predicate info(FrameworkLibrary fl, string v) {

View File

@@ -16,9 +16,7 @@
import javascript
private class BackwardExploringConfiguration extends DataFlow::Configuration {
DataFlow::Configuration cfg;
BackwardExploringConfiguration() { this = cfg }
BackwardExploringConfiguration() { this = any(DataFlow::Configuration cfg) }
override predicate isSource(DataFlow::Node node) { any() }

View File

@@ -14,9 +14,7 @@
import javascript
private class ForwardExploringConfiguration extends DataFlow::Configuration {
DataFlow::Configuration cfg;
ForwardExploringConfiguration() { this = cfg }
ForwardExploringConfiguration() { this = any(DataFlow::Configuration cfg) }
override predicate isSink(DataFlow::Node node) { any() }

View File

@@ -149,12 +149,10 @@ DataFlow::CallNode moduleRef(AngularModule m) {
* A call to a method from the `angular.Module` API.
*/
class ModuleApiCall extends DataFlow::CallNode {
/** The module on which the method is called. */
AngularModule mod;
/** The name of the called method. */
string methodName;
ModuleApiCall() { this = moduleRef(mod).getAMethodCall(methodName) }
ModuleApiCall() { this = moduleRef(_).getAMethodCall(methodName) }
/**
* Gets the name of the invoked method.

View File

@@ -65,10 +65,9 @@ private string getInterpolatedExpressionPattern() { result = "(?<=\\{\\{).*?(?=\
*/
private class HtmlTextNodeAsNgSourceProvider extends NgSourceProvider, HTML::TextNode {
string source;
int offset;
HtmlTextNodeAsNgSourceProvider() {
source = this.getText().regexpFind(getInterpolatedExpressionPattern(), _, offset)
source = this.getText().regexpFind(getInterpolatedExpressionPattern(), _, _)
}
override predicate providesSourceAt(

View File

@@ -46,23 +46,23 @@ abstract class InjectableFunction extends DataFlow::ValueNode {
/**
* Gets the `i`th dependency declaration, which is also named `name`.
*/
abstract ASTNode getDependencyDeclaration(int i, string name);
abstract AstNode getDependencyDeclaration(int i, string name);
/**
* Gets an ASTNode for the `name` dependency declaration.
*/
ASTNode getADependencyDeclaration(string name) { result = getDependencyDeclaration(_, name) }
AstNode getADependencyDeclaration(string name) { result = getDependencyDeclaration(_, name) }
/**
* Gets the ASTNode for the `i`th dependency declaration.
*/
ASTNode getDependencyDeclaration(int i) { result = getDependencyDeclaration(i, _) }
AstNode getDependencyDeclaration(int i) { result = getDependencyDeclaration(i, _) }
/** Gets the function underlying this injectable function. */
abstract Function asFunction();
/** Gets a location where this function is explicitly dependency injected. */
abstract ASTNode getAnExplicitDependencyInjection();
abstract AstNode getAnExplicitDependencyInjection();
/**
* Gets a service corresponding to the dependency-injected `parameter`.
@@ -110,7 +110,7 @@ private class FunctionWithImplicitDependencyAnnotation extends InjectableFunctio
override Function asFunction() { result = astNode }
override ASTNode getAnExplicitDependencyInjection() { none() }
override AstNode getAnExplicitDependencyInjection() { none() }
}
private DataFlow::PropWrite getAPropertyDependencyInjection(Function function) {
@@ -143,7 +143,7 @@ private class FunctionWithInjectProperty extends InjectableFunction {
exists(int i | exists(getDependencyDeclaration(i, name)) | result = astNode.getParameter(i))
}
override ASTNode getDependencyDeclaration(int i, string name) {
override AstNode getDependencyDeclaration(int i, string name) {
exists(DataFlow::ValueNode decl |
decl = dependencies.getElement(i) and
decl.mayHaveStringValue(name) and
@@ -153,7 +153,7 @@ private class FunctionWithInjectProperty extends InjectableFunction {
override Function asFunction() { result = astNode }
override ASTNode getAnExplicitDependencyInjection() {
override AstNode getAnExplicitDependencyInjection() {
result = getAPropertyDependencyInjection(astNode).getAstNode()
}
}
@@ -176,14 +176,14 @@ private class FunctionWithExplicitDependencyAnnotation extends InjectableFunctio
)
}
override ASTNode getDependencyDeclaration(int i, string name) {
override AstNode getDependencyDeclaration(int i, string name) {
result = astNode.getElement(i) and
result.(Expr).mayHaveStringValue(name)
}
override Function asFunction() { result = function.getAstNode() }
override ASTNode getAnExplicitDependencyInjection() {
override AstNode getAnExplicitDependencyInjection() {
result = astNode or
result = function.(InjectableFunction).getAnExplicitDependencyInjection()
}

View File

@@ -9,18 +9,18 @@ module Babel {
* A Babel configuration object, either from `package.json` or from a
* `.babelrc` file.
*/
class Config extends JSONObject {
class Config extends JsonObject {
Config() {
isTopLevel() and getJsonFile().getBaseName().matches(".babelrc%")
or
this = any(PackageJSON pkg).getPropValue("babel")
this = any(PackageJson pkg).getPropValue("babel")
}
/**
* Gets the configuration for the plugin with the given name.
*/
JSONValue getPluginConfig(string pluginName) {
exists(JSONArray plugins |
JsonValue getPluginConfig(string pluginName) {
exists(JsonArray plugins |
plugins = getPropValue("plugins") and
result = plugins.getElementValue(_)
|
@@ -38,7 +38,7 @@ module Babel {
or
result = getAContainerInScope().getAChildContainer() and
// File-relative .babelrc search stops at any package.json or .babelrc file.
not result.getAChildContainer() = any(PackageJSON pkg).getJsonFile() and
not result.getAChildContainer() = any(PackageJson pkg).getJsonFile() and
not result.getAChildContainer() = any(Config pkg).getJsonFile()
}
@@ -51,7 +51,7 @@ module Babel {
/**
* A configuration object for a Babel plugin.
*/
class Plugin extends JSONValue {
class Plugin extends JsonValue {
Config cfg;
string pluginName;
@@ -64,10 +64,10 @@ module Babel {
Config getConfig() { result = cfg }
/** Gets the options value passed to the plugin, if any. */
JSONValue getOptions() { result = this.(JSONArray).getElementValue(1) }
JsonValue getOptions() { result = this.(JsonArray).getElementValue(1) }
/** Gets a named option from the option object, if present. */
JSONValue getOption(string name) { result = getOptions().getPropValue(name) }
JsonValue getOption(string name) { result = getOptions().getPropValue(name) }
/** Holds if this plugin applies to `tl`. */
predicate appliesTo(TopLevel tl) { cfg.appliesTo(tl) }
@@ -99,12 +99,12 @@ module Babel {
/**
* Gets an object specifying a root prefix.
*/
private JSONObject getARootPathSpec() {
private JsonObject getARootPathSpec() {
// ["babel-plugin-root-import", <spec>]
result = getOptions() and
exists(result.getPropValue("rootPathSuffix"))
or
exists(JSONArray pathSpecs |
exists(JsonArray pathSpecs |
// ["babel-plugin-root-import", [ <spec>... ] ]
pathSpecs = getOptions()
or
@@ -119,7 +119,7 @@ module Babel {
* Gets the (explicitly specified) root for the given prefix.
*/
private string getExplicitRoot(string prefix) {
exists(JSONObject rootPathSpec |
exists(JsonObject rootPathSpec |
rootPathSpec = getARootPathSpec() and
result = rootPathSpec.getPropStringValue("rootPathSuffix")
|
@@ -140,7 +140,6 @@ module Babel {
*/
private class BabelRootTransformedPathExpr extends PathExpr, Expr {
RootImportConfig plugin;
string rawPath;
string prefix;
string mappedPrefix;
string suffix;
@@ -148,9 +147,8 @@ module Babel {
BabelRootTransformedPathExpr() {
this instanceof PathExpr and
plugin.appliesTo(getTopLevel()) and
rawPath = getStringValue() and
prefix = rawPath.regexpCapture("(.)/(.*)", 1) and
suffix = rawPath.regexpCapture("(.)/(.*)", 2) and
prefix = getStringValue().regexpCapture("(.)/(.*)", 1) and
suffix = getStringValue().regexpCapture("(.)/(.*)", 2) and
mappedPrefix = plugin.getRoot(prefix)
}

View File

@@ -71,8 +71,6 @@ class ClientRequest extends DataFlow::InvokeNode instanceof ClientRequest::Range
DataFlow::Node getASavePath() { result = super.getASavePath() }
}
deprecated class CustomClientRequest = ClientRequest::Range;
module ClientRequest {
/**
* A call that performs a request to a URL.
@@ -548,8 +546,8 @@ module ClientRequest {
*
* Note: Prefer to use the `ClientRequest` class as it is more general.
*/
class XMLHttpRequest extends ClientRequest::Range {
XMLHttpRequest() {
class XmlHttpRequest extends ClientRequest::Range {
XmlHttpRequest() {
this = DataFlow::globalVarRef("XMLHttpRequest").getAnInstantiation()
or
// closure shim for XMLHttpRequest
@@ -620,6 +618,9 @@ module ClientRequest {
}
}
/** DEPRECATED: Alias for XmlHttpRequest */
deprecated class XMLHttpRequest = XmlHttpRequest;
/**
* A model of a URL request made using the `XhrIo` class from the closure library.
*/
@@ -790,8 +791,8 @@ module ClientRequest {
/**
* A model of a URL request made using `jsdom.fromUrl()`.
*/
class JSDOMFromUrl extends ClientRequest::Range {
JSDOMFromUrl() {
class JSDomFromUrl extends ClientRequest::Range {
JSDomFromUrl() {
this = API::moduleImport("jsdom").getMember("JSDOM").getMember("fromURL").getACall()
}
@@ -802,6 +803,9 @@ module ClientRequest {
override DataFlow::Node getADataNode() { none() }
}
/** DEPRECATED: Alias for JSDomFromUrl */
deprecated class JSDOMFromUrl = JSDomFromUrl;
/**
* Classes and predicates modeling the `apollo-client` library.
*/

View File

@@ -367,10 +367,10 @@ private module ExpressCookies {
* In case an array is passed `setHeader("Set-Cookie", [...]` it sets multiple cookies.
* We model a `CookieWrite` for each array element.
*/
private class HTTPCookieWrite extends CookieWrites::CookieWrite {
private class HttpCookieWrite extends CookieWrites::CookieWrite {
string header;
HTTPCookieWrite() {
HttpCookieWrite() {
exists(HTTP::CookieDefinition setCookie |
this.asExpr() = setCookie.getHeaderArgument() and
not this instanceof DataFlow::ArrayCreationNode

View File

@@ -378,10 +378,9 @@ private module CryptoJS {
* A model of the TweetNaCl library.
*/
private module TweetNaCl {
private class Apply extends CryptographicOperation {
private class Apply extends CryptographicOperation instanceof MethodCallExpr {
Expr input;
CryptographicAlgorithm algorithm;
MethodCallExpr mce;
Apply() {
/*
@@ -395,15 +394,14 @@ private module TweetNaCl {
* Also matches the "hash" method name, and the "nacl-fast" module.
*/
this = mce and
exists(DataFlow::SourceNode mod, string name |
name = "hash" and algorithm.matchesName("SHA512")
or
name = "sign" and algorithm.matchesName("ed25519")
|
(mod = DataFlow::moduleImport("nacl") or mod = DataFlow::moduleImport("nacl-fast")) and
mce = mod.getAMemberCall(name).asExpr() and
mce.getArgument(0) = input
this = mod.getAMemberCall(name).asExpr() and
super.getArgument(0) = input
)
}
@@ -440,10 +438,9 @@ private module HashJs {
)
}
private class Apply extends CryptographicOperation {
private class Apply extends CryptographicOperation instanceof MethodCallExpr {
Expr input;
CryptographicAlgorithm algorithm; // non-functional
MethodCallExpr mce;
Apply() {
/*
@@ -459,9 +456,8 @@ private module HashJs {
* Also matches where `hash.<algorithmName>()` has been replaced by a more specific require a la `require("hash.js/lib/hash/sha/512")`
*/
this = mce and
mce = getAlgorithmExpr(algorithm).getAMemberCall("update").asExpr() and
input = mce.getArgument(0)
this = getAlgorithmExpr(algorithm).getAMemberCall("update").asExpr() and
input = super.getArgument(0)
}
override Expr getInput() { result = input }
@@ -535,16 +531,14 @@ private module Forge {
override CryptographicAlgorithm getAlgorithm() { result = algorithm }
}
private class Apply extends CryptographicOperation {
private class Apply extends CryptographicOperation instanceof MethodCallExpr {
Expr input;
CryptographicAlgorithm algorithm; // non-functional
MethodCallExpr mce;
Apply() {
this = mce and
exists(Cipher cipher |
mce = cipher.getAMemberCall("update").asExpr() and
mce.getArgument(0) = input and
this = cipher.getAMemberCall("update").asExpr() and
super.getArgument(0) = input and
algorithm = cipher.getAlgorithm()
)
}
@@ -596,19 +590,17 @@ private module Forge {
* A model of the md5 library.
*/
private module Md5 {
private class Apply extends CryptographicOperation {
private class Apply extends CryptographicOperation instanceof CallExpr {
Expr input;
CryptographicAlgorithm algorithm;
CallExpr call;
Apply() {
// `require("md5")("message");`
this = call and
exists(DataFlow::SourceNode mod |
mod = DataFlow::moduleImport("md5") and
algorithm.matchesName("MD5") and
call = mod.getACall().asExpr() and
call.getArgument(0) = input
this = mod.getACall().asExpr() and
super.getArgument(0) = input
)
}
@@ -622,14 +614,12 @@ private module Md5 {
* A model of the bcrypt, bcryptjs, bcrypt-nodejs libraries.
*/
private module Bcrypt {
private class Apply extends CryptographicOperation {
private class Apply extends CryptographicOperation instanceof MethodCallExpr {
Expr input;
CryptographicAlgorithm algorithm;
MethodCallExpr mce;
Apply() {
// `require("bcrypt").hash(password);` with minor naming variations
this = mce and
exists(DataFlow::SourceNode mod, string moduleName, string methodName |
algorithm.matchesName("BCRYPT") and
(
@@ -642,8 +632,8 @@ private module Bcrypt {
methodName = "hashSync"
) and
mod = DataFlow::moduleImport(moduleName) and
mce = mod.getAMemberCall(methodName).asExpr() and
mce.getArgument(0) = input
this = mod.getAMemberCall(methodName).asExpr() and
super.getArgument(0) = input
)
}
@@ -657,20 +647,18 @@ private module Bcrypt {
* A model of the hasha library.
*/
private module Hasha {
private class Apply extends CryptographicOperation {
private class Apply extends CryptographicOperation instanceof CallExpr {
Expr input;
CryptographicAlgorithm algorithm;
CallExpr call;
Apply() {
// `require('hasha')('unicorn', { algorithm: "md5" });`
this = call and
exists(DataFlow::SourceNode mod, string algorithmName, Expr algorithmNameNode |
mod = DataFlow::moduleImport("hasha") and
call = mod.getACall().asExpr() and
call.getArgument(0) = input and
this = mod.getACall().asExpr() and
super.getArgument(0) = input and
algorithm.matchesName(algorithmName) and
call.hasOptionArgument(1, "algorithm", algorithmNameNode) and
super.hasOptionArgument(1, "algorithm", algorithmNameNode) and
algorithmNameNode.mayHaveStringValue(algorithmName)
)
}

View File

@@ -189,8 +189,6 @@ module Electron {
abstract class Range extends NodeJSLib::NodeJSClientRequest::Range { }
}
deprecated class CustomElectronClientRequest = ElectronClientRequest::Range;
/**
* A Node.js-style HTTP or HTTPS request made using `electron.ClientRequest`.
*/

View File

@@ -212,12 +212,12 @@ private class RecursiveReadDir extends FileSystemAccess, FileNameProducer, API::
/**
* Classes and predicates for modeling the `jsonfile` library (https://www.npmjs.com/package/jsonfile).
*/
private module JSONFile {
private module JsonFile {
/**
* A reader for JSON files.
*/
class JSONFileReader extends FileSystemReadAccess, API::CallNode {
JSONFileReader() {
class JsonFileReader extends FileSystemReadAccess, API::CallNode {
JsonFileReader() {
this = API::moduleImport("jsonfile").getMember(["readFile", "readFileSync"]).getACall()
}
@@ -238,11 +238,14 @@ private module JSONFile {
}
}
/** DEPRECATED: Alias for JsonFileReader */
deprecated class JSONFileReader = JsonFileReader;
/**
* A writer for JSON files.
*/
class JSONFileWriter extends FileSystemWriteAccess, DataFlow::CallNode {
JSONFileWriter() {
class JsonFileWriter extends FileSystemWriteAccess, DataFlow::CallNode {
JsonFileWriter() {
this =
DataFlow::moduleMember("jsonfile", any(string s | s = "writeFile" or s = "writeFileSync"))
.getACall()
@@ -252,6 +255,9 @@ private module JSONFile {
override DataFlow::Node getADataNode() { result = this.getArgument(1) }
}
/** DEPRECATED: Alias for JsonFileWriter */
deprecated class JSONFileWriter = JsonFileWriter;
}
/**

View File

@@ -104,13 +104,6 @@ module HTTP {
predicate isUnsafe() { not this.isSafe() }
}
/**
* DEPRECATED: Use `http` or `https` directly as appropriate.
*
* Gets the string `http` or `https`.
*/
deprecated string httpOrHttps() { result = "http" or result = "https" }
/**
* An expression whose value is sent as (part of) the body of an HTTP response.
*/
@@ -411,10 +404,10 @@ module HTTP {
* E.g. `chunk` in: `http.createServer().on('request', (req, res) => req.on("data", (chunk) => ...))`.
*/
private class ServerRequestDataEvent extends RemoteFlowSource, DataFlow::ParameterNode {
RequestSource req;
ServerRequestDataEvent() {
exists(DataFlow::MethodCallNode mcn | mcn = req.ref().getAMethodCall(EventEmitter::on()) |
exists(DataFlow::MethodCallNode mcn, RequestSource req |
mcn = req.ref().getAMethodCall(EventEmitter::on())
|
mcn.getArgument(0).mayHaveStringValue("data") and
this = mcn.getABoundCallbackParameter(1, 0)
)

View File

@@ -74,12 +74,13 @@ private module HttpProxy {
*/
class ProxyListenerCallback extends NodeJSLib::RouteHandler, DataFlow::FunctionNode {
string event;
API::CallNode call;
ProxyListenerCallback() {
call = any(CreateServerCall server).getReturn().getMember(["on", "once"]).getACall() and
call.getParameter(0).getARhs().mayHaveStringValue(event) and
this = call.getParameter(1).getARhs().getAFunctionValue()
exists(API::CallNode call |
call = any(CreateServerCall server).getReturn().getMember(["on", "once"]).getACall() and
call.getParameter(0).getARhs().mayHaveStringValue(event) and
this = call.getParameter(1).getARhs().getAFunctionValue()
)
}
override Parameter getRequestParameter() {

View File

@@ -42,8 +42,8 @@ private module JsonWebToken {
/**
* The private key for a JWT as a `CredentialsExpr`.
*/
private class JWTKey extends CredentialsExpr {
JWTKey() {
private class JwtKey extends CredentialsExpr {
JwtKey() {
this = DataFlow::moduleMember("jsonwebtoken", "sign").getACall().getArgument(1).asExpr()
}

View File

@@ -5,22 +5,6 @@
import javascript
module LazyCache {
/**
* DEPRECATED. DO NOT USE.
*
* A lazy-cache object, usually created through an expression of form `require('lazy-cache')(require)`.
*/
deprecated class LazyCacheObject extends DataFlow::SourceNode {
LazyCacheObject() {
// Use `require` directly instead of `moduleImport` to avoid recursion.
// For the same reason, avoid `Import.getImportedPath`.
exists(Require req |
req.getArgument(0).getStringValue() = "lazy-cache" and
this = req.flow().(DataFlow::SourceNode).getAnInvocation()
)
}
}
/**
* A variable containing a lazy-cache object.
*/

View File

@@ -29,9 +29,9 @@ module LdapJS {
/** A reference to a LDAPjs client `search` options. */
class SearchOptions extends API::Node {
ClientCall call;
SearchOptions() { call.getMethodName() = "search" and this = call.getParameter(1) }
SearchOptions() {
exists(ClientCall call | call.getMethodName() = "search" and this = call.getParameter(1))
}
}
/** A creation of an LDAPjs filter, or object containing a filter, that doesn't sanitizes the input. */

View File

@@ -123,7 +123,7 @@ private module Winston {
/**
* Provides classes for working with [log4js](https://github.com/log4js-node/log4js-node).
*/
private module log4js {
private module Log4js {
/**
* A call to the log4js logging mechanism.
*/

View File

@@ -21,7 +21,10 @@ module Markdown {
/**
* Holds if the taint-step preserves HTML.
*/
predicate preservesHTML() { any() }
predicate preservesHtml() { any() }
/** DEPRECATED: Alias for preservesHtml */
deprecated predicate preservesHTML() { this.preservesHtml() }
}
private class MarkdownStepAsTaintStep extends TaintTracking::SharedTaintStep {

View File

@@ -376,11 +376,11 @@ module NestJS {
* redirects to `https://example.com`.
*/
private class ReturnValueAsRedirection extends ServerSideUrlRedirect::Sink {
NestJSRouteHandler handler;
ReturnValueAsRedirection() {
handler.hasRedirectDecorator() and
this = handler.getAReturn().getALocalSource().getAPropertyWrite("url").getRhs()
exists(NestJSRouteHandler handler |
handler.hasRedirectDecorator() and
this = handler.getAReturn().getALocalSource().getAPropertyWrite("url").getRhs()
)
}
}

View File

@@ -11,7 +11,7 @@ module NextJS {
/**
* Gets a `package.json` that depends on the `Next.js` library.
*/
PackageJSON getANextPackage() { result.getDependencies().getADependency("next", _) }
PackageJson getANextPackage() { result.getDependencies().getADependency("next", _) }
/**
* Gets a "pages" folder in a `Next.js` application.
@@ -155,11 +155,7 @@ module NextJS {
* A Next.js function that is exected on the server for every request, seen as a routehandler.
*/
class NextHttpRouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode {
Module pageModule;
NextHttpRouteHandler() {
this = getServerSidePropsFunction(pageModule) or this = getInitialProps(pageModule)
}
NextHttpRouteHandler() { this = getServerSidePropsFunction(_) or this = getInitialProps(_) }
}
/**
@@ -199,9 +195,9 @@ module NextJS {
* The response (res) includes a set of Express.js-like methods,
* and we therefore model the routehandler as an Express.js routehandler.
*/
class NextAPIRouteHandler extends DataFlow::FunctionNode, Express::RouteHandler,
class NextApiRouteHandler extends DataFlow::FunctionNode, Express::RouteHandler,
HTTP::Servers::StandardRouteHandler {
NextAPIRouteHandler() {
NextApiRouteHandler() {
exists(Module mod | mod.getFile().getParentContainer() = apiFolder() |
this = mod.getAnExportedValue("default").getAFunctionValue()
)
@@ -214,6 +210,9 @@ module NextJS {
}
}
/** DEPRECATED: Alias for NextApiRouteHandler */
deprecated class NextAPIRouteHandler = NextApiRouteHandler;
/**
* Gets a reference to a [Next.js router](https://nextjs.org/docs/api-reference/next/router).
*/

View File

@@ -5,7 +5,8 @@
import javascript
import semmle.javascript.Promises
module NoSQL {
/** Provices classes for modelling NoSQL query sinks. */
module NoSql {
/** 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. */
@@ -13,6 +14,9 @@ module NoSQL {
}
}
/** DEPRECATED: Alias for NoSql */
deprecated module NoSQL = NoSql;
/**
* Gets a value that has been assigned to the "$where" property of an object that flows to `queryArg`.
*/
@@ -78,7 +82,7 @@ private module MongoDB {
/**
* An expression that is interpreted as a MongoDB query.
*/
class Query extends NoSQL::Query {
class Query extends NoSql::Query {
QueryCall qc;
Query() { this = qc.getAQueryArgument().asExpr() }
@@ -512,7 +516,7 @@ private module Mongoose {
/**
* An expression that is interpreted as a (part of a) MongoDB query.
*/
class MongoDBQueryPart extends NoSQL::Query {
class MongoDBQueryPart extends NoSql::Query {
MongooseFunction f;
MongoDBQueryPart() { this = f.getQueryArgument().getARhs().asExpr() }
@@ -619,7 +623,7 @@ private module Minimongo {
/**
* An expression that is interpreted as a Minimongo query.
*/
class Query extends NoSQL::Query {
class Query extends NoSql::Query {
QueryCall qc;
Query() { this = qc.getAQueryArgument().asExpr() }
@@ -679,7 +683,7 @@ private module MarsDB {
/**
* An expression that is interpreted as a MarsDB query.
*/
class Query extends NoSQL::Query {
class Query extends NoSql::Query {
QueryCall qc;
Query() { this = qc.getAQueryArgument().asExpr() }
@@ -763,7 +767,7 @@ private module Redis {
/**
* An expression that is interpreted as a key in a Node Redis call.
*/
class RedisKeyArgument extends NoSQL::Query {
class RedisKeyArgument extends NoSql::Query {
RedisKeyArgument() {
exists(string method, int argIndex |
QuerySignatures::argumentIsAmbiguousKey(method, argIndex) and

View File

@@ -801,11 +801,6 @@ module NodeJSLib {
TrackedRouteHandlerCandidateWithSetup() { this = any(RouteSetup s).getARouteHandler() }
}
/**
* DEPRECATED Use `VmModuleMemberInvocation` instead.
*/
deprecated class VmModuleMethodCall = VmModuleMemberInvocation;
/**
* An invocation of a member from module `vm`
*/
@@ -864,8 +859,6 @@ module NodeJSLib {
abstract class Range extends ClientRequest::Range { }
}
deprecated class CustomNodeJSClientRequest = NodeJSClientRequest::Range;
/**
* A model of a URL request in the Node.js `http` library.
*/
@@ -1171,17 +1164,17 @@ module NodeJSLib {
* A connection opened on a NodeJS net server.
*/
private class NodeJSNetServerConnection extends EventEmitter::Range {
NodeJSNetServer server;
NodeJSNetServerConnection() {
exists(DataFlow::MethodCallNode call |
call = server.ref().getAMethodCall("on") and
call.getArgument(0).mayHaveStringValue("connection")
|
this = call.getCallback(1).getParameter(0)
exists(NodeJSNetServer server |
exists(DataFlow::MethodCallNode call |
call = server.ref().getAMethodCall("on") and
call.getArgument(0).mayHaveStringValue("connection")
|
this = call.getCallback(1).getParameter(0)
)
or
this = server.getCallback([0, 1]).getParameter(0)
)
or
this = server.getCallback([0, 1]).getParameter(0)
}
DataFlow::SourceNode ref() { result = EventEmitter::trackEventEmitter(this) }
@@ -1201,9 +1194,9 @@ module NodeJSLib {
* A data flow node representing data received from a client to a NodeJS net server, viewed as remote user input.
*/
private class NodeJSNetServerItemAsRemoteFlow extends RemoteFlowSource {
NodeJSNetServerRegistration reg;
NodeJSNetServerItemAsRemoteFlow() { this = reg.getReceivedItem(_) }
NodeJSNetServerItemAsRemoteFlow() {
this = any(NodeJSNetServerRegistration reg).getReceivedItem(_)
}
override string getSourceType() { result = "NodeJS server" }
}

View File

@@ -59,8 +59,6 @@ module PropertyProjection {
}
}
deprecated class CustomPropertyProjection = PropertyProjection::Range;
/**
* Gets a callee of a simple property projection call.
* This predicate is used exclusively in `SimplePropertyProjection`.

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