Merge branch 'main' into actiondispatch-response

This commit is contained in:
Arthur Baars
2022-10-17 13:22:17 +02:00
committed by GitHub
139 changed files with 1332 additions and 183 deletions

View File

@@ -241,7 +241,7 @@ private Instruction getANonConversionUse(Operand operand) {
/**
* Gets the operand that represents the first use of the value of `call` following
* a sequnce of conversion-like instructions.
* a sequence of conversion-like instructions.
*/
predicate operandForfullyConvertedCall(Operand operand, CallInstruction call) {
exists(getANonConversionUse(operand)) and
@@ -254,7 +254,7 @@ predicate operandForfullyConvertedCall(Operand operand, CallInstruction call) {
/**
* Gets the instruction that represents the first use of the value of `call` following
* a sequnce of conversion-like instructions.
* a sequence of conversion-like instructions.
*
* This predicate only holds if there is no suitable operand (i.e., no operand of a non-
* conversion instruction) to use to represent the value of `call` after conversions.

View File

@@ -746,7 +746,7 @@ predicate exprNodeShouldBeOperand(Node node, Expr e) {
/**
* Holds if `load` is a `LoadInstruction` that is the result of evaluating `e`
* and `node` is an `IndirctOperandNode` that should map `node.asExpr()` to `e`.
* and `node` is an `IndirectOperandNode` that should map `node.asExpr()` to `e`.
*
* We map `e` to `node.asExpr()` when `node` semantically represents the
* same value as `load`. A subsequent flow step will flow `node` to

View File

@@ -100,7 +100,7 @@ private string getNodeProperty(DataFlow::Node node, string key) {
or
// Is there partial flow from a source to this node?
// This property will only be emitted if partial flow is enabled by overriding
// `DataFlow::Configration::explorationLimit()`.
// `DataFlow::Configuration::explorationLimit()`.
key = "pflow" and
result =
strictconcat(DataFlow::PartialPathNode sourceNode, DataFlow::PartialPathNode destNode, int dist,

View File

@@ -71,7 +71,7 @@ abstract class CustomSignDef extends SignDef {
* Concrete implementations extend one of the following subclasses:
* - `ConstantSignExpr`, for expressions with a compile-time constant value.
* - `FlowSignExpr`, for expressions whose sign can be computed from the signs of their operands.
* - `CustomsignExpr`, for expressions shose sign can be computed by a language-specific
* - `CustomsignExpr`, for expressions whose sign can be computed by a language-specific
* implementation.
*
* If the same expression matches more than one of the above subclasses, the sign is computed as

View File

@@ -11,7 +11,7 @@ private import experimental.semmle.code.cpp.semantic.Semantic
predicate ignoreTypeRestrictions(SemExpr e) { none() }
/**
* Workaround to track the sign of cetain expressions even if the type of the expression is not
* Workaround to track the sign of certain expressions even if the type of the expression is not
* numeric.
*/
predicate trackUnknownNonNumericExpr(SemExpr e) { none() }

View File

@@ -1,5 +1,5 @@
/**
* Proivdes the `LinkTarget` class representing linker invocations during the build process.
* Provides the `LinkTarget` class representing linker invocations during the build process.
*/
import semmle.code.cpp.Class

View File

@@ -144,7 +144,7 @@ class Variable extends Declaration, @variable {
* `Variable.getInitializer()` to get the variable's initializer,
* or use `Variable.getAnAssignedValue()` to get an expression that
* is the right-hand side of an assignment or an initialization of
* the varible.
* the variable.
*/
Assignment getAnAssignment() { result.getLValue() = this.getAnAccess() }
@@ -173,7 +173,7 @@ class Variable extends Declaration, @variable {
}
/**
* Holds if this variable is declated as part of a structured binding
* Holds if this variable is declared as part of a structured binding
* declaration. For example, `x` in `auto [x, y] = ...`.
*/
predicate isStructuredBinding() { is_structured_binding(underlyingElement(this)) }

View File

@@ -76,7 +76,7 @@ class TypeBoundsAnalysis extends BufferWriteEstimationReason, TTypeBoundsAnalysi
/**
* The estimation comes from non trivial bounds found via actual flow analysis,
* but a widening aproximation might have been used for variables in loops.
* but a widening approximation might have been used for variables in loops.
* For example
* ```
* for (int i = 0; i < 10; ++i) {
@@ -141,7 +141,7 @@ class AttributeFormattingFunction extends FormattingFunction {
* - `""` is a `vprintf` variant, `outputParamIndex` is `-1`.
* - `"f"` is a `vfprintf` variant, `outputParamIndex` indicates the output stream parameter.
* - `"s"` is a `vsprintf` variant, `outputParamIndex` indicates the output buffer parameter.
* - `"?"` if the type cannot be deteremined. `outputParamIndex` is `-1`.
* - `"?"` if the type cannot be determined. `outputParamIndex` is `-1`.
*/
predicate primitiveVariadicFormatter(
TopLevelFunction f, string type, int formatParamIndex, int outputParamIndex
@@ -198,7 +198,7 @@ private predicate callsVariadicFormatter(
* - `""` is a `vprintf` variant, `outputParamIndex` is `-1`.
* - `"f"` is a `vfprintf` variant, `outputParamIndex` indicates the output stream parameter.
* - `"s"` is a `vsprintf` variant, `outputParamIndex` indicates the output buffer parameter.
* - `"?"` if the type cannot be deteremined. `outputParamIndex` is `-1`.
* - `"?"` if the type cannot be determined. `outputParamIndex` is `-1`.
*/
predicate variadicFormatter(Function f, string type, int formatParamIndex, int outputParamIndex) {
primitiveVariadicFormatter(f, type, formatParamIndex, outputParamIndex)

View File

@@ -12,7 +12,7 @@ private import internal.ConstantExprs
* relation). The refinement manifests itself in two changes:
*
* - The successor relation on `BasicBlock`s uses `successors_adapted`
* (instead of `successors_extended` used by `PrimtiveBasicBlock`s). Consequently,
* (instead of `successors_extended` used by `PrimitiveBasicBlock`s). Consequently,
* some edges between `BasicBlock`s may be removed. Example:
* ```
* x = 1; // s1

View File

@@ -149,7 +149,7 @@ private predicate bbLoopEntryConditionAlwaysTrueAt(BasicBlock bb, int i, Control
/**
* Basic block `pred` contains all or part of the condition belonging to a loop,
* and there is an edge from `pred` to `succ` that concludes the condition.
* If the edge corrseponds with the loop condition being found to be `true`, then
* If the edge corresponds with the loop condition being found to be `true`, then
* `skipsLoop` is `false`. Otherwise the edge corresponds with the loop condition
* being found to be `false` and `skipsLoop` is `true`. Non-concluding edges
* within a complex loop condition are not matched by this predicate.

View File

@@ -1137,7 +1137,7 @@ class BuiltInOperationIsArray extends BuiltInOperation, @isarray {
* A C++ `__array_rank` built-in operation (used by some implementations of the
* `<type_traits>` header).
*
* If known, returns the number of dimentsions of an arrary type.
* If known, returns the number of dimensions of an arrary type.
* ```
* template<typename _Tp>
* struct rank

View File

@@ -494,7 +494,7 @@ class VacuousDestructorCall extends Expr, @vacuous_destructor_call {
* An initialization of a base class or member variable performed as part
* of a constructor's explicit initializer list or implicit actions.
*
* This is a QL root class for reprenting various types of constructor
* This is a QL root class for representing various types of constructor
* initializations.
*/
class ConstructorInit extends Expr, @ctorinit {

View File

@@ -779,7 +779,7 @@ class AlignofExprOperator extends AlignofOperator {
/**
* A C++11 `alignof` expression whose operand is a type name.
* ```
* bool proper_alignment = (alingof(T) == alignof(T[0]);
* bool proper_alignment = (alignof(T) == alignof(T[0]);
* ```
*/
class AlignofTypeOperator extends AlignofOperator {

View File

@@ -451,7 +451,7 @@ class Expr extends StmtParent, @expr {
// For performance, we avoid a full transitive closure over `getConversion`.
// Since there can be several implicit conversions before and after an
// explicit conversion, use `getImplicitlyConverted` to step over them
// cheaply. Then, if there is an explicit conversion following the implict
// cheaply. Then, if there is an explicit conversion following the implicit
// conversion sequence, recurse to handle multiple explicit conversions.
if this.getImplicitlyConverted().hasExplicitConversion()
then result = this.getImplicitlyConverted().getConversion().getExplicitlyConverted()

View File

@@ -100,7 +100,7 @@ private string getNodeProperty(DataFlow::Node node, string key) {
or
// Is there partial flow from a source to this node?
// This property will only be emitted if partial flow is enabled by overriding
// `DataFlow::Configration::explorationLimit()`.
// `DataFlow::Configuration::explorationLimit()`.
key = "pflow" and
result =
strictconcat(DataFlow::PartialPathNode sourceNode, DataFlow::PartialPathNode destNode, int dist,

View File

@@ -742,7 +742,7 @@ class NoOpInstruction extends Instruction {
* The `ReturnInstruction` for a function will have a control-flow successor edge to a block
* containing the `ExitFunction` instruction for that function.
*
* There are two differet return instructions: `ReturnValueInstruction`, for returning a value from
* There are two different return instructions: `ReturnValueInstruction`, for returning a value from
* a non-`void`-returning function, and `ReturnVoidInstruction`, for returning from a
* `void`-returning function.
*/
@@ -1331,7 +1331,7 @@ class CheckedConvertOrThrowInstruction extends UnaryInstruction {
*
* If the operand holds a null address, the result is a null address.
*
* This instruction is used to represent `dyanmic_cast<void*>` in C++, which returns the pointer to
* This instruction is used to represent `dynamic_cast<void*>` in C++, which returns the pointer to
* the most-derived object.
*/
class CompleteObjectAddressInstruction extends UnaryInstruction {

View File

@@ -64,7 +64,7 @@ private module Cached {
or
instr = reusedPhiInstruction(_) and
// Check that the phi instruction is *not* degenerate, but we can't use
// getDegeneratePhiOperand in the first stage with phi instyructions
// getDegeneratePhiOperand in the first stage with phi instructions
not exists(
unique(OldIR::PhiInputOperand operand |
operand = instr.(OldIR::PhiInstruction).getAnInputOperand() and
@@ -718,7 +718,7 @@ module DefUse {
}
/**
* Gets the rank index of a hyphothetical use one instruction past the end of
* Gets the rank index of a hypothetical use one instruction past the end of
* the block. This index can be used to determine if a definition reaches the
* end of the block, even if the definition is the last instruction in the
* block.

View File

@@ -172,7 +172,7 @@ deprecated module UnaliasedSSAOperands = UnaliasedSsaOperands;
/**
* Provides wrappers for the constructors of each branch of `TOperand` that is used by the
* asliased SSA stage.
* aliased SSA stage.
* These wrappers are not parameterized because it is not possible to invoke an IPA constructor via
* a class alias.
*/

View File

@@ -742,7 +742,7 @@ class NoOpInstruction extends Instruction {
* The `ReturnInstruction` for a function will have a control-flow successor edge to a block
* containing the `ExitFunction` instruction for that function.
*
* There are two differet return instructions: `ReturnValueInstruction`, for returning a value from
* There are two different return instructions: `ReturnValueInstruction`, for returning a value from
* a non-`void`-returning function, and `ReturnVoidInstruction`, for returning from a
* `void`-returning function.
*/
@@ -1331,7 +1331,7 @@ class CheckedConvertOrThrowInstruction extends UnaryInstruction {
*
* If the operand holds a null address, the result is a null address.
*
* This instruction is used to represent `dyanmic_cast<void*>` in C++, which returns the pointer to
* This instruction is used to represent `dynamic_cast<void*>` in C++, which returns the pointer to
* the most-derived object.
*/
class CompleteObjectAddressInstruction extends UnaryInstruction {

View File

@@ -542,7 +542,7 @@ class TranslatedArgumentExprSideEffect extends TranslatedArgumentSideEffect,
* The IR translation of an argument side effect for `*this` on a call, where there is no `Expr`
* object that represents the `this` argument.
*
* The applies only to constructor calls, as the AST has explioit qualifier `Expr`s for all other
* The applies only to constructor calls, as the AST has exploit qualifier `Expr`s for all other
* calls to non-static member functions.
*/
class TranslatedStructorQualifierSideEffect extends TranslatedArgumentSideEffect,

View File

@@ -2177,7 +2177,7 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
/**
* The IR translation of the ternary conditional operator (`a ? b : c`).
* For this version, we expand the condition as a `TranslatedCondition`, rather than a
* `TranslatedExpr`, to simplify the control flow in the presence of short-ciruit logical operators.
* `TranslatedExpr`, to simplify the control flow in the presence of short-circuit logical operators.
*/
class TranslatedTernaryConditionalExpr extends TranslatedConditionalExpr, ConditionContext {
TranslatedTernaryConditionalExpr() { not expr.isTwoOperand() }

View File

@@ -742,7 +742,7 @@ class NoOpInstruction extends Instruction {
* The `ReturnInstruction` for a function will have a control-flow successor edge to a block
* containing the `ExitFunction` instruction for that function.
*
* There are two differet return instructions: `ReturnValueInstruction`, for returning a value from
* There are two different return instructions: `ReturnValueInstruction`, for returning a value from
* a non-`void`-returning function, and `ReturnVoidInstruction`, for returning from a
* `void`-returning function.
*/
@@ -1331,7 +1331,7 @@ class CheckedConvertOrThrowInstruction extends UnaryInstruction {
*
* If the operand holds a null address, the result is a null address.
*
* This instruction is used to represent `dyanmic_cast<void*>` in C++, which returns the pointer to
* This instruction is used to represent `dynamic_cast<void*>` in C++, which returns the pointer to
* the most-derived object.
*/
class CompleteObjectAddressInstruction extends UnaryInstruction {

View File

@@ -64,7 +64,7 @@ private module Cached {
or
instr = reusedPhiInstruction(_) and
// Check that the phi instruction is *not* degenerate, but we can't use
// getDegeneratePhiOperand in the first stage with phi instyructions
// getDegeneratePhiOperand in the first stage with phi instructions
not exists(
unique(OldIR::PhiInputOperand operand |
operand = instr.(OldIR::PhiInstruction).getAnInputOperand() and
@@ -718,7 +718,7 @@ module DefUse {
}
/**
* Gets the rank index of a hyphothetical use one instruction past the end of
* Gets the rank index of a hypothetical use one instruction past the end of
* the block. This index can be used to determine if a definition reaches the
* end of the block, even if the definition is the last instruction in the
* block.

View File

@@ -12,7 +12,7 @@ private Type getDecayedType(Type type) {
}
/**
* Holds if the sepcified variable is a structured binding with a non-reference
* Holds if the specified variable is a structured binding with a non-reference
* type.
*/
predicate isNonReferenceStructuredBinding(Variable v) {

View File

@@ -209,7 +209,7 @@ private predicate aClassFile(Class c, File file) { c.getDefinitionLocation().get
pragma[noopt]
private predicate dependsOnFileSimple(MetricFile source, MetricFile dest) {
// class derives from classs
// class derives from another class
exists(Class fromClass, Class toClass |
aClassFile(fromClass, source) and
fromClass.derivesFrom(toClass) and

View File

@@ -173,7 +173,7 @@ predicate eqOpWithSwapAndNegate(EqualityOperation cmp, Expr a, Expr b, boolean i
/**
* Holds if `cmp` is an unconverted conversion of `a` to a Boolean that
* evalutes to `isEQ` iff `a` is 0.
* evaluates to `isEQ` iff `a` is 0.
*
* Note that `a` can be `cmp` itself or a conversion thereof.
*/

View File

@@ -51,14 +51,14 @@ string getInsecureAlgorithmRegex() {
/**
* Holds if `name` looks like it might be related to operations with an
* insecure encyption algorithm.
* insecure encryption algorithm.
*/
bindingset[name]
predicate isInsecureEncryption(string name) { name.regexpMatch(getInsecureAlgorithmRegex()) }
/**
* Holds if there is additional evidence that `name` looks like it might be
* related to operations with an encyption algorithm, besides the name of a
* related to operations with an encryption algorithm, besides the name of a
* specific algorithm. This can be used in conjunction with
* `isInsecureEncryption` to produce a stronger heuristic.
*/

View File

@@ -1,7 +1,7 @@
/**
* DEPRECATED: we now use `semmle.code.cpp.ir.dataflow.DefaultTaintTracking`,
* which is based on the IR but designed to behave similarly to this old
* libarary.
* library.
*
* Provides the implementation of `semmle.code.cpp.security.TaintTracking`. Do
* not import this file directly.

View File

@@ -104,7 +104,7 @@ private newtype HC_Alloc =
HC_HasAlloc(HashCons hc) { mk_HasAlloc(hc, _) }
/**
* Used to implement optional extent expression on `new[]` exprtessions
* Used to implement optional extent expression on `new[]` expressions
*/
private newtype HC_Extent =
HC_NoExtent() or
@@ -116,7 +116,7 @@ private newtype HC_Args =
HC_ArgCons(HashCons hc, int i, HC_Args list) { mk_ArgCons(hc, i, list, _) }
/**
* Used to implement hash-consing of struct initizializers.
* Used to implement hash-consing of struct initializers.
*/
private newtype HC_Fields =
HC_EmptyFields(Class c) { exists(ClassAggregateLiteral cal | c = cal.getUnspecifiedType()) } or

View File

@@ -125,7 +125,7 @@
* The `security` tag has been added to the `cpp/return-stack-allocated-memory` query. As a result, its results will now appear by default.
* The "Uncontrolled data in arithmetic expression" (cpp/uncontrolled-arithmetic) query has been enhanced to reduce false positive results and its @precision increased to high.
* A new `cpp/very-likely-overruning-write` query has been added to the default query suite for C/C++. The query reports some results that were formerly flagged by `cpp/overruning-write`.
* A new `cpp/very-likely-overrunning-write` query has been added to the default query suite for C/C++. The query reports some results that were formerly flagged by `cpp/overrunning-write`.
### Minor Analysis Improvements

View File

@@ -63,7 +63,7 @@ predicate verifiedRealloc(FunctionCall reallocCall, Variable v, ControlFlowNode
node.(AnalysedExpr).getNonNullSuccessor(newV) = verified and
// note: this case uses naive flow logic (getAnAssignedValue).
// special case: if the result of the 'realloc' is assigned to the
// same variable, we don't descriminate properly between the old
// same variable, we don't discriminate properly between the old
// and the new allocation; better to not consider this a free at
// all in that case.
newV != v

View File

@@ -23,7 +23,7 @@ DoStmt getAFalseLoop() {
/**
* Gets a `do` ... `while` loop surrounding a statement. This is blocked by a
* `switch` statement, since a `continue` inside a `switch` inside a loop may be
* jusitifed (`continue` breaks out of the loop whereas `break` only escapes the
* justified (`continue` breaks out of the loop whereas `break` only escapes the
* `switch`).
*/
DoStmt enclosingLoop(Stmt s) {

View File

@@ -17,7 +17,7 @@ import cpp
/**
* It's common in some projects to use "a double negation" to normalize the boolean
* result to either 1 or 0.
* This predciate is intended to filter explicit usage of a double negation as it typically
* This predicate is intended to filter explicit usage of a double negation as it typically
* indicates the explicit purpose to normalize the result for bit-wise or arithmetic purposes.
*/
predicate doubleNegationNormalization(NotExpr notexpr) { notexpr.getAnOperand() instanceof NotExpr }

View File

@@ -3,7 +3,7 @@
* @name Untrusted network-to-host usage
* @description Using the result of a network-to-host byte order function, such as ntohl, as an
* array bound or length value without checking it may result in buffer overflows or
* other vulnerabilties.
* other vulnerabilities.
* @kind problem
* @problem.severity error
*/

View File

@@ -44,7 +44,7 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
// Holds if `sink` is a node that represents the `StoreInstruction` that is subsequently used in
// a `ReturnValueInstruction`.
// We use the `StoreInstruction` instead of the instruction that defines the
// `ReturnValueInstruction`'s source value oprand because the former has better location information.
// `ReturnValueInstruction`'s source value operand because the former has better location information.
exists(StoreInstruction store |
store.getDestinationAddress().(VariableAddressInstruction).getIRVariable() instanceof
IRReturnVariable and

View File

@@ -24,7 +24,7 @@ import semmle.code.cpp.valuenumbering.GlobalValueNumbering
* Holds if `call` is a call to `strncat` such that `sizeArg` and `destArg` are the size and
* destination arguments, respectively.
*/
predicate interestringCallWithArgs(Call call, Expr sizeArg, Expr destArg) {
predicate interestingCallWithArgs(Call call, Expr sizeArg, Expr destArg) {
exists(StrcatFunction strcat |
strcat = call.getTarget() and
sizeArg = call.getArgument(strcat.getParamSize()) and
@@ -37,7 +37,7 @@ predicate interestringCallWithArgs(Call call, Expr sizeArg, Expr destArg) {
* argument `destArg`, and `destArg` is the size of the buffer pointed to by `destArg`.
*/
predicate case1(FunctionCall fc, Expr sizeArg, VariableAccess destArg) {
interestringCallWithArgs(fc, sizeArg, destArg) and
interestingCallWithArgs(fc, sizeArg, destArg) and
exists(VariableAccess va |
va = sizeArg.(BufferSizeExpr).getArg() and
destArg.getTarget() = va.getTarget()
@@ -49,7 +49,7 @@ predicate case1(FunctionCall fc, Expr sizeArg, VariableAccess destArg) {
* argument `destArg`, and `sizeArg` computes the value `sizeof (dest) - strlen (dest)`.
*/
predicate case2(FunctionCall fc, Expr sizeArg, VariableAccess destArg) {
interestringCallWithArgs(fc, sizeArg, destArg) and
interestingCallWithArgs(fc, sizeArg, destArg) and
exists(SubExpr sub, int n |
// The destination buffer is an array of size n
destArg.getUnspecifiedType().(ArrayType).getSize() = n and

View File

@@ -1,4 +1,4 @@
/* '#include <stdlib.h>' was forgotton */
/* '#include <stdlib.h>' was forgotten */
int main(void) {
/* 'int malloc()' assumed */

View File

@@ -26,7 +26,7 @@ where
dest = bw.getDest() and
destSize = getBufferSize(dest, _) and
estimated = bw.getMaxDataLimited(reason) and
// we exclude ValueFlowAnalysis as it is reported in cpp/very-likely-overruning-write
// we exclude ValueFlowAnalysis as it is reported in cpp/very-likely-overrunning-write
not reason instanceof ValueFlowAnalysis and
// we can deduce that too much data may be copied (even without
// long '%f' conversions)

View File

@@ -31,7 +31,7 @@ predicate bounded(Expr e) {
) and
not convertedExprMightOverflow(e)
or
// Optimitically assume that a remainder expression always yields a much smaller value.
// Optimistically assume that a remainder expression always yields a much smaller value.
e = any(RemExpr rem).getLeftOperand()
or
e = any(AssignRemExpr rem).getLValue()
@@ -44,7 +44,7 @@ predicate bounded(Expr e) {
boundedBitwiseAnd(e, andExpr, andExpr.getAnOperand(), andExpr.getAnOperand())
)
or
// Optimitically assume that a division always yields a much smaller value.
// Optimistically assume that a division always yields a much smaller value.
e = any(DivExpr div).getLeftOperand()
or
e = any(AssignDivExpr div).getLValue()

View File

@@ -4,7 +4,7 @@
* The `security` tag has been added to the `cpp/return-stack-allocated-memory` query. As a result, its results will now appear by default.
* The "Uncontrolled data in arithmetic expression" (cpp/uncontrolled-arithmetic) query has been enhanced to reduce false positive results and its @precision increased to high.
* A new `cpp/very-likely-overruning-write` query has been added to the default query suite for C/C++. The query reports some results that were formerly flagged by `cpp/overruning-write`.
* A new `cpp/very-likely-overrunning-write` query has been added to the default query suite for C/C++. The query reports some results that were formerly flagged by `cpp/overrunning-write`.
### Minor Analysis Improvements

View File

@@ -13,6 +13,6 @@ where
def = definitionOf(e, kind) and
// We need to exclude definitions for elements inside template instantiations,
// as these often lead to multiple links to definitions from the same source location.
// LGTM does not support this bevaviour.
// LGTM does not support this behaviour.
not e.isFromTemplateInstantiation(_)
select e, def, kind

View File

@@ -1,7 +1,7 @@
/**
* @id cpp/wrong-uint-access
* @name Wrong Uint
* @descripion Acess an array of size lower than 256 with a uint16.
* @description Access an array of size lower than 256 with a uint16.
* @kind problem
* @problem.severity recommendation
* @tags efficiency
@@ -21,5 +21,5 @@ where
) and
defLine.getArraySize() <= 256
select useExpr,
"Using a " + useExpr.getArrayOffset().getType() + " to acess the array $@ of size " +
"Using a " + useExpr.getArrayOffset().getType() + " to access the array $@ of size " +
defLine.getArraySize() + ".", var, var.getName()

View File

@@ -0,0 +1,19 @@
int main(int argc, char** argv) {
char *filePath = argv[2];
{
// BAD: the user-controlled string is injected
// directly into `wordexp` which performs command substitution
wordexp_t we;
wordexp(filePath, &we, 0);
}
{
// GOOD: command substitution is disabled
wordexp_t we;
wordexp(filePath, &we, WRDE_NOCMD);
}
}

View File

@@ -0,0 +1,42 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>The code passes user input to <code>wordexp</code>. This leaves the code
vulnerable to attack by command injection, because <code>wordexp</code> performs command substitution.
Command substitution is a feature that replaces <code>$(command)</code> or <code>`command`</code> with the
output of the given command, allowing the user to run arbitrary code on the system.
</p>
</overview>
<recommendation>
<p>When calling <code>wordexp</code>, pass the <code>WRDE_NOCMD</code> flag to prevent command substitution.</p>
</recommendation>
<example>
<p>The following example passes a user-supplied file path to <code>wordexp</code> in two ways. The
first way uses <code>wordexp</code> with no specified flags. As such, it is vulnerable to command
injection.
The second way uses <code>wordexp</code> with the <code>WRDE_NOCMD</code> flag. As such, no command substitution
is performed, making this safe from command injection.</p>
<sample src="WordexpTainted.c" />
</example>
<references>
<li>CERT C Coding Standard:
<a href="https://www.securecoding.cert.org/confluence/display/c/STR02-C.+Sanitize+data+passed+to+complex+subsystems">STR02-C.
Sanitize data passed to complex subsystems</a>.</li>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/Command_Injection">Command Injection</a>.
</li>
<!-- LocalWords: CWE STR
-->
</references>
</qhelp>

View File

@@ -0,0 +1,57 @@
/**
* @name Uncontrolled data used in `wordexp` command
* @description Using user-supplied data in a `wordexp` command, without
* disabling command substitution, can make code vulnerable
* to command injection.
* @kind path-problem
* @problem.severity error
* @precision high
* @id cpp/wordexp-injection
* @tags security
* external/cwe/cwe-078
*/
import cpp
import semmle.code.cpp.ir.dataflow.TaintTracking
import semmle.code.cpp.security.FlowSources
import DataFlow::PathGraph
/**
* The `wordexp` function, which can perform command substitution.
*/
private class WordexpFunction extends Function {
WordexpFunction() { hasGlobalName("wordexp") }
}
/**
* Holds if `fc` disables command substitution by containing `WRDE_NOCMD` as a flag argument.
*/
private predicate isCommandSubstitutionDisabled(FunctionCall fc) {
fc.getArgument(2).getValue().toInt().bitAnd(4) = 4
/* 4 = WRDE_NOCMD. Check whether the flag is set. */
}
/**
* A configuration to track user-supplied data to the `wordexp` function.
*/
class WordexpTaintConfiguration extends TaintTracking::Configuration {
WordexpTaintConfiguration() { this = "WordexpTaintConfiguration" }
override predicate isSource(DataFlow::Node source) { source instanceof FlowSource }
override predicate isSink(DataFlow::Node sink) {
exists(FunctionCall fc | fc.getTarget() instanceof WordexpFunction |
fc.getArgument(0) = sink.asExpr() and
not isCommandSubstitutionDisabled(fc)
)
}
override predicate isSanitizer(DataFlow::Node node) {
node.asExpr().getUnspecifiedType() instanceof IntegralType
}
}
from WordexpTaintConfiguration conf, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode
where conf.hasFlowPath(sourceNode, sinkNode)
select sinkNode.getNode(), sourceNode, sinkNode,
"Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection."

View File

@@ -1,7 +1,7 @@
/**
* @name LinuxPrivilegeDroppingOutoforder
* @description A syscall commonly associated with privilege dropping is being called out of order.
* Normally a process drops group ID and sets supplimental groups for the target user
* Normally a process drops group ID and sets supplemental groups for the target user
* before setting the target user ID. This can have security impact if the return code
* from these methods is not checked.
* @kind problem

View File

@@ -2,7 +2,7 @@
* @name Linux kernel double-fetch vulnerability detection
* @description Double-fetch is a very common vulnerability pattern
* in linux kernel, attacker can exploit double-fetch
* issues to obatain root privilege.
* issues to obtain root privilege.
* Double-fetch is caused by fetching data from user
* mode by calling copy_from_user twice, CVE-2016-6480
* is quite a good example for your information.

View File

@@ -84,7 +84,7 @@ predicate isConditionBig(SwitchStmt swtmp) {
}
/** Holds if there are labels inside the block with names similar to `default` or `case`. */
predicate isWrongLableName(SwitchStmt swtmp) {
predicate isWrongLabelName(SwitchStmt swtmp) {
not swtmp.hasDefaultCase() and
exists(LabelStmt lb |
(
@@ -147,7 +147,7 @@ where
isConditionBig(sw) and msg = "The range of condition values is wider than the choices."
)
or
isWrongLableName(sw) and msg = "Possibly erroneous label name."
isWrongLabelName(sw) and msg = "Possibly erroneous label name."
or
isCodeBeforeCase(sw) and msg = "Code before case will not be executed."
select sw, msg

View File

@@ -24,7 +24,7 @@ where
texp.getEnclosingStmt().getParentStmt*() = ts.getStmt() and
not ts.getACatchClause().isEmpty()
) and
msg = "DllMain contains an exeption not wrapped in a try..catch block."
msg = "DllMain contains an exception not wrapped in a try..catch block."
or
texp.getExpr().isParenthesised() and
texp.getExpr().(CommaExpr).getLeftOperand().isConstant() and

View File

@@ -292,7 +292,7 @@ deprecated predicate duplicateFiles(File f, File other, int percent) {
}
/**
* DEPRECATED: Information on duplciate classes is no longer available.
* DEPRECATED: Information on duplicate classes is no longer available.
*
* Holds if most member functions of `c` (`numDup` out of `total`) are
* duplicates of member functions in `other`.
@@ -313,7 +313,7 @@ deprecated predicate mostlyDuplicateClassBase(Class c, Class other, int numDup,
}
/**
* DEPRECATED: Information on duplciate classes is no longer available.
* DEPRECATED: Information on duplicate classes is no longer available.
*
* Holds if most member functions of `c` are duplicates of member functions in
* `other`. Provides the human-readable `message` to describe the amount of

View File

@@ -14,4 +14,4 @@ from Function f
where
f.fromSource() and
f.calls+(f)
select f, "Functions shall not call theselves, either directly or indirectly."
select f, "Functions shall not call themselves, either directly or indirectly."

View File

@@ -41,4 +41,4 @@ where
not ae.getParent() instanceof ExprStmt and
not ae instanceof ForStmtSideEffectExpr
select ae,
"AV Rule 160: An assignment expression shall be used only as the exprression in an expression statement."
"AV Rule 160: An assignment expression shall be used only as the expression in an expression statement."

View File

@@ -0,0 +1,11 @@
edges
| test.cpp:23:20:23:23 | argv | test.cpp:29:13:29:20 | (const char *)... |
| test.cpp:23:20:23:23 | argv | test.cpp:29:13:29:20 | filePath |
nodes
| test.cpp:23:20:23:23 | argv | semmle.label | argv |
| test.cpp:29:13:29:20 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:29:13:29:20 | filePath | semmle.label | filePath |
subpaths
#select
| test.cpp:29:13:29:20 | (const char *)... | test.cpp:23:20:23:23 | argv | test.cpp:29:13:29:20 | (const char *)... | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
| test.cpp:29:13:29:20 | filePath | test.cpp:23:20:23:23 | argv | test.cpp:29:13:29:20 | filePath | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-078/WordexpTainted.ql

View File

@@ -0,0 +1,45 @@
#ifdef _MSC_VER
#define restrict __restrict
#else
#define restrict __restrict__
#endif
typedef unsigned long size_t;
typedef struct {
size_t we_wordc;
char **we_wordv;
size_t we_offs;
} wordexp_t;
enum {
WRDE_APPEND = (1 << 1),
WRDE_NOCMD = (1 << 2)
};
int wordexp(const char *restrict s, wordexp_t *restrict p, int flags);
int main(int argc, char** argv) {
char *filePath = argv[2];
{
// BAD: the user string is injected directly into `wordexp` which performs command substitution
wordexp_t we;
wordexp(filePath, &we, 0);
}
{
// GOOD: command substitution is disabled
wordexp_t we;
wordexp(filePath, &we, WRDE_NOCMD);
}
{
// GOOD: command substitution is disabled
wordexp_t we;
wordexp(filePath, &we, WRDE_NOCMD | WRDE_APPEND);
}
}

View File

@@ -1,3 +1,3 @@
| test.cpp:35:3:35:33 | call to runtime_error | Object creation of exception type on stack. Did you forget the throw keyword? |
| test.cpp:41:3:41:11 | call to funcTest1 | There is an exception in the function that requires your attention. |
| test.cpp:42:3:42:9 | call to DllMain | DllMain contains an exeption not wrapped in a try..catch block. |
| test.cpp:42:3:42:9 | call to DllMain | DllMain contains an exception not wrapped in a try..catch block. |

View File

@@ -1672,6 +1672,8 @@ predicate jumpStep(Node pred, Node succ) {
jrk.getTarget() = call.getATarget(_) and
succ = getAnOutNode(call, jrk.getTargetReturnKind())
)
or
FlowSummaryImpl::Private::Steps::summaryJumpStep(pred, succ)
}
private class StoreStepConfiguration extends ControlFlowReachabilityConfiguration {

View File

@@ -61,6 +61,20 @@ module Public {
/** Gets a summary component for a return of kind `rk`. */
SummaryComponent return(ReturnKind rk) { result = TReturnSummaryComponent(rk) }
/** Gets a summary component for synthetic global `sg`. */
SummaryComponent syntheticGlobal(SyntheticGlobal sg) {
result = TSyntheticGlobalSummaryComponent(sg)
}
/**
* A synthetic global. This represents some form of global state, which
* summaries can read and write individually.
*/
abstract class SyntheticGlobal extends string {
bindingset[this]
SyntheticGlobal() { any() }
}
}
/**
@@ -256,6 +270,7 @@ module Private {
TParameterSummaryComponent(ArgumentPosition pos) or
TArgumentSummaryComponent(ParameterPosition pos) or
TReturnSummaryComponent(ReturnKind rk) or
TSyntheticGlobalSummaryComponent(SummaryComponent::SyntheticGlobal sg) or
TWithoutContentSummaryComponent(ContentSet c) or
TWithContentSummaryComponent(ContentSet c)
@@ -563,6 +578,11 @@ module Private {
getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
s.tail())), rk)
)
or
exists(SummaryComponent::SyntheticGlobal sg |
head = TSyntheticGlobalSummaryComponent(sg) and
result = getSyntheticGlobalType(sg)
)
)
or
n = summaryNodeOutputState(c, s) and
@@ -582,6 +602,11 @@ module Private {
getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
s.tail())), pos)
)
or
exists(SummaryComponent::SyntheticGlobal sg |
head = TSyntheticGlobalSummaryComponent(sg) and
result = getSyntheticGlobalType(sg)
)
)
)
}
@@ -692,6 +717,18 @@ module Private {
)
}
/**
* Holds if there is a jump step from `pred` to `succ`, which is synthesized
* from a flow summary.
*/
predicate summaryJumpStep(Node pred, Node succ) {
exists(SummaryComponentStack s |
s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and
pred = summaryNodeOutputState(_, s) and
succ = summaryNodeInputState(_, s)
)
}
/**
* Holds if values stored inside content `c` are cleared at `n`. `n` is a
* synthesized summary node, so in order for values to be cleared at calls
@@ -871,18 +908,28 @@ module Private {
AccessPathRange() { relevantSpec(this) }
}
/** Holds if specification component `c` parses as parameter `n`. */
/** Holds if specification component `token` parses as parameter `pos`. */
predicate parseParam(AccessPathToken token, ArgumentPosition pos) {
token.getName() = "Parameter" and
pos = parseParamBody(token.getAnArgument())
}
/** Holds if specification component `c` parses as argument `n`. */
/** Holds if specification component `token` parses as argument `pos`. */
predicate parseArg(AccessPathToken token, ParameterPosition pos) {
token.getName() = "Argument" and
pos = parseArgBody(token.getAnArgument())
}
/** Holds if specification component `token` parses as synthetic global `sg`. */
predicate parseSynthGlobal(AccessPathToken token, string sg) {
token.getName() = "SyntheticGlobal" and
sg = token.getAnArgument()
}
private class SyntheticGlobalFromAccessPath extends SummaryComponent::SyntheticGlobal {
SyntheticGlobalFromAccessPath() { parseSynthGlobal(_, this) }
}
private SummaryComponent interpretComponent(AccessPathToken token) {
exists(ParameterPosition pos |
parseArg(token, pos) and result = SummaryComponent::argument(pos)
@@ -894,6 +941,10 @@ module Private {
or
token = "ReturnValue" and result = SummaryComponent::return(getReturnValueKind())
or
exists(string sg |
parseSynthGlobal(token, sg) and result = SummaryComponent::syntheticGlobal(sg)
)
or
result = interpretComponentSpecific(token)
}

View File

@@ -91,6 +91,12 @@ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) {
)
}
/** Gets the type of synthetic global `sg`. */
DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) {
exists(sg) and
result = Gvn::getGlobalValueNumber(any(ObjectType t))
}
bindingset[provenance]
private boolean isGenerated(string provenance) {
provenance = "generated" and result = true

View File

@@ -742,7 +742,7 @@ class NoOpInstruction extends Instruction {
* The `ReturnInstruction` for a function will have a control-flow successor edge to a block
* containing the `ExitFunction` instruction for that function.
*
* There are two differet return instructions: `ReturnValueInstruction`, for returning a value from
* There are two different return instructions: `ReturnValueInstruction`, for returning a value from
* a non-`void`-returning function, and `ReturnVoidInstruction`, for returning from a
* `void`-returning function.
*/
@@ -1331,7 +1331,7 @@ class CheckedConvertOrThrowInstruction extends UnaryInstruction {
*
* If the operand holds a null address, the result is a null address.
*
* This instruction is used to represent `dyanmic_cast<void*>` in C++, which returns the pointer to
* This instruction is used to represent `dynamic_cast<void*>` in C++, which returns the pointer to
* the most-derived object.
*/
class CompleteObjectAddressInstruction extends UnaryInstruction {

View File

@@ -742,7 +742,7 @@ class NoOpInstruction extends Instruction {
* The `ReturnInstruction` for a function will have a control-flow successor edge to a block
* containing the `ExitFunction` instruction for that function.
*
* There are two differet return instructions: `ReturnValueInstruction`, for returning a value from
* There are two different return instructions: `ReturnValueInstruction`, for returning a value from
* a non-`void`-returning function, and `ReturnVoidInstruction`, for returning from a
* `void`-returning function.
*/
@@ -1331,7 +1331,7 @@ class CheckedConvertOrThrowInstruction extends UnaryInstruction {
*
* If the operand holds a null address, the result is a null address.
*
* This instruction is used to represent `dyanmic_cast<void*>` in C++, which returns the pointer to
* This instruction is used to represent `dynamic_cast<void*>` in C++, which returns the pointer to
* the most-derived object.
*/
class CompleteObjectAddressInstruction extends UnaryInstruction {

View File

@@ -64,7 +64,7 @@ private module Cached {
or
instr = reusedPhiInstruction(_) and
// Check that the phi instruction is *not* degenerate, but we can't use
// getDegeneratePhiOperand in the first stage with phi instyructions
// getDegeneratePhiOperand in the first stage with phi instructions
not exists(
unique(OldIR::PhiInputOperand operand |
operand = instr.(OldIR::PhiInstruction).getAnInputOperand() and
@@ -718,7 +718,7 @@ module DefUse {
}
/**
* Gets the rank index of a hyphothetical use one instruction past the end of
* Gets the rank index of a hypothetical use one instruction past the end of
* the block. This index can be used to determine if a definition reaches the
* end of the block, even if the definition is the last instruction in the
* block.

View File

@@ -4243,9 +4243,11 @@ open class KotlinFileExtractor(
* this.dispatchReceiver = dispatchReceiver
* }
*
* fun get(): R { return this.dispatchReceiver.FN1() }
* override fun get(): R { return this.dispatchReceiver.FN1() }
*
* fun set(a0: R): Unit { return this.dispatchReceiver.FN2(a0) }
* override fun set(a0: R): Unit { return this.dispatchReceiver.FN2(a0) }
*
* override fun invoke(): R { return this.get() }
* }
* ```
*
@@ -4283,8 +4285,8 @@ open class KotlinFileExtractor(
)
val declarationParent = peekDeclStackAsDeclarationParent(propertyReferenceExpr) ?: return
val prefix = if (kPropertyClass.owner.name.asString().startsWith("KMutableProperty")) "Mutable" else ""
val baseClass = pluginContext.referenceClass(FqName("kotlin.jvm.internal.${prefix}PropertyReference${kPropertyType.arguments.size - 1}"))?.owner?.typeWith()
// The base class could be `Any`. `PropertyReference` is used to keep symmetry with function references.
val baseClass = pluginContext.referenceClass(FqName("kotlin.jvm.internal.PropertyReference"))?.owner?.typeWith()
?: pluginContext.irBuiltIns.anyType
val classId = extractGeneratedClass(ids, listOf(baseClass, kPropertyType), locId, propertyReferenceExpr, declarationParent)
@@ -5043,7 +5045,10 @@ open class KotlinFileExtractor(
return
}
if (!st.isFunctionOrKFunction() && !st.isSuspendFunctionOrKFunction()) {
fun IrSimpleType.isKProperty() =
classFqName?.asString()?.startsWith("kotlin.reflect.KProperty") == true
if (!st.isFunctionOrKFunction() && !st.isSuspendFunctionOrKFunction() && !st.isKProperty()) {
logger.errorElement("Expected to find expression with function type in SAM conversion.", e)
return
}

View File

@@ -83,6 +83,8 @@ predicate jumpStep(Node node1, Node node2) {
or
any(AdditionalValueStep a).step(node1, node2) and
node1.getEnclosingCallable() != node2.getEnclosingCallable()
or
FlowSummaryImpl::Private::Steps::summaryJumpStep(node1, node2)
}
/**

View File

@@ -61,6 +61,20 @@ module Public {
/** Gets a summary component for a return of kind `rk`. */
SummaryComponent return(ReturnKind rk) { result = TReturnSummaryComponent(rk) }
/** Gets a summary component for synthetic global `sg`. */
SummaryComponent syntheticGlobal(SyntheticGlobal sg) {
result = TSyntheticGlobalSummaryComponent(sg)
}
/**
* A synthetic global. This represents some form of global state, which
* summaries can read and write individually.
*/
abstract class SyntheticGlobal extends string {
bindingset[this]
SyntheticGlobal() { any() }
}
}
/**
@@ -256,6 +270,7 @@ module Private {
TParameterSummaryComponent(ArgumentPosition pos) or
TArgumentSummaryComponent(ParameterPosition pos) or
TReturnSummaryComponent(ReturnKind rk) or
TSyntheticGlobalSummaryComponent(SummaryComponent::SyntheticGlobal sg) or
TWithoutContentSummaryComponent(ContentSet c) or
TWithContentSummaryComponent(ContentSet c)
@@ -563,6 +578,11 @@ module Private {
getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
s.tail())), rk)
)
or
exists(SummaryComponent::SyntheticGlobal sg |
head = TSyntheticGlobalSummaryComponent(sg) and
result = getSyntheticGlobalType(sg)
)
)
or
n = summaryNodeOutputState(c, s) and
@@ -582,6 +602,11 @@ module Private {
getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
s.tail())), pos)
)
or
exists(SummaryComponent::SyntheticGlobal sg |
head = TSyntheticGlobalSummaryComponent(sg) and
result = getSyntheticGlobalType(sg)
)
)
)
}
@@ -692,6 +717,18 @@ module Private {
)
}
/**
* Holds if there is a jump step from `pred` to `succ`, which is synthesized
* from a flow summary.
*/
predicate summaryJumpStep(Node pred, Node succ) {
exists(SummaryComponentStack s |
s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and
pred = summaryNodeOutputState(_, s) and
succ = summaryNodeInputState(_, s)
)
}
/**
* Holds if values stored inside content `c` are cleared at `n`. `n` is a
* synthesized summary node, so in order for values to be cleared at calls
@@ -871,18 +908,28 @@ module Private {
AccessPathRange() { relevantSpec(this) }
}
/** Holds if specification component `c` parses as parameter `n`. */
/** Holds if specification component `token` parses as parameter `pos`. */
predicate parseParam(AccessPathToken token, ArgumentPosition pos) {
token.getName() = "Parameter" and
pos = parseParamBody(token.getAnArgument())
}
/** Holds if specification component `c` parses as argument `n`. */
/** Holds if specification component `token` parses as argument `pos`. */
predicate parseArg(AccessPathToken token, ParameterPosition pos) {
token.getName() = "Argument" and
pos = parseArgBody(token.getAnArgument())
}
/** Holds if specification component `token` parses as synthetic global `sg`. */
predicate parseSynthGlobal(AccessPathToken token, string sg) {
token.getName() = "SyntheticGlobal" and
sg = token.getAnArgument()
}
private class SyntheticGlobalFromAccessPath extends SummaryComponent::SyntheticGlobal {
SyntheticGlobalFromAccessPath() { parseSynthGlobal(_, this) }
}
private SummaryComponent interpretComponent(AccessPathToken token) {
exists(ParameterPosition pos |
parseArg(token, pos) and result = SummaryComponent::argument(pos)
@@ -894,6 +941,10 @@ module Private {
or
token = "ReturnValue" and result = SummaryComponent::return(getReturnValueKind())
or
exists(string sg |
parseSynthGlobal(token, sg) and result = SummaryComponent::syntheticGlobal(sg)
)
or
result = interpretComponentSpecific(token)
}

View File

@@ -52,6 +52,12 @@ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) {
exists(rk)
}
/** Gets the type of synthetic global `sg`. */
DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) {
exists(sg) and
result instanceof TypeObject
}
bindingset[provenance]
private boolean isGenerated(string provenance) {
provenance = "generated" and result = true

View File

@@ -6432,6 +6432,120 @@ samConversion.kt:
# 59| -1: [VarAccess] i0
# 59| 0: [IntegerLiteral] 1
# 59| 1: [IntegerLiteral] 2
# 74| 6: [Method] propertyRefsTest
# 74| 3: [TypeAccess] Unit
#-----| 4: (Parameters)
# 74| 0: [Parameter] prt
# 74| 0: [TypeAccess] PropertyRefsTest
# 74| 5: [BlockStmt] { ... }
# 75| 0: [LocalVariableDeclStmt] var ...;
# 75| 1: [LocalVariableDeclExpr] test1
# 75| 0: [CastExpr] (...)...
# 75| 0: [TypeAccess] IntGetter
# 75| 1: [ClassInstanceExpr] new (...)
# 75| -4: [AnonymousClass] new IntGetter(...) { ... }
# 75| 1: [Constructor]
#-----| 4: (Parameters)
# 75| 0: [Parameter] <fn>
# 75| 5: [BlockStmt] { ... }
# 75| 0: [SuperConstructorInvocationStmt] super(...)
# 75| 1: [ExprStmt] <Expr>;
# 75| 0: [AssignExpr] ...=...
# 75| 0: [VarAccess] this.<fn>
# 75| -1: [ThisAccess] this
# 75| 1: [VarAccess] <fn>
# 75| 2: [FieldDeclaration] Function0<Integer> <fn>;
# 75| -1: [TypeAccess] Function0<Integer>
# 75| 0: [TypeAccess] Integer
# 75| 3: [Method] f
# 75| 3: [TypeAccess] int
# 75| 5: [BlockStmt] { ... }
# 75| 0: [ReturnStmt] return ...
# 75| 0: [MethodAccess] invoke(...)
# 75| -1: [VarAccess] <fn>
# 75| -3: [TypeAccess] IntGetter
# 75| 0: [PropertyRefExpr] ...::...
# 75| -4: [AnonymousClass] new KProperty0<Integer>(...) { ... }
# 75| 1: [Constructor]
#-----| 4: (Parameters)
# 75| 0: [Parameter] <dispatchReceiver>
# 75| 5: [BlockStmt] { ... }
# 75| 0: [SuperConstructorInvocationStmt] super(...)
# 75| 1: [ExprStmt] <Expr>;
# 75| 0: [AssignExpr] ...=...
# 75| 0: [VarAccess] this.<dispatchReceiver>
# 75| -1: [ThisAccess] this
# 75| 1: [VarAccess] <dispatchReceiver>
# 75| 2: [FieldDeclaration] PropertyRefsTest <dispatchReceiver>;
# 75| -1: [TypeAccess] PropertyRefsTest
# 75| 3: [Method] get
# 75| 5: [BlockStmt] { ... }
# 75| 0: [ReturnStmt] return ...
# 75| 0: [MethodAccess] getX(...)
# 75| -1: [VarAccess] this.<dispatchReceiver>
# 75| -1: [ThisAccess] this
# 75| 4: [Method] invoke
# 75| 5: [BlockStmt] { ... }
# 75| 0: [ReturnStmt] return ...
# 75| 0: [MethodAccess] get(...)
# 75| -1: [ThisAccess] this
# 75| -3: [TypeAccess] KProperty0<Integer>
# 75| 0: [TypeAccess] Integer
# 75| 0: [VarAccess] prt
# 76| 1: [LocalVariableDeclStmt] var ...;
# 76| 1: [LocalVariableDeclExpr] test2
# 76| 0: [CastExpr] (...)...
# 76| 0: [TypeAccess] PropertyRefsGetter
# 76| 1: [ClassInstanceExpr] new (...)
# 76| -4: [AnonymousClass] new PropertyRefsGetter(...) { ... }
# 76| 1: [Constructor]
#-----| 4: (Parameters)
# 76| 0: [Parameter] <fn>
# 76| 5: [BlockStmt] { ... }
# 76| 0: [SuperConstructorInvocationStmt] super(...)
# 76| 1: [ExprStmt] <Expr>;
# 76| 0: [AssignExpr] ...=...
# 76| 0: [VarAccess] this.<fn>
# 76| -1: [ThisAccess] this
# 76| 1: [VarAccess] <fn>
# 76| 2: [FieldDeclaration] Function1<PropertyRefsTest,Integer> <fn>;
# 76| -1: [TypeAccess] Function1<PropertyRefsTest,Integer>
# 76| 0: [TypeAccess] PropertyRefsTest
# 76| 1: [TypeAccess] Integer
# 76| 3: [Method] f
# 76| 3: [TypeAccess] int
#-----| 4: (Parameters)
# 76| 0: [Parameter] prt
# 76| 0: [TypeAccess] PropertyRefsTest
# 76| 5: [BlockStmt] { ... }
# 76| 0: [ReturnStmt] return ...
# 76| 0: [MethodAccess] invoke(...)
# 76| -1: [VarAccess] <fn>
# 76| 0: [VarAccess] prt
# 76| -3: [TypeAccess] PropertyRefsGetter
# 76| 0: [PropertyRefExpr] ...::...
# 76| -4: [AnonymousClass] new KProperty1<PropertyRefsTest,Integer>(...) { ... }
# 76| 1: [Constructor]
# 76| 5: [BlockStmt] { ... }
# 76| 0: [SuperConstructorInvocationStmt] super(...)
# 76| 2: [Method] get
#-----| 4: (Parameters)
# 76| 0: [Parameter] a0
# 76| 5: [BlockStmt] { ... }
# 76| 0: [ReturnStmt] return ...
# 76| 0: [MethodAccess] getX(...)
# 76| -1: [VarAccess] a0
# 76| 3: [Method] invoke
#-----| 4: (Parameters)
# 76| 0: [Parameter] a0
# 76| 5: [BlockStmt] { ... }
# 76| 0: [ReturnStmt] return ...
# 76| 0: [MethodAccess] get(...)
# 76| -1: [ThisAccess] this
# 76| 0: [VarAccess] a0
# 76| -3: [TypeAccess] KProperty1<PropertyRefsTest,Integer>
# 76| 0: [TypeAccess] PropertyRefsTest
# 76| 1: [TypeAccess] Integer
# 16| 2: [Interface] IntPredicate
# 17| 1: [Method] accept
# 17| 3: [TypeAccess] boolean
@@ -6520,6 +6634,32 @@ samConversion.kt:
# 54| 0: [TypeAccess] int
# 54| 1: [Parameter] j
# 54| 0: [TypeAccess] int
# 62| 8: [Class] PropertyRefsTest
# 62| 1: [Constructor] PropertyRefsTest
# 62| 5: [BlockStmt] { ... }
# 62| 0: [SuperConstructorInvocationStmt] super(...)
# 62| 1: [BlockStmt] { ... }
# 63| 0: [ExprStmt] <Expr>;
# 63| 0: [KtInitializerAssignExpr] ...=...
# 63| 0: [VarAccess] x
# 63| 2: [Method] getX
# 63| 3: [TypeAccess] int
# 63| 5: [BlockStmt] { ... }
# 63| 0: [ReturnStmt] return ...
# 63| 0: [VarAccess] this.x
# 63| -1: [ThisAccess] this
# 63| 3: [FieldDeclaration] int x;
# 63| -1: [TypeAccess] int
# 63| 0: [IntegerLiteral] 1
# 66| 9: [Interface] PropertyRefsGetter
# 67| 1: [Method] f
# 67| 3: [TypeAccess] int
#-----| 4: (Parameters)
# 67| 0: [Parameter] prt
# 67| 0: [TypeAccess] PropertyRefsTest
# 70| 10: [Interface] IntGetter
# 71| 1: [Method] f
# 71| 3: [TypeAccess] int
whenExpr.kt:
# 0| [CompilationUnit] whenExpr
# 0| 1: [Class] WhenExprKt

View File

@@ -4028,6 +4028,72 @@
| samConversion.kt:59:8:59:15 | fn1(...) | samConversion.kt:57:9:60:1 | test | MethodAccess |
| samConversion.kt:59:12:59:12 | 1 | samConversion.kt:57:9:60:1 | test | IntegerLiteral |
| samConversion.kt:59:14:59:14 | 2 | samConversion.kt:57:9:60:1 | test | IntegerLiteral |
| samConversion.kt:63:5:63:13 | ...=... | samConversion.kt:62:1:64:1 | PropertyRefsTest | KtInitializerAssignExpr |
| samConversion.kt:63:5:63:13 | int | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:63:5:63:13 | int | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:63:5:63:13 | this | samConversion.kt:63:5:63:13 | getX | ThisAccess |
| samConversion.kt:63:5:63:13 | this.x | samConversion.kt:63:5:63:13 | getX | VarAccess |
| samConversion.kt:63:5:63:13 | x | samConversion.kt:62:1:64:1 | PropertyRefsTest | VarAccess |
| samConversion.kt:63:13:63:13 | 1 | samConversion.kt:62:1:64:1 | PropertyRefsTest | IntegerLiteral |
| samConversion.kt:67:5:67:37 | int | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:67:11:67:31 | PropertyRefsTest | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:71:5:71:16 | int | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:74:1:77:1 | Unit | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:74:22:74:42 | PropertyRefsTest | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:75:5:75:33 | test1 | samConversion.kt:74:1:77:1 | propertyRefsTest | LocalVariableDeclExpr |
| samConversion.kt:75:17:75:33 | (...)... | samConversion.kt:74:1:77:1 | propertyRefsTest | CastExpr |
| samConversion.kt:75:17:75:33 | ...=... | samConversion.kt:75:17:75:33 | | AssignExpr |
| samConversion.kt:75:17:75:33 | <fn> | samConversion.kt:75:17:75:33 | | VarAccess |
| samConversion.kt:75:17:75:33 | <fn> | samConversion.kt:75:17:75:33 | f | VarAccess |
| samConversion.kt:75:17:75:33 | Function0<Integer> | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:75:17:75:33 | IntGetter | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:75:17:75:33 | IntGetter | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:75:17:75:33 | Integer | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:75:17:75:33 | int | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:75:17:75:33 | invoke(...) | samConversion.kt:75:17:75:33 | f | MethodAccess |
| samConversion.kt:75:17:75:33 | new (...) | samConversion.kt:74:1:77:1 | propertyRefsTest | ClassInstanceExpr |
| samConversion.kt:75:17:75:33 | this | samConversion.kt:75:17:75:33 | | ThisAccess |
| samConversion.kt:75:17:75:33 | this.<fn> | samConversion.kt:75:17:75:33 | | VarAccess |
| samConversion.kt:75:27:75:29 | prt | samConversion.kt:74:1:77:1 | propertyRefsTest | VarAccess |
| samConversion.kt:75:27:75:32 | ...::... | samConversion.kt:74:1:77:1 | propertyRefsTest | PropertyRefExpr |
| samConversion.kt:75:27:75:32 | ...=... | samConversion.kt:75:27:75:32 | | AssignExpr |
| samConversion.kt:75:27:75:32 | <dispatchReceiver> | samConversion.kt:75:27:75:32 | | VarAccess |
| samConversion.kt:75:27:75:32 | Integer | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:75:27:75:32 | KProperty0<Integer> | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:75:27:75:32 | PropertyRefsTest | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:75:27:75:32 | get(...) | samConversion.kt:75:27:75:32 | invoke | MethodAccess |
| samConversion.kt:75:27:75:32 | getX(...) | samConversion.kt:75:27:75:32 | get | MethodAccess |
| samConversion.kt:75:27:75:32 | this | samConversion.kt:75:27:75:32 | | ThisAccess |
| samConversion.kt:75:27:75:32 | this | samConversion.kt:75:27:75:32 | get | ThisAccess |
| samConversion.kt:75:27:75:32 | this | samConversion.kt:75:27:75:32 | invoke | ThisAccess |
| samConversion.kt:75:27:75:32 | this.<dispatchReceiver> | samConversion.kt:75:27:75:32 | | VarAccess |
| samConversion.kt:75:27:75:32 | this.<dispatchReceiver> | samConversion.kt:75:27:75:32 | get | VarAccess |
| samConversion.kt:76:5:76:55 | test2 | samConversion.kt:74:1:77:1 | propertyRefsTest | LocalVariableDeclExpr |
| samConversion.kt:76:17:76:55 | (...)... | samConversion.kt:74:1:77:1 | propertyRefsTest | CastExpr |
| samConversion.kt:76:17:76:55 | ...=... | samConversion.kt:76:17:76:55 | | AssignExpr |
| samConversion.kt:76:17:76:55 | <fn> | samConversion.kt:76:17:76:55 | | VarAccess |
| samConversion.kt:76:17:76:55 | <fn> | samConversion.kt:76:17:76:55 | f | VarAccess |
| samConversion.kt:76:17:76:55 | Function1<PropertyRefsTest,Integer> | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:76:17:76:55 | Integer | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:76:17:76:55 | PropertyRefsGetter | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:76:17:76:55 | PropertyRefsGetter | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:76:17:76:55 | PropertyRefsTest | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:76:17:76:55 | PropertyRefsTest | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:76:17:76:55 | int | file://:0:0:0:0 | <none> | TypeAccess |
| samConversion.kt:76:17:76:55 | invoke(...) | samConversion.kt:76:17:76:55 | f | MethodAccess |
| samConversion.kt:76:17:76:55 | new (...) | samConversion.kt:74:1:77:1 | propertyRefsTest | ClassInstanceExpr |
| samConversion.kt:76:17:76:55 | prt | samConversion.kt:76:17:76:55 | f | VarAccess |
| samConversion.kt:76:17:76:55 | this | samConversion.kt:76:17:76:55 | | ThisAccess |
| samConversion.kt:76:17:76:55 | this.<fn> | samConversion.kt:76:17:76:55 | | VarAccess |
| samConversion.kt:76:36:76:54 | ...::... | samConversion.kt:74:1:77:1 | propertyRefsTest | PropertyRefExpr |
| samConversion.kt:76:36:76:54 | Integer | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:76:36:76:54 | KProperty1<PropertyRefsTest,Integer> | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:76:36:76:54 | PropertyRefsTest | samConversion.kt:74:1:77:1 | propertyRefsTest | TypeAccess |
| samConversion.kt:76:36:76:54 | a0 | samConversion.kt:76:36:76:54 | get | VarAccess |
| samConversion.kt:76:36:76:54 | a0 | samConversion.kt:76:36:76:54 | invoke | VarAccess |
| samConversion.kt:76:36:76:54 | get(...) | samConversion.kt:76:36:76:54 | invoke | MethodAccess |
| samConversion.kt:76:36:76:54 | getX(...) | samConversion.kt:76:36:76:54 | get | MethodAccess |
| samConversion.kt:76:36:76:54 | this | samConversion.kt:76:36:76:54 | invoke | ThisAccess |
| whenExpr.kt:1:1:9:1 | int | file://:0:0:0:0 | <none> | TypeAccess |
| whenExpr.kt:1:14:1:19 | int | file://:0:0:0:0 | <none> | TypeAccess |
| whenExpr.kt:2:10:8:3 | <Stmt> | whenExpr.kt:1:1:9:1 | testWhen | StmtExpr |

View File

@@ -241,6 +241,12 @@ anon_class_member_modifiers
| samConversion.kt:46:32:46:44 | new Function1<Integer,Boolean>(...) { ... } | samConversion.kt:46:32:46:44 | invoke | override, public |
| samConversion.kt:58:14:58:45 | new InterfaceFn1Sus(...) { ... } | samConversion.kt:58:14:58:45 | fn1 | override, public, suspend |
| samConversion.kt:58:30:58:45 | new Function2<Integer,Integer,Unit>(...) { ... } | samConversion.kt:58:30:58:45 | invoke | override, public, suspend |
| samConversion.kt:75:17:75:33 | new IntGetter(...) { ... } | samConversion.kt:75:17:75:33 | f | override, public |
| samConversion.kt:75:27:75:32 | new KProperty0<Integer>(...) { ... } | samConversion.kt:75:27:75:32 | get | override, public |
| samConversion.kt:75:27:75:32 | new KProperty0<Integer>(...) { ... } | samConversion.kt:75:27:75:32 | invoke | override, public |
| samConversion.kt:76:17:76:55 | new PropertyRefsGetter(...) { ... } | samConversion.kt:76:17:76:55 | f | override, public |
| samConversion.kt:76:36:76:54 | new KProperty1<PropertyRefsTest,Integer>(...) { ... } | samConversion.kt:76:36:76:54 | get | override, public |
| samConversion.kt:76:36:76:54 | new KProperty1<PropertyRefsTest,Integer>(...) { ... } | samConversion.kt:76:36:76:54 | invoke | override, public |
nonOverrideInvoke
| funcExprs.kt:36:29:36:117 | ...->... | funcExprs.kt:36:29:36:117 | invoke | 23 |
| funcExprs.kt:90:15:90:69 | ...->... | funcExprs.kt:90:15:90:69 | invoke | 23 |

View File

@@ -58,3 +58,20 @@ suspend fun test() {
val i0 = InterfaceFn1Sus { a, b -> Unit }
i0.fn1(1,2)
}
class PropertyRefsTest {
val x = 1
}
fun interface PropertyRefsGetter {
fun f(prt: PropertyRefsTest): Int
}
fun interface IntGetter {
fun f(): Int
}
fun propertyRefsTest(prt: PropertyRefsTest) {
val test1 = IntGetter(prt::x)
val test2 = PropertyRefsGetter(PropertyRefsTest::x)
}

View File

@@ -2,21 +2,21 @@ variableInitializerType
| reflection.kt:7:9:7:54 | KFunction<Double> ref | file://<external>/KFunction.class:0:0:0:0 | KFunction<Double> | reflection.kt:7:49:7:54 | new Function2<Ccc,Integer,Double>(...) { ... } | file://<external>/Function2.class:0:0:0:0 | Function2<Ccc,Integer,Double> | true |
| reflection.kt:7:9:7:54 | KFunction<Double> ref | file://<external>/KFunction.class:0:0:0:0 | KFunction<Double> | reflection.kt:7:49:7:54 | new Function2<Ccc,Integer,Double>(...) { ... } | file://<external>/FunctionReference.class:0:0:0:0 | FunctionReference | true |
| reflection.kt:10:9:10:42 | KProperty1<C,Integer> x0 | file://<external>/KProperty1.class:0:0:0:0 | KProperty1<C,Integer> | reflection.kt:10:38:10:42 | new KProperty1<C,Integer>(...) { ... } | file://<external>/KProperty1.class:0:0:0:0 | KProperty1<C,Integer> | true |
| reflection.kt:10:9:10:42 | KProperty1<C,Integer> x0 | file://<external>/KProperty1.class:0:0:0:0 | KProperty1<C,Integer> | reflection.kt:10:38:10:42 | new KProperty1<C,Integer>(...) { ... } | file://<external>/PropertyReference1.class:0:0:0:0 | PropertyReference1 | true |
| reflection.kt:10:9:10:42 | KProperty1<C,Integer> x0 | file://<external>/KProperty1.class:0:0:0:0 | KProperty1<C,Integer> | reflection.kt:10:38:10:42 | new KProperty1<C,Integer>(...) { ... } | file://<external>/PropertyReference.class:0:0:0:0 | PropertyReference | true |
| reflection.kt:13:9:13:53 | Getter<C,Integer> x3 | file://<external>/KProperty1$Getter.class:0:0:0:0 | Getter<C,Integer> | file://<external>/KProperty1$Getter.class:0:0:0:0 | Getter<C,Integer> | file://<external>/Function1.class:0:0:0:0 | Function1<C,Integer> | true |
| reflection.kt:13:9:13:53 | Getter<C,Integer> x3 | file://<external>/KProperty1$Getter.class:0:0:0:0 | Getter<C,Integer> | file://<external>/KProperty1$Getter.class:0:0:0:0 | Getter<C,Integer> | file://<external>/KProperty$Getter.class:0:0:0:0 | Getter<Integer> | true |
| reflection.kt:14:9:14:44 | KFunction<Integer> x4 | file://<external>/KFunction.class:0:0:0:0 | KFunction<Integer> | reflection.kt:14:38:14:44 | new Function1<C,Integer>(...) { ... } | file://<external>/Function1.class:0:0:0:0 | Function1<C,Integer> | true |
| reflection.kt:14:9:14:44 | KFunction<Integer> x4 | file://<external>/KFunction.class:0:0:0:0 | KFunction<Integer> | reflection.kt:14:38:14:44 | new Function1<C,Integer>(...) { ... } | file://<external>/FunctionReference.class:0:0:0:0 | FunctionReference | true |
| reflection.kt:15:9:15:41 | KProperty0<Integer> x5 | file://<external>/KProperty0.class:0:0:0:0 | KProperty0<Integer> | reflection.kt:15:35:15:41 | new KProperty0<Integer>(...) { ... } | file://<external>/KProperty0.class:0:0:0:0 | KProperty0<Integer> | true |
| reflection.kt:15:9:15:41 | KProperty0<Integer> x5 | file://<external>/KProperty0.class:0:0:0:0 | KProperty0<Integer> | reflection.kt:15:35:15:41 | new KProperty0<Integer>(...) { ... } | file://<external>/PropertyReference0.class:0:0:0:0 | PropertyReference0 | true |
| reflection.kt:15:9:15:41 | KProperty0<Integer> x5 | file://<external>/KProperty0.class:0:0:0:0 | KProperty0<Integer> | reflection.kt:15:35:15:41 | new KProperty0<Integer>(...) { ... } | file://<external>/PropertyReference.class:0:0:0:0 | PropertyReference | true |
| reflection.kt:17:9:17:49 | KMutableProperty1<C,Integer> y0 | file://<external>/KMutableProperty1.class:0:0:0:0 | KMutableProperty1<C,Integer> | reflection.kt:17:45:17:49 | new KMutableProperty1<C,Integer>(...) { ... } | file://<external>/KMutableProperty1.class:0:0:0:0 | KMutableProperty1<C,Integer> | true |
| reflection.kt:17:9:17:49 | KMutableProperty1<C,Integer> y0 | file://<external>/KMutableProperty1.class:0:0:0:0 | KMutableProperty1<C,Integer> | reflection.kt:17:45:17:49 | new KMutableProperty1<C,Integer>(...) { ... } | file://<external>/MutablePropertyReference1.class:0:0:0:0 | MutablePropertyReference1 | true |
| reflection.kt:17:9:17:49 | KMutableProperty1<C,Integer> y0 | file://<external>/KMutableProperty1.class:0:0:0:0 | KMutableProperty1<C,Integer> | reflection.kt:17:45:17:49 | new KMutableProperty1<C,Integer>(...) { ... } | file://<external>/PropertyReference.class:0:0:0:0 | PropertyReference | true |
| reflection.kt:20:9:20:60 | Setter<C,Integer> y3 | file://<external>/KMutableProperty1$Setter.class:0:0:0:0 | Setter<C,Integer> | file://<external>/KMutableProperty1$Setter.class:0:0:0:0 | Setter<C,Integer> | file://<external>/Function2.class:0:0:0:0 | Function2<C,Integer,Unit> | true |
| reflection.kt:20:9:20:60 | Setter<C,Integer> y3 | file://<external>/KMutableProperty1$Setter.class:0:0:0:0 | Setter<C,Integer> | file://<external>/KMutableProperty1$Setter.class:0:0:0:0 | Setter<C,Integer> | file://<external>/KMutableProperty$Setter.class:0:0:0:0 | Setter<Integer> | true |
| reflection.kt:21:9:21:50 | KFunction<Unit> y4 | file://<external>/KFunction.class:0:0:0:0 | KFunction<Unit> | reflection.kt:21:44:21:50 | new Function2<C,Integer,Unit>(...) { ... } | file://<external>/Function2.class:0:0:0:0 | Function2<C,Integer,Unit> | true |
| reflection.kt:21:9:21:50 | KFunction<Unit> y4 | file://<external>/KFunction.class:0:0:0:0 | KFunction<Unit> | reflection.kt:21:44:21:50 | new Function2<C,Integer,Unit>(...) { ... } | file://<external>/FunctionReference.class:0:0:0:0 | FunctionReference | true |
| reflection.kt:22:9:22:48 | KMutableProperty0<Integer> y5 | file://<external>/KMutableProperty0.class:0:0:0:0 | KMutableProperty0<Integer> | reflection.kt:22:42:22:48 | new KMutableProperty0<Integer>(...) { ... } | file://<external>/KMutableProperty0.class:0:0:0:0 | KMutableProperty0<Integer> | true |
| reflection.kt:22:9:22:48 | KMutableProperty0<Integer> y5 | file://<external>/KMutableProperty0.class:0:0:0:0 | KMutableProperty0<Integer> | reflection.kt:22:42:22:48 | new KMutableProperty0<Integer>(...) { ... } | file://<external>/MutablePropertyReference0.class:0:0:0:0 | MutablePropertyReference0 | true |
| reflection.kt:22:9:22:48 | KMutableProperty0<Integer> y5 | file://<external>/KMutableProperty0.class:0:0:0:0 | KMutableProperty0<Integer> | reflection.kt:22:42:22:48 | new KMutableProperty0<Integer>(...) { ... } | file://<external>/PropertyReference.class:0:0:0:0 | PropertyReference | true |
| reflection.kt:24:9:24:91 | KProperty2<C,Integer,Integer> prop | file://<external>/KProperty2.class:0:0:0:0 | KProperty2<C,Integer,Integer> | file://<external>/KProperty2.class:0:0:0:0 | KProperty2<C,Integer,Integer> | file://<external>/Function2.class:0:0:0:0 | Function2<C,Integer,Integer> | true |
| reflection.kt:24:9:24:91 | KProperty2<C,Integer,Integer> prop | file://<external>/KProperty2.class:0:0:0:0 | KProperty2<C,Integer,Integer> | file://<external>/KProperty2.class:0:0:0:0 | KProperty2<C,Integer,Integer> | file://<external>/KProperty.class:0:0:0:0 | KProperty<Integer> | true |
| reflection.kt:116:9:116:44 | KFunction<Unit> x | file://<external>/KFunction.class:0:0:0:0 | KFunction<Unit> | reflection.kt:116:40:116:44 | new Function1<Integer,Unit>(...) { ... } | file://<external>/Function1.class:0:0:0:0 | Function1<Integer,Unit> | true |
@@ -243,3 +243,251 @@ compGenerated
| reflection.kt:105:18:105:31 | getProp1 | 3 |
| reflection.kt:105:18:105:31 | setProp1 | 3 |
| reflection.kt:126:9:126:13 | | 1 |
propertyReferenceOverrides
| reflection.kt:10:38:10:42 | ...::... | reflection.kt:10:38:10:42 | get | kotlin.reflect.KProperty1<C,Integer>.get(Reflection.C) |
| reflection.kt:10:38:10:42 | ...::... | reflection.kt:10:38:10:42 | invoke | kotlin.jvm.functions.Function1<C,Integer>.invoke(Reflection.C) |
| reflection.kt:15:35:15:41 | ...::... | reflection.kt:15:35:15:41 | get | kotlin.reflect.KProperty0<Integer>.get() |
| reflection.kt:15:35:15:41 | ...::... | reflection.kt:15:35:15:41 | invoke | kotlin.jvm.functions.Function0<Integer>.invoke() |
| reflection.kt:17:45:17:49 | ...::... | reflection.kt:17:45:17:49 | get | kotlin.reflect.KProperty1<C,Integer>.get(Reflection.C) |
| reflection.kt:17:45:17:49 | ...::... | reflection.kt:17:45:17:49 | invoke | kotlin.jvm.functions.Function1<C,Integer>.invoke(Reflection.C) |
| reflection.kt:22:42:22:48 | ...::... | reflection.kt:22:42:22:48 | get | kotlin.reflect.KProperty0<Integer>.get() |
| reflection.kt:22:42:22:48 | ...::... | reflection.kt:22:42:22:48 | invoke | kotlin.jvm.functions.Function0<Integer>.invoke() |
| reflection.kt:50:13:50:28 | ...::... | reflection.kt:50:13:50:28 | get | kotlin.reflect.KProperty1<String,Character>.get(java.lang.String) |
| reflection.kt:50:13:50:28 | ...::... | reflection.kt:50:13:50:28 | invoke | kotlin.jvm.functions.Function1<String,Character>.invoke(java.lang.String) |
| reflection.kt:51:13:51:28 | ...::... | reflection.kt:51:13:51:28 | get | kotlin.reflect.KProperty0<Character>.get() |
| reflection.kt:51:13:51:28 | ...::... | reflection.kt:51:13:51:28 | invoke | kotlin.jvm.functions.Function0<Character>.invoke() |
| reflection.kt:67:17:67:32 | ...::... | reflection.kt:67:17:67:32 | get | kotlin.reflect.KProperty1<Generic<Integer>,Integer>.get(Class1.Generic) |
| reflection.kt:67:17:67:32 | ...::... | reflection.kt:67:17:67:32 | invoke | kotlin.jvm.functions.Function1<Generic<Integer>,Integer>.invoke(Class1.Generic) |
| reflection.kt:67:17:67:32 | ...::... | reflection.kt:67:17:67:32 | set | kotlin.reflect.KMutableProperty1<Generic<Integer>,Integer>.set(Class1.Generic,java.lang.Integer) |
| reflection.kt:68:17:68:34 | ...::... | reflection.kt:68:17:68:34 | get | kotlin.reflect.KProperty0<Integer>.get() |
| reflection.kt:68:17:68:34 | ...::... | reflection.kt:68:17:68:34 | invoke | kotlin.jvm.functions.Function0<Integer>.invoke() |
| reflection.kt:68:17:68:34 | ...::... | reflection.kt:68:17:68:34 | set | kotlin.reflect.KMutableProperty0<Integer>.set(java.lang.Integer) |
| reflection.kt:70:17:70:30 | ...::... | reflection.kt:70:17:70:30 | get | kotlin.reflect.KProperty0<Integer>.get() |
| reflection.kt:70:17:70:30 | ...::... | reflection.kt:70:17:70:30 | invoke | kotlin.jvm.functions.Function0<Integer>.invoke() |
| reflection.kt:71:17:71:34 | ...::... | reflection.kt:71:17:71:34 | get | kotlin.reflect.KProperty0<Integer>.get() |
| reflection.kt:71:17:71:34 | ...::... | reflection.kt:71:17:71:34 | invoke | kotlin.jvm.functions.Function0<Integer>.invoke() |
| reflection.kt:72:17:72:35 | ...::... | reflection.kt:72:17:72:35 | get | kotlin.reflect.KProperty0<Integer>.get() |
| reflection.kt:72:17:72:35 | ...::... | reflection.kt:72:17:72:35 | invoke | kotlin.jvm.functions.Function0<Integer>.invoke() |
| reflection.kt:109:17:109:27 | ...::... | reflection.kt:109:17:109:27 | get | kotlin.reflect.KProperty0<Integer>.get() |
| reflection.kt:109:17:109:27 | ...::... | reflection.kt:109:17:109:27 | invoke | kotlin.jvm.functions.Function0<Integer>.invoke() |
notImplementedInterfaceMembers
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KCallable<Integer>.call(java.lang.Object[]) |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KCallable<Integer>.callBy(java.util.Map) |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KCallable<Integer>.getName() |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KCallable<Integer>.getParameters() |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KCallable<Integer>.getReturnType() |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KCallable<Integer>.getTypeParameters() |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KCallable<Integer>.getVisibility() |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KCallable<Integer>.isAbstract() |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KCallable<Integer>.isFinal() |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KCallable<Integer>.isOpen() |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KCallable<Integer>.isSuspend() |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KProperty1<C,Integer>.getDelegate(Reflection.C) |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KProperty1<C,Integer>.getGetter() |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KProperty<Integer>.getGetter() |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KProperty<Integer>.isConst() |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KProperty<Integer>.isLateinit() |
| reflection.kt:10:38:10:42 | ...::... | kotlin.reflect.KProperty<Object>.getGetter() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KCallable<Integer>.call(java.lang.Object[]) |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KCallable<Integer>.callBy(java.util.Map) |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KCallable<Integer>.getName() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KCallable<Integer>.getParameters() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KCallable<Integer>.getReturnType() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KCallable<Integer>.getTypeParameters() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KCallable<Integer>.getVisibility() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KCallable<Integer>.isAbstract() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KCallable<Integer>.isFinal() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KCallable<Integer>.isOpen() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KCallable<Integer>.isSuspend() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KProperty0<Integer>.getDelegate() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KProperty0<Integer>.getGetter() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KProperty<Integer>.getGetter() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KProperty<Integer>.isConst() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KProperty<Integer>.isLateinit() |
| reflection.kt:15:35:15:41 | ...::... | kotlin.reflect.KProperty<Object>.getGetter() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KCallable<Integer>.call(java.lang.Object[]) |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KCallable<Integer>.callBy(java.util.Map) |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KCallable<Integer>.getName() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KCallable<Integer>.getParameters() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KCallable<Integer>.getReturnType() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KCallable<Integer>.getTypeParameters() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KCallable<Integer>.getVisibility() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KCallable<Integer>.isAbstract() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KCallable<Integer>.isFinal() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KCallable<Integer>.isOpen() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KCallable<Integer>.isSuspend() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KMutableProperty1<C,Integer>.getSetter() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KMutableProperty1<C,Integer>.set(Reflection.C,java.lang.Integer) |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KMutableProperty<Integer>.getSetter() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KProperty1<C,Integer>.getDelegate(Reflection.C) |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KProperty1<C,Integer>.getGetter() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KProperty<Integer>.getGetter() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KProperty<Integer>.isConst() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KProperty<Integer>.isLateinit() |
| reflection.kt:17:45:17:49 | ...::... | kotlin.reflect.KProperty<Object>.getGetter() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KCallable<Integer>.call(java.lang.Object[]) |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KCallable<Integer>.callBy(java.util.Map) |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KCallable<Integer>.getName() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KCallable<Integer>.getParameters() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KCallable<Integer>.getReturnType() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KCallable<Integer>.getTypeParameters() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KCallable<Integer>.getVisibility() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KCallable<Integer>.isAbstract() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KCallable<Integer>.isFinal() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KCallable<Integer>.isOpen() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KCallable<Integer>.isSuspend() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KMutableProperty0<Integer>.getSetter() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KMutableProperty0<Integer>.set(java.lang.Integer) |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KMutableProperty<Integer>.getSetter() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KProperty0<Integer>.getDelegate() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KProperty0<Integer>.getGetter() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KProperty<Integer>.getGetter() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KProperty<Integer>.isConst() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KProperty<Integer>.isLateinit() |
| reflection.kt:22:42:22:48 | ...::... | kotlin.reflect.KProperty<Object>.getGetter() |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KCallable<Character>.call(java.lang.Object[]) |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KCallable<Character>.callBy(java.util.Map) |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KCallable<Character>.getName() |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KCallable<Character>.getParameters() |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KCallable<Character>.getReturnType() |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KCallable<Character>.getTypeParameters() |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KCallable<Character>.getVisibility() |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KCallable<Character>.isAbstract() |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KCallable<Character>.isFinal() |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KCallable<Character>.isOpen() |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KCallable<Character>.isSuspend() |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KProperty1<String,Character>.getDelegate(java.lang.String) |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KProperty1<String,Character>.getGetter() |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KProperty<Character>.getGetter() |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KProperty<Character>.isConst() |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KProperty<Character>.isLateinit() |
| reflection.kt:50:13:50:28 | ...::... | kotlin.reflect.KProperty<Object>.getGetter() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KCallable<Character>.call(java.lang.Object[]) |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KCallable<Character>.callBy(java.util.Map) |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KCallable<Character>.getName() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KCallable<Character>.getParameters() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KCallable<Character>.getReturnType() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KCallable<Character>.getTypeParameters() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KCallable<Character>.getVisibility() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KCallable<Character>.isAbstract() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KCallable<Character>.isFinal() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KCallable<Character>.isOpen() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KCallable<Character>.isSuspend() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KProperty0<Character>.getDelegate() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KProperty0<Character>.getGetter() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KProperty<Character>.getGetter() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KProperty<Character>.isConst() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KProperty<Character>.isLateinit() |
| reflection.kt:51:13:51:28 | ...::... | kotlin.reflect.KProperty<Object>.getGetter() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KCallable<Integer>.call(java.lang.Object[]) |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KCallable<Integer>.callBy(java.util.Map) |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KCallable<Integer>.getName() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KCallable<Integer>.getParameters() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KCallable<Integer>.getReturnType() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KCallable<Integer>.getTypeParameters() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KCallable<Integer>.getVisibility() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KCallable<Integer>.isAbstract() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KCallable<Integer>.isFinal() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KCallable<Integer>.isOpen() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KCallable<Integer>.isSuspend() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KMutableProperty1<Generic<Integer>,Integer>.getSetter() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KMutableProperty<Integer>.getSetter() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KProperty1<Generic<Integer>,Integer>.getDelegate(Class1.Generic) |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KProperty1<Generic<Integer>,Integer>.getGetter() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KProperty<Integer>.getGetter() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KProperty<Integer>.isConst() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KProperty<Integer>.isLateinit() |
| reflection.kt:67:17:67:32 | ...::... | kotlin.reflect.KProperty<Object>.getGetter() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KCallable<Integer>.call(java.lang.Object[]) |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KCallable<Integer>.callBy(java.util.Map) |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KCallable<Integer>.getName() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KCallable<Integer>.getParameters() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KCallable<Integer>.getReturnType() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KCallable<Integer>.getTypeParameters() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KCallable<Integer>.getVisibility() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KCallable<Integer>.isAbstract() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KCallable<Integer>.isFinal() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KCallable<Integer>.isOpen() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KCallable<Integer>.isSuspend() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KMutableProperty0<Integer>.getSetter() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KMutableProperty<Integer>.getSetter() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KProperty0<Integer>.getDelegate() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KProperty0<Integer>.getGetter() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KProperty<Integer>.getGetter() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KProperty<Integer>.isConst() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KProperty<Integer>.isLateinit() |
| reflection.kt:68:17:68:34 | ...::... | kotlin.reflect.KProperty<Object>.getGetter() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KCallable<Integer>.call(java.lang.Object[]) |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KCallable<Integer>.callBy(java.util.Map) |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KCallable<Integer>.getName() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KCallable<Integer>.getParameters() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KCallable<Integer>.getReturnType() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KCallable<Integer>.getTypeParameters() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KCallable<Integer>.getVisibility() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KCallable<Integer>.isAbstract() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KCallable<Integer>.isFinal() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KCallable<Integer>.isOpen() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KCallable<Integer>.isSuspend() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KProperty0<Integer>.getDelegate() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KProperty0<Integer>.getGetter() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KProperty<Integer>.getGetter() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KProperty<Integer>.isConst() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KProperty<Integer>.isLateinit() |
| reflection.kt:70:17:70:30 | ...::... | kotlin.reflect.KProperty<Object>.getGetter() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KCallable<Integer>.call(java.lang.Object[]) |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KCallable<Integer>.callBy(java.util.Map) |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KCallable<Integer>.getName() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KCallable<Integer>.getParameters() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KCallable<Integer>.getReturnType() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KCallable<Integer>.getTypeParameters() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KCallable<Integer>.getVisibility() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KCallable<Integer>.isAbstract() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KCallable<Integer>.isFinal() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KCallable<Integer>.isOpen() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KCallable<Integer>.isSuspend() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KProperty0<Integer>.getDelegate() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KProperty0<Integer>.getGetter() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KProperty<Integer>.getGetter() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KProperty<Integer>.isConst() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KProperty<Integer>.isLateinit() |
| reflection.kt:71:17:71:34 | ...::... | kotlin.reflect.KProperty<Object>.getGetter() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KCallable<Integer>.call(java.lang.Object[]) |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KCallable<Integer>.callBy(java.util.Map) |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KCallable<Integer>.getName() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KCallable<Integer>.getParameters() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KCallable<Integer>.getReturnType() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KCallable<Integer>.getTypeParameters() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KCallable<Integer>.getVisibility() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KCallable<Integer>.isAbstract() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KCallable<Integer>.isFinal() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KCallable<Integer>.isOpen() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KCallable<Integer>.isSuspend() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KMutableProperty0<Integer>.getSetter() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KMutableProperty0<Integer>.set(java.lang.Integer) |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KMutableProperty<Integer>.getSetter() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KProperty0<Integer>.getDelegate() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KProperty0<Integer>.getGetter() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KProperty<Integer>.getGetter() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KProperty<Integer>.isConst() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KProperty<Integer>.isLateinit() |
| reflection.kt:72:17:72:35 | ...::... | kotlin.reflect.KProperty<Object>.getGetter() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KCallable<Integer>.call(java.lang.Object[]) |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KCallable<Integer>.callBy(java.util.Map) |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KCallable<Integer>.getName() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KCallable<Integer>.getParameters() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KCallable<Integer>.getReturnType() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KCallable<Integer>.getTypeParameters() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KCallable<Integer>.getVisibility() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KCallable<Integer>.isAbstract() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KCallable<Integer>.isFinal() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KCallable<Integer>.isOpen() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KCallable<Integer>.isSuspend() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KMutableProperty0<Integer>.getSetter() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KMutableProperty0<Integer>.set(java.lang.Integer) |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KMutableProperty<Integer>.getSetter() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KProperty0<Integer>.getDelegate() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KProperty0<Integer>.getGetter() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KProperty<Integer>.getGetter() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KProperty<Integer>.isConst() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KProperty<Integer>.isLateinit() |
| reflection.kt:109:17:109:27 | ...::... | kotlin.reflect.KProperty<Object>.getGetter() |

View File

@@ -87,3 +87,24 @@ query predicate modifiers(ClassInstanceExpr e, Method m, string modifier) {
}
query predicate compGenerated(Element e, int i) { compiler_generated(e, i) }
query predicate propertyReferenceOverrides(PropertyRefExpr e, Method m, string overridden) {
e.getAnonymousClass().getAMember() = m and
exists(Method n |
m.overrides(n) and
overridden = n.getDeclaringType().getQualifiedName() + "." + n.getSignature()
)
}
query predicate notImplementedInterfaceMembers(PropertyRefExpr e, string interfaceMember) {
exists(Interface i, Method interfaceMethod |
e.getAnonymousClass().extendsOrImplements+(i) and
i.getAMethod() = interfaceMethod and
interfaceMember = i.getQualifiedName() + "." + interfaceMethod.getSignature() and
not exists(Class c, Method classMethod |
e.getAnonymousClass().extendsOrImplements*(c) and
c.getAMethod() = classMethod and
classMethod.overrides(interfaceMethod)
)
)
}

View File

@@ -0,0 +1 @@
Violations of Best Practice/Naming Conventions/ConfusingOverloading.ql

View File

@@ -0,0 +1,9 @@
class C {
var p: Int
get() = 1
set(value) {}
fun fn() {
val prop = C::p
prop(this)
}
}

View File

@@ -0,0 +1,25 @@
package my.qltest.synth;
public class A {
void storeInArray(String x) { }
void storeTaintInArray(String x) { }
void storeValue(String x) { }
String readValue() { return null; }
String readArray() { return null; }
String source(String tag) { return "tainted"; }
void sink(Object o) { }
void stores() {
storeInArray(source("A"));
storeTaintInArray(source("B"));
storeValue(source("C"));
}
void reads() {
sink(readValue()); // $ hasValueFlow=C
sink(readArray()); // $ hasValueFlow=A hasTaintFlow=B hasTaintFlow=C
}
}

View File

@@ -0,0 +1,2 @@
failures
invalidModelRow

View File

@@ -0,0 +1,16 @@
import java
import TestUtilities.InlineFlowTest
import CsvValidation
class SummaryModelTest extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"my.qltest.synth;A;false;storeInArray;(String);;Argument[0];SyntheticGlobal[db1].ArrayElement;value;manual",
"my.qltest.synth;A;false;storeTaintInArray;(String);;Argument[0];SyntheticGlobal[db1].ArrayElement;taint;manual",
"my.qltest.synth;A;false;storeValue;(String);;Argument[0];SyntheticGlobal[db1];value;manual",
"my.qltest.synth;A;false;readValue;();;SyntheticGlobal[db1];ReturnValue;value;manual",
"my.qltest.synth;A;false;readArray;();;SyntheticGlobal[db1].ArrayElement;ReturnValue;value;manual",
]
}
}

View File

@@ -106,7 +106,7 @@ predicate useAfterCheck(FileCheck check, FileUse use) {
)
)
or
check.getBasicBlock().getASuccessor+() = use.getBasicBlock()
check.getBasicBlock().(ReachableBasicBlock).strictlyDominates(use.getBasicBlock())
}
from FileCheck check, FileUse use

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Removed some false positives from the `js/file-system-race` query by requiring that the file-check dominates the file-access.

View File

@@ -41,3 +41,8 @@ const filePath3 = createFile();
if (fs.existsSync(filePath3)) {
fs.readFileSync(filePath3); // OK - a read after an existence check is OK
}
const filePath4 = createFile();
while(Math.random() > 0.5) {
fs.open(filePath4); // OK - it is only ever opened here.
}

View File

@@ -82,7 +82,7 @@ predefined_entity_xml = """<?xml version="1.0"?>
# other setup
# we set up local Flask application so we can tests whether loading external resources
# works (such as SSRF from DTD-retrival works)
# works (such as SSRF from DTD-retrieval works)
app = Flask(__name__)
@app.route("/alive")
@@ -187,7 +187,7 @@ class TestSax():
@staticmethod
@expects_timeout
def test_quardratic_blowup_allowed_by_default():
def test_quadratic_blowup_allowed_by_default():
parser = xml.sax.make_parser()
parser.parse(StringIO(quadratic_blowup))
@@ -263,7 +263,7 @@ class TestEtree:
@staticmethod
@expects_timeout
def test_quardratic_blowup_allowed_by_default():
def test_quadratic_blowup_allowed_by_default():
parser = xml.etree.ElementTree.XMLParser()
_root = xml.etree.ElementTree.fromstring(quadratic_blowup, parser=parser)
@@ -324,7 +324,7 @@ class TestLxml:
assert "Detected an entity reference loop" in str(e)
@staticmethod
def test_quardratic_blowup_disabled_by_default():
def test_quadratic_blowup_disabled_by_default():
parser = lxml.etree.XMLParser()
try:
_root = lxml.etree.fromstring(quadratic_blowup, parser=parser)
@@ -465,7 +465,7 @@ class TestXmltodict:
assert d == {"lolz": None}, d
@staticmethod
def test_quardratic_blowup_disabled_by_default():
def test_quadratic_blowup_disabled_by_default():
d = xmltodict.parse(quadratic_blowup)
assert d == {"foo": None}, d
@@ -476,7 +476,7 @@ class TestXmltodict:
@staticmethod
@expects_timeout
def test_quardratic_blowup_manually_enabled():
def test_quadratic_blowup_manually_enabled():
xmltodict.parse(quadratic_blowup, disable_entities=False)
@staticmethod
@@ -524,7 +524,7 @@ class TestMinidom:
@staticmethod
@expects_timeout
def test_quardratic_blowup():
def test_quadratic_blowup():
xml.dom.minidom.parseString(quadratic_blowup)
@staticmethod
@@ -585,7 +585,7 @@ class TestPulldom:
@staticmethod
@expects_timeout
def test_quardratic_blowup():
def test_quadratic_blowup():
doc = xml.dom.pulldom.parseString(quadratic_blowup)
for event, node in doc:
pass
@@ -670,7 +670,7 @@ class TestExpat:
@staticmethod
@expects_timeout
def test_quardratic_blowup():
def test_quadratic_blowup():
parser = xml.parsers.expat.ParserCreate()
parser.Parse(quadratic_blowup, True)
@@ -699,7 +699,7 @@ class TestExpat:
assert char_data_recv == []
# there might be ways to make it vuln, but I did not investigate futher.
# there might be ways to make it vuln, but I did not investigate further.
@staticmethod
def test_dtd():
@@ -711,4 +711,4 @@ class TestExpat:
parser.Parse(dtd_retrieval, True)
assert hit_dtd == False
# there might be ways to make it vuln, but I did not investigate futher.
# there might be ways to make it vuln, but I did not investigate further.

View File

@@ -1,7 +1,7 @@
/**
* @id py/examples/override-method
* @name Override of method
* @description Finds methods that overide MyClass.methodName
* @description Finds methods that override MyClass.methodName
* @tags method
* override
*/

View File

@@ -2,7 +2,7 @@
### Minor Analysis Improvements
* Added the ability to refer to subscript operations in the API graph. It is now possible to write `response().getMember("cookies").getASubscript()` to find code like `resp.cookies["key"]` (assuming `response` returns an API node for reponse objects).
* Added the ability to refer to subscript operations in the API graph. It is now possible to write `response().getMember("cookies").getASubscript()` to find code like `resp.cookies["key"]` (assuming `response` returns an API node for response objects).
* Added modeling of creating Flask responses with `flask.jsonify`.
## 0.6.0

View File

@@ -2,5 +2,5 @@
### Minor Analysis Improvements
* Added the ability to refer to subscript operations in the API graph. It is now possible to write `response().getMember("cookies").getASubscript()` to find code like `resp.cookies["key"]` (assuming `response` returns an API node for reponse objects).
* Added the ability to refer to subscript operations in the API graph. It is now possible to write `response().getMember("cookies").getASubscript()` to find code like `resp.cookies["key"]` (assuming `response` returns an API node for response objects).
* Added modeling of creating Flask responses with `flask.jsonify`.

View File

@@ -1,7 +1,7 @@
# The Python libraries
The Python libraries are a collection of libraries for analysing Python code.
Everythng can be imported by importing `python.qll`.
Everything can be imported by importing `python.qll`.
## The analysis layers
@@ -15,10 +15,10 @@ The analysis is built up in layers. the stack looks like this:
## Avoiding non-monotonic recursion
Given the many interactivg layers, it is imprtant to decie which predicates are allowed to be mutually recursive in order to avoid non-monotonic recursion when negation is used to express the predicates.
As an example, we have defined local source as those whcih do not receive local flow. This means that the local flow relation is not allowed to be recursive with anything depending on local sources.
Given the many interacting layers, it is important to decide which predicates are allowed to be mutually recursive in order to avoid non-monotonic recursion when negation is used to express the predicates.
As an example, we have defined local source as those which do not receive local flow. This means that the local flow relation is not allowed to be recursive with anything depending on local sources.
Some particular reatrictions to keep in mind:
Some particular restrictions to keep in mind:
- Typetracking needs to use a local flow step not including summaries
- Typetracking needs to use a call graph not including summaries

View File

@@ -211,7 +211,7 @@ module API {
* Gets a node representing the `i`th parameter of the function represented by this node.
*
* This predicate may have multiple results when there are multiple invocations of this API component.
* Consider using `getAnInvocation()` if there is a need to distingiush between individual calls.
* Consider using `getAnInvocation()` if there is a need to distinguish between individual calls.
*/
Node getParameter(int i) { result = this.getASuccessor(Label::parameter(i)) }
@@ -219,7 +219,7 @@ module API {
* Gets the node representing the keyword parameter `name` of the function represented by this node.
*
* This predicate may have multiple results when there are multiple invocations of this API component.
* Consider using `getAnInvocation()` if there is a need to distingiush between individual calls.
* Consider using `getAnInvocation()` if there is a need to distinguish between individual calls.
*/
Node getKeywordParameter(string name) {
result = this.getASuccessor(Label::keywordParameter(name))

View File

@@ -7,7 +7,7 @@ int major_version() {
explicit_major_version(result)
or
not explicit_major_version(_) and
/* If there is more than one version, prefer 2 for backwards compatibilty */
/* If there is more than one version, prefer 2 for backwards compatibility */
(if py_flags_versioned("version.major", "2", "2") then result = 2 else result = 3)
}

View File

@@ -931,7 +931,7 @@ class NameConstantNode extends NameNode {
}
/** A control flow node correspoinding to a starred expression, `*a`. */
/** A control flow node corresponding to a starred expression, `*a`. */
class StarredNode extends ControlFlowNode {
StarredNode() { toAst(this) instanceof Starred }

View File

@@ -1,5 +1,5 @@
/**
* Provides an extension point for for modeling user-controlled data.
* Provides an extension point for modeling user-controlled data.
* Such data is often used as data-flow sources in security queries.
*/

View File

@@ -1,5 +1,5 @@
/**
* Provides an extension point for for modeling sensitive data, such as secrets, certificates, or passwords.
* Provides an extension point for modeling sensitive data, such as secrets, certificates, or passwords.
* Sensitive data can be interesting to use as data-flow sources in security queries.
*/

View File

@@ -205,12 +205,12 @@ module ArgumentPassing {
result = TCfgNode(call.getArgByName(unbind_string(argName)))
)
or
// a synthezised argument passed to the starred parameter (at position -1)
// a synthesized argument passed to the starred parameter (at position -1)
callable.getScope().hasVarArg() and
paramN = -1 and
result = TPosOverflowNode(call, callable)
or
// a synthezised argument passed to the doubly starred parameter (at position -2)
// a synthesized argument passed to the doubly starred parameter (at position -2)
callable.getScope().hasKwArg() and
paramN = -2 and
result = TKwOverflowNode(call, callable)
@@ -769,7 +769,7 @@ DataFlowCallable viableCallable(ExtractedDataFlowCall call) {
// A call to a library callable with a flow summary
// In this situation we can not resolve the callable from the call,
// as that would make data flow depend on type tracking.
// Instead we reolve the call from the summary.
// Instead we resolve the call from the summary.
exists(LibraryCallable callable |
result = TLibraryCallable(callable) and
call.getNode() = callable.getACall().getNode()

View File

@@ -453,13 +453,15 @@ predicate jumpStep(Node nodeFrom, Node nodeTo) {
jumpStepSharedWithTypeTracker(nodeFrom, nodeTo)
or
jumpStepNotSharedWithTypeTracker(nodeFrom, nodeTo)
or
FlowSummaryImpl::Private::Steps::summaryJumpStep(nodeFrom, nodeTo)
}
/**
* Set of jumpSteps that are shared with type-tracker implementation.
*
* For ORM modeling we want to add jumpsteps to global dataflow, but since these are
* based on type-trackers, it's important that these new ORM jumsteps are not used in
* based on type-trackers, it's important that these new ORM jumpsteps are not used in
* the type-trackers as well, as that would make evaluation of type-tracking recursive
* with the new jumpsteps.
*
@@ -485,7 +487,7 @@ predicate jumpStepSharedWithTypeTracker(Node nodeFrom, Node nodeTo) {
* Set of jumpSteps that are NOT shared with type-tracker implementation.
*
* For ORM modeling we want to add jumpsteps to global dataflow, but since these are
* based on type-trackers, it's important that these new ORM jumsteps are not used in
* based on type-trackers, it's important that these new ORM jumpsteps are not used in
* the type-trackers as well, as that would make evaluation of type-tracking recursive
* with the new jumpsteps.
*
@@ -668,7 +670,7 @@ predicate attributeStoreStep(Node nodeFrom, AttributeContent c, PostUpdateNode n
}
/**
* Holds if `nodeFrom` flows into the synthezised positional overflow argument (`nodeTo`)
* Holds if `nodeFrom` flows into the synthesized positional overflow argument (`nodeTo`)
* at the position indicated by `c`.
*/
predicate posOverflowStoreStep(CfgNode nodeFrom, TupleElementContent c, Node nodeTo) {
@@ -680,7 +682,7 @@ predicate posOverflowStoreStep(CfgNode nodeFrom, TupleElementContent c, Node nod
}
/**
* Holds if `nodeFrom` flows into the synthezised keyword overflow argument (`nodeTo`)
* Holds if `nodeFrom` flows into the synthesized keyword overflow argument (`nodeTo`)
* at the key indicated by `c`.
*/
predicate kwOverflowStoreStep(CfgNode nodeFrom, DictionaryElementContent c, Node nodeTo) {
@@ -814,7 +816,7 @@ predicate attributeReadStep(Node nodeFrom, AttributeContent c, AttrRead nodeTo)
/**
* Holds if `nodeFrom` is a dictionary argument being unpacked and `nodeTo` is the
* synthezised unpacked argument with the name indicated by `c`.
* synthesized unpacked argument with the name indicated by `c`.
*/
predicate kwUnpackReadStep(CfgNode nodeFrom, DictionaryElementContent c, Node nodeTo) {
exists(CallNode call, CallableValue callable, string name |

View File

@@ -61,6 +61,20 @@ module Public {
/** Gets a summary component for a return of kind `rk`. */
SummaryComponent return(ReturnKind rk) { result = TReturnSummaryComponent(rk) }
/** Gets a summary component for synthetic global `sg`. */
SummaryComponent syntheticGlobal(SyntheticGlobal sg) {
result = TSyntheticGlobalSummaryComponent(sg)
}
/**
* A synthetic global. This represents some form of global state, which
* summaries can read and write individually.
*/
abstract class SyntheticGlobal extends string {
bindingset[this]
SyntheticGlobal() { any() }
}
}
/**
@@ -256,6 +270,7 @@ module Private {
TParameterSummaryComponent(ArgumentPosition pos) or
TArgumentSummaryComponent(ParameterPosition pos) or
TReturnSummaryComponent(ReturnKind rk) or
TSyntheticGlobalSummaryComponent(SummaryComponent::SyntheticGlobal sg) or
TWithoutContentSummaryComponent(ContentSet c) or
TWithContentSummaryComponent(ContentSet c)
@@ -563,6 +578,11 @@ module Private {
getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
s.tail())), rk)
)
or
exists(SummaryComponent::SyntheticGlobal sg |
head = TSyntheticGlobalSummaryComponent(sg) and
result = getSyntheticGlobalType(sg)
)
)
or
n = summaryNodeOutputState(c, s) and
@@ -582,6 +602,11 @@ module Private {
getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
s.tail())), pos)
)
or
exists(SummaryComponent::SyntheticGlobal sg |
head = TSyntheticGlobalSummaryComponent(sg) and
result = getSyntheticGlobalType(sg)
)
)
)
}
@@ -692,6 +717,18 @@ module Private {
)
}
/**
* Holds if there is a jump step from `pred` to `succ`, which is synthesized
* from a flow summary.
*/
predicate summaryJumpStep(Node pred, Node succ) {
exists(SummaryComponentStack s |
s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and
pred = summaryNodeOutputState(_, s) and
succ = summaryNodeInputState(_, s)
)
}
/**
* Holds if values stored inside content `c` are cleared at `n`. `n` is a
* synthesized summary node, so in order for values to be cleared at calls
@@ -871,18 +908,28 @@ module Private {
AccessPathRange() { relevantSpec(this) }
}
/** Holds if specification component `c` parses as parameter `n`. */
/** Holds if specification component `token` parses as parameter `pos`. */
predicate parseParam(AccessPathToken token, ArgumentPosition pos) {
token.getName() = "Parameter" and
pos = parseParamBody(token.getAnArgument())
}
/** Holds if specification component `c` parses as argument `n`. */
/** Holds if specification component `token` parses as argument `pos`. */
predicate parseArg(AccessPathToken token, ParameterPosition pos) {
token.getName() = "Argument" and
pos = parseArgBody(token.getAnArgument())
}
/** Holds if specification component `token` parses as synthetic global `sg`. */
predicate parseSynthGlobal(AccessPathToken token, string sg) {
token.getName() = "SyntheticGlobal" and
sg = token.getAnArgument()
}
private class SyntheticGlobalFromAccessPath extends SummaryComponent::SyntheticGlobal {
SyntheticGlobalFromAccessPath() { parseSynthGlobal(_, this) }
}
private SummaryComponent interpretComponent(AccessPathToken token) {
exists(ParameterPosition pos |
parseArg(token, pos) and result = SummaryComponent::argument(pos)
@@ -894,6 +941,10 @@ module Private {
or
token = "ReturnValue" and result = SummaryComponent::return(getReturnValueKind())
or
exists(string sg |
parseSynthGlobal(token, sg) and result = SummaryComponent::syntheticGlobal(sg)
)
or
result = interpretComponentSpecific(token)
}

View File

@@ -12,15 +12,15 @@
*
* Having both extracted and non-extracted callables means that we now have three types of calls:
* - Extracted calls to extracted callables, either `NormalCall` or `SpecialCall`. These are handled by standard data flow.
* - Extracted calls to non-extracted callables, `LibraryCall`. These are handled by loking up the relevant summary when the
* global data flwo graph is connected up via `getViableCallable`.
* - Extracted calls to non-extracted callables, `LibraryCall`. These are handled by looking up the relevant summary when the
* global data flow graph is connected up via `getViableCallable`.
* - Non-extracted calls, `SummaryCall`. These are synthesised by the flow summary framework.
*
* The first two can be referred to as `ExtractedDataFlowCall`. In fact, `LibraryCall` is a subclass of `NormalCall`, where
* `getCallable` is set to `none()`. The member predicate `ExtractedDataFlowCall::getCallable` is _not_ the mechanism for
* call resolution in global data flow. That mechanism is `getViableCallable`.
* Resolving a call to a non-extracted callable goes via `LibraryCallable::getACall`, which may involve type tracking.
* To avoid that type tracking becomes mutualy recursive with data flow, type tracking must use a call graph not including summaries.
* To avoid that type tracking becomes mutually recursive with data flow, type tracking must use a call graph not including summaries.
* Type tracking sees the callgraph given by `ExtractedDataFlowCall::getACallable`.
*
* We do not support summaries of special methods via the special methods framework,
@@ -73,6 +73,9 @@ DataFlowType getCallbackParameterType(DataFlowType t, int i) { any() }
*/
DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { any() }
/** Gets the type of synthetic global `sg`. */
DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) { any() }
/**
* Holds if an external flow summary exists for `c` with input specification
* `input`, output specification `output`, kind `kind`, and a flag `generated`

View File

@@ -52,14 +52,14 @@
* Note that an empty access path means that the value we are tracking flows directly to the element.
*
*
* The `TIterableSequence(sequence)` is at this point superflous but becomes useful when handling recursive
* The `TIterableSequence(sequence)` is at this point superfluous but becomes useful when handling recursive
* structures in the LHS, where `sequence` is some internal sequence node. We can have a uniform treatment
* by always having these two synthetic nodes. So we transfer to (or, in the recursive case, read into)
* `TIterableSequence(sequence)`, from which we take a read step to `TIterableElement(sequence)` and then a
* store step to `sequence`.
*
* This allows the unknown content from the RHS to be read into `TIterableElement(sequence)` and tuple content
* to then be stored into `sequence`. If the content is already tuple content, this inderection creates crosstalk
* to then be stored into `sequence`. If the content is already tuple content, this indirection creates crosstalk
* between indices. Therefore, tuple content is never read into `TIterableElement(sequence)`; it is instead
* transferred directly from `TIterableSequence(sequence)` to `sequence` via a flow step. Such a flow step will
* also transfer other content, but only tuple content is further read from `sequence` into its elements.

View File

@@ -185,7 +185,7 @@ private module Cached {
/**
* Holds if `source` is a `LocalSourceNode` that can reach `sink` via local flow steps.
*
* The slightly backwards parametering ordering is to force correct indexing.
* The slightly backwards parameter ordering is to force correct indexing.
*/
cached
predicate hasLocalSource(Node sink, LocalSourceNode source) {

View File

@@ -250,7 +250,7 @@ class TaintTrackingImplementation extends string {
}
/**
* Hold if taint flows to `src` to `(node, context, path, kind)` in a single step, labelled with `egdeLabel` with this configuration.
* Hold if taint flows to `src` to `(node, context, path, kind)` in a single step, labelled with `edgeLabel` with this configuration.
* `edgeLabel` is purely informative.
*/
predicate flowStep(

View File

@@ -31,7 +31,7 @@ module Aioch {
}
/**
* A call to any of the the execute methods on a `aioch.Client`, which are just async
* A call to any of the execute methods on a `aioch.Client`, which are just async
* versions of the methods in the `clickhouse-driver` PyPI package.
*
* See

View File

@@ -45,7 +45,7 @@ module AiohttpWebModel {
}
/** Gets a reference to an `aiohttp.web.UrlDispatcher` instance. */
API::Node urlDispathcerInstance() {
API::Node urlDispatcherInstance() {
result = API::moduleImport("aiohttp").getMember("web").getMember("UrlDispatcher").getReturn()
or
result = applicationInstance().getMember("router")
@@ -170,7 +170,7 @@ module AiohttpWebModel {
funcName = "route" and
routeArgsStart = 1
|
this = urlDispathcerInstance().getMember("add_" + funcName).getACall()
this = urlDispatcherInstance().getMember("add_" + funcName).getACall()
or
this = API::moduleImport("aiohttp").getMember("web").getMember(funcName).getACall()
)

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