mirror of
https://github.com/github/codeql.git
synced 2026-05-20 14:17:11 +02:00
Compare commits
19 Commits
mbg/go/add
...
codeql-cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2daf50500c | ||
|
|
2f058ffb4d | ||
|
|
711c474049 | ||
|
|
ce31f8641a | ||
|
|
727a38a409 | ||
|
|
661e68dab5 | ||
|
|
7e2a775a2a | ||
|
|
967963a653 | ||
|
|
eaef544a26 | ||
|
|
40ff75db07 | ||
|
|
a8d240dd72 | ||
|
|
ac394dc80c | ||
|
|
b1e0bc03ab | ||
|
|
367ecf75d5 | ||
|
|
2aa093c95c | ||
|
|
92e91f596f | ||
|
|
a67218a027 | ||
|
|
19539ab6d8 | ||
|
|
2b2ea597ce |
@@ -88,46 +88,123 @@
|
||||
"IR Instruction": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll"
|
||||
],
|
||||
"IR IRBlock": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll"
|
||||
],
|
||||
"IR IRVariable": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRVariable.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IRVariable.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRVariable.qll"
|
||||
],
|
||||
"IR IRFunction": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRFunction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRFunction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRFunction.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRFunction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IRFunction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRFunction.qll"
|
||||
],
|
||||
"IR Operand": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Operand.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/Operand.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll"
|
||||
],
|
||||
"IR IRType": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/IRType.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/IRType.qll"
|
||||
],
|
||||
"IR IRConfiguration": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/IRConfiguration.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/IRConfiguration.qll"
|
||||
],
|
||||
"IR UseSoundEscapeAnalysis": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/UseSoundEscapeAnalysis.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/UseSoundEscapeAnalysis.qll"
|
||||
],
|
||||
"IR IRFunctionBase": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/IRFunctionBase.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/internal/IRFunctionBase.qll"
|
||||
],
|
||||
"IR Operand Tag": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/OperandTag.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/internal/OperandTag.qll"
|
||||
],
|
||||
"IR TInstruction": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll"
|
||||
],
|
||||
"IR TIRVariable": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/internal/TIRVariable.qll"
|
||||
],
|
||||
"IR IR": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IR.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IR.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IR.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IR.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IR.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IR.qll"
|
||||
],
|
||||
"IR IRConsistency": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRConsistency.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRConsistency.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRConsistency.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRConsistency.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/IRConsistency.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRConsistency.qll"
|
||||
],
|
||||
"IR PrintIR": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/PrintIR.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/PrintIR.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/PrintIR.qll"
|
||||
],
|
||||
"IR IntegerConstant": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/internal/IntegerConstant.qll",
|
||||
"csharp/ql/src/experimental/ir/internal/IntegerConstant.qll"
|
||||
],
|
||||
"IR IntegerInteval": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/internal/IntegerInterval.qll",
|
||||
"csharp/ql/src/experimental/ir/internal/IntegerInterval.qll"
|
||||
],
|
||||
"IR IntegerPartial": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/internal/IntegerPartial.qll",
|
||||
"csharp/ql/src/experimental/ir/internal/IntegerPartial.qll"
|
||||
],
|
||||
"IR Overlap": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/internal/Overlap.qll",
|
||||
"csharp/ql/src/experimental/ir/internal/Overlap.qll"
|
||||
],
|
||||
"IR EdgeKind": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/EdgeKind.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/EdgeKind.qll"
|
||||
],
|
||||
"IR MemoryAccessKind": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/MemoryAccessKind.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/MemoryAccessKind.qll"
|
||||
],
|
||||
"IR TempVariableTag": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/TempVariableTag.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/TempVariableTag.qll"
|
||||
],
|
||||
"IR Opcode": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/Opcode.qll"
|
||||
],
|
||||
"IR SSAConsistency": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll"
|
||||
],
|
||||
"C++ IR InstructionImports": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionImports.qll",
|
||||
@@ -175,7 +252,8 @@
|
||||
],
|
||||
"SSA AliasAnalysis": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll"
|
||||
],
|
||||
"SSA PrintAliasAnalysis": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintAliasAnalysis.qll",
|
||||
@@ -190,28 +268,44 @@
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingImports.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingImports.qll"
|
||||
],
|
||||
"IR SSA SimpleSSA": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll"
|
||||
],
|
||||
"IR AliasConfiguration (unaliased_ssa)": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasConfiguration.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/AliasConfiguration.qll"
|
||||
],
|
||||
"IR SSA SSAConstruction": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll"
|
||||
],
|
||||
"IR SSA PrintSSA": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/PrintSSA.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintSSA.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/PrintSSA.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/PrintSSA.qll"
|
||||
],
|
||||
"IR ValueNumberInternal": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll"
|
||||
],
|
||||
"C++ IR ValueNumber": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/ValueNumbering.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/ValueNumbering.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/ValueNumbering.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/gvn/ValueNumbering.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll"
|
||||
],
|
||||
"C++ IR PrintValueNumbering": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/PrintValueNumbering.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/PrintValueNumbering.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/PrintValueNumbering.qll"
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/PrintValueNumbering.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/gvn/PrintValueNumbering.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/PrintValueNumbering.qll"
|
||||
],
|
||||
"C++ IR ConstantAnalysis": [
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/constant/ConstantAnalysis.qll",
|
||||
@@ -239,6 +333,38 @@
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/reachability/PrintDominance.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/reachability/PrintDominance.qll"
|
||||
],
|
||||
"C# IR InstructionImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/InstructionImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/InstructionImports.qll"
|
||||
],
|
||||
"C# IR IRImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/IRImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/IRImports.qll"
|
||||
],
|
||||
"C# IR IRBlockImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/IRBlockImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/IRBlockImports.qll"
|
||||
],
|
||||
"C# IR IRFunctionImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/IRFunctionImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/IRFunctionImports.qll"
|
||||
],
|
||||
"C# IR IRVariableImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/IRVariableImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/IRVariableImports.qll"
|
||||
],
|
||||
"C# IR OperandImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/OperandImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/OperandImports.qll"
|
||||
],
|
||||
"C# IR PrintIRImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/internal/PrintIRImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/PrintIRImports.qll"
|
||||
],
|
||||
"C# IR ValueNumberingImports": [
|
||||
"csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingImports.qll",
|
||||
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingImports.qll"
|
||||
],
|
||||
"C# ControlFlowReachability": [
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/ControlFlowReachability.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/ControlFlowReachability.qll"
|
||||
@@ -372,4 +498,4 @@
|
||||
"python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ext.yml",
|
||||
"python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ext.yml"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.12.7
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added destructors for named objects to the intermediate representation.
|
||||
|
||||
## 0.12.6
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added destructors for named objects to the intermediate representation.
|
||||
## 0.12.7
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added destructors for named objects to the intermediate representation.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.12.6
|
||||
lastReleaseVersion: 0.12.7
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.12.7-dev
|
||||
version: 0.12.7
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -10,12 +10,13 @@ private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs as FIO
|
||||
private import semmle.code.cpp.ir.internal.IRCppLanguage
|
||||
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
|
||||
private import DataFlowPrivate
|
||||
private import ssa0.SsaInternals as SsaInternals0
|
||||
import SsaInternalsCommon
|
||||
|
||||
private module SourceVariables {
|
||||
cached
|
||||
private newtype TSourceVariable =
|
||||
TMkSourceVariable(BaseSourceVariable base, int ind) {
|
||||
TMkSourceVariable(SsaInternals0::SourceVariable base, int ind) {
|
||||
ind = [0 .. countIndirectionsForCppType(base.getLanguageType()) + 1]
|
||||
}
|
||||
|
||||
@@ -29,7 +30,7 @@ private module SourceVariables {
|
||||
}
|
||||
|
||||
class SourceVariable extends TSourceVariable {
|
||||
BaseSourceVariable base;
|
||||
SsaInternals0::SourceVariable base;
|
||||
int ind;
|
||||
|
||||
SourceVariable() { this = TMkSourceVariable(base, ind) }
|
||||
@@ -41,7 +42,7 @@ private module SourceVariables {
|
||||
* Gets the base source variable (i.e., the variable without any
|
||||
* indirections) of this source variable.
|
||||
*/
|
||||
BaseSourceVariable getBaseVariable() { result = base }
|
||||
SsaInternals0::SourceVariable getBaseVariable() { result = base }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = repeatStars(this.getIndirection()) + base.toString() }
|
||||
@@ -104,7 +105,16 @@ predicate hasRawIndirectInstruction(Instruction instr, int indirectionIndex) {
|
||||
cached
|
||||
private newtype TDefOrUseImpl =
|
||||
TDefImpl(BaseSourceVariableInstruction base, Operand address, int indirectionIndex) {
|
||||
isDef(_, _, address, base, _, indirectionIndex)
|
||||
isDef(_, _, address, base, _, indirectionIndex) and
|
||||
(
|
||||
// We only include the definition if the SSA pruning stage
|
||||
// concluded that the definition is live after the write.
|
||||
any(SsaInternals0::Def def).getAddressOperand() = address
|
||||
or
|
||||
// Since the pruning stage doesn't know about global variables we can't use the above check to
|
||||
// rule out dead assignments to globals.
|
||||
base.(VariableAddressInstruction).getAstVariable() instanceof GlobalLikeVariable
|
||||
)
|
||||
} or
|
||||
TUseImpl(BaseSourceVariableInstruction base, Operand operand, int indirectionIndex) {
|
||||
isUse(_, operand, base, _, indirectionIndex) and
|
||||
@@ -123,7 +133,8 @@ private newtype TDefOrUseImpl =
|
||||
TIteratorDef(
|
||||
Operand iteratorDerefAddress, BaseSourceVariableInstruction container, int indirectionIndex
|
||||
) {
|
||||
isIteratorDef(container, iteratorDerefAddress, _, _, indirectionIndex)
|
||||
isIteratorDef(container, iteratorDerefAddress, _, _, indirectionIndex) and
|
||||
any(SsaInternals0::Def def | def.isIteratorDef()).getAddressOperand() = iteratorDerefAddress
|
||||
} or
|
||||
TIteratorUse(
|
||||
Operand iteratorAddress, BaseSourceVariableInstruction container, int indirectionIndex
|
||||
@@ -973,6 +984,17 @@ predicate fromPhiNode(SsaPhiNode nodeFrom, Node nodeTo) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is a write at index `i` in basic block `bb` to variable `v` that's
|
||||
* subsequently read (as determined by the SSA pruning stage).
|
||||
*/
|
||||
private predicate variableWriteCand(IRBlock bb, int i, SourceVariable v) {
|
||||
exists(SsaInternals0::Def def, SsaInternals0::SourceVariable v0 |
|
||||
def.asDefOrUse().hasIndexInBlock(bb, i, v0) and
|
||||
v0 = v.getBaseVariable()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate sourceVariableIsGlobal(
|
||||
SourceVariable sv, GlobalLikeVariable global, IRFunction func, int indirectionIndex
|
||||
) {
|
||||
@@ -996,14 +1018,16 @@ private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
predicate variableWrite(IRBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
DataFlowImplCommon::forceCachingInSameStage() and
|
||||
(
|
||||
exists(DefImpl def | def.hasIndexInBlock(bb, i, v) |
|
||||
if def.isCertain() then certain = true else certain = false
|
||||
)
|
||||
or
|
||||
exists(GlobalDefImpl global |
|
||||
global.hasIndexInBlock(bb, i, v) and
|
||||
certain = true
|
||||
)
|
||||
variableWriteCand(bb, i, v) or
|
||||
sourceVariableIsGlobal(v, _, _, _)
|
||||
) and
|
||||
exists(DefImpl def | def.hasIndexInBlock(bb, i, v) |
|
||||
if def.isCertain() then certain = true else certain = false
|
||||
)
|
||||
or
|
||||
exists(GlobalDefImpl global |
|
||||
global.hasIndexInBlock(bb, i, v) and
|
||||
certain = true
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,347 @@
|
||||
/**
|
||||
* This module defines an initial SSA pruning stage that doesn't take
|
||||
* indirections into account.
|
||||
*/
|
||||
|
||||
private import codeql.ssa.Ssa as SsaImplCommon
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplCommon as DataFlowImplCommon
|
||||
private import semmle.code.cpp.models.interfaces.Allocation as Alloc
|
||||
private import semmle.code.cpp.models.interfaces.DataFlow as DataFlow
|
||||
private import semmle.code.cpp.ir.implementation.raw.internal.SideEffects as SideEffects
|
||||
private import semmle.code.cpp.ir.internal.IRCppLanguage
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||
private import semmle.code.cpp.ir.dataflow.internal.SsaInternalsCommon
|
||||
|
||||
private module SourceVariables {
|
||||
class SourceVariable extends BaseSourceVariable {
|
||||
/**
|
||||
* Gets the base source variable of this `SourceVariable`.
|
||||
*/
|
||||
BaseSourceVariable getBaseVariable() { result = this }
|
||||
}
|
||||
}
|
||||
|
||||
import SourceVariables
|
||||
|
||||
private newtype TDefOrUseImpl =
|
||||
TDefImpl(Operand address) { isDef(_, _, address, _, _, _) } or
|
||||
TUseImpl(Operand operand) {
|
||||
isUse(_, operand, _, _, _) and
|
||||
not isDef(true, _, operand, _, _, _)
|
||||
} or
|
||||
TIteratorDef(BaseSourceVariableInstruction container, Operand iteratorAddress) {
|
||||
isIteratorDef(container, iteratorAddress, _, _, _)
|
||||
} or
|
||||
TIteratorUse(BaseSourceVariableInstruction container, Operand iteratorAddress) {
|
||||
isIteratorUse(container, iteratorAddress, _, _)
|
||||
} or
|
||||
TFinalParameterUse(Parameter p) {
|
||||
any(Indirection indirection).getType() = p.getUnspecifiedType()
|
||||
}
|
||||
|
||||
abstract private class DefOrUseImpl extends TDefOrUseImpl {
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
|
||||
/** Gets the block of this definition or use. */
|
||||
final IRBlock getBlock() { this.hasIndexInBlock(result, _) }
|
||||
|
||||
/** Holds if this definition or use has index `index` in block `block`. */
|
||||
abstract predicate hasIndexInBlock(IRBlock block, int index);
|
||||
|
||||
final predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) {
|
||||
this.hasIndexInBlock(block, index) and
|
||||
sv = this.getSourceVariable()
|
||||
}
|
||||
|
||||
/** Gets the location of this element. */
|
||||
abstract Cpp::Location getLocation();
|
||||
|
||||
abstract BaseSourceVariableInstruction getBase();
|
||||
|
||||
final BaseSourceVariable getBaseSourceVariable() {
|
||||
result = this.getBase().getBaseSourceVariable()
|
||||
}
|
||||
|
||||
/** Gets the variable that is defined or used. */
|
||||
final SourceVariable getSourceVariable() {
|
||||
result.getBaseVariable() = this.getBaseSourceVariable()
|
||||
}
|
||||
|
||||
abstract predicate isCertain();
|
||||
}
|
||||
|
||||
abstract class DefImpl extends DefOrUseImpl {
|
||||
Operand address;
|
||||
|
||||
Operand getAddressOperand() { result = address }
|
||||
|
||||
abstract Node0Impl getValue();
|
||||
|
||||
override string toString() { result = address.toString() }
|
||||
|
||||
override Cpp::Location getLocation() { result = this.getAddressOperand().getLocation() }
|
||||
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
this.getAddressOperand().getUse() = block.getInstruction(index)
|
||||
}
|
||||
}
|
||||
|
||||
private class DirectDef extends DefImpl, TDefImpl {
|
||||
DirectDef() { this = TDefImpl(address) }
|
||||
|
||||
override BaseSourceVariableInstruction getBase() { isDef(_, _, address, result, _, _) }
|
||||
|
||||
override Node0Impl getValue() { isDef(_, result, address, _, _, _) }
|
||||
|
||||
override predicate isCertain() { isDef(true, _, address, _, _, _) }
|
||||
}
|
||||
|
||||
private class IteratorDef extends DefImpl, TIteratorDef {
|
||||
BaseSourceVariableInstruction container;
|
||||
|
||||
IteratorDef() { this = TIteratorDef(container, address) }
|
||||
|
||||
override BaseSourceVariableInstruction getBase() { result = container }
|
||||
|
||||
override Node0Impl getValue() { isIteratorDef(_, address, result, _, _) }
|
||||
|
||||
override predicate isCertain() { none() }
|
||||
}
|
||||
|
||||
abstract class UseImpl extends DefOrUseImpl { }
|
||||
|
||||
abstract private class OperandBasedUse extends UseImpl {
|
||||
Operand operand;
|
||||
|
||||
override string toString() { result = operand.toString() }
|
||||
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
// Ideally, this would just be implemented as:
|
||||
// ```
|
||||
// operand.getUse() = block.getInstruction(index)
|
||||
// ```
|
||||
// but because the IR generated for a snippet such as
|
||||
// ```
|
||||
// int x = *p++;
|
||||
// ```
|
||||
// looks like
|
||||
// ```
|
||||
// r1(glval<int>) = VariableAddress[x] :
|
||||
// r2(glval<int *>) = VariableAddress[p] :
|
||||
// r3(int *) = Load[p] : &:r2, m1
|
||||
// r4(int) = Constant[1] :
|
||||
// r5(int *) = PointerAdd[4] : r3, r4
|
||||
// m3(int *) = Store[p] : &:r2, r5
|
||||
// r6(int *) = CopyValue : r3
|
||||
// r7(int) = Load[?] : &:r6, ~m2
|
||||
// m2(int) = Store[x] : &:r1, r7
|
||||
// ```
|
||||
// we need to ensure that the `r3` operand of the `CopyValue` instruction isn't seen as a fresh use
|
||||
// of `p` that happens after the increment. So if the base instruction of this use comes from a
|
||||
// post-fix crement operation we set the index of the SSA use that wraps the `r3` operand at the
|
||||
// `CopyValue` instruction to be the same index as the `r3` operand at the `PointerAdd` instruction.
|
||||
// This ensures that the SSA library doesn't create flow from the `PointerAdd` to `r6`.
|
||||
exists(BaseSourceVariableInstruction base | base = this.getBase() |
|
||||
if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
|
||||
then
|
||||
exists(Operand op |
|
||||
op =
|
||||
min(Operand cand, int i |
|
||||
isUse(_, cand, base, _, _) and
|
||||
block.getInstruction(i) = cand.getUse()
|
||||
|
|
||||
cand order by i
|
||||
) and
|
||||
block.getInstruction(index) = op.getUse()
|
||||
)
|
||||
else operand.getUse() = block.getInstruction(index)
|
||||
)
|
||||
}
|
||||
|
||||
final override Cpp::Location getLocation() { result = operand.getLocation() }
|
||||
}
|
||||
|
||||
private class DirectUse extends OperandBasedUse, TUseImpl {
|
||||
DirectUse() { this = TUseImpl(operand) }
|
||||
|
||||
override BaseSourceVariableInstruction getBase() { isUse(_, operand, result, _, _) }
|
||||
|
||||
override predicate isCertain() { isUse(true, operand, _, _, _) }
|
||||
}
|
||||
|
||||
private class IteratorUse extends OperandBasedUse, TIteratorUse {
|
||||
BaseSourceVariableInstruction container;
|
||||
|
||||
IteratorUse() { this = TIteratorUse(container, operand) }
|
||||
|
||||
override BaseSourceVariableInstruction getBase() { result = container }
|
||||
|
||||
override predicate isCertain() { none() }
|
||||
}
|
||||
|
||||
private class FinalParameterUse extends UseImpl, TFinalParameterUse {
|
||||
Parameter p;
|
||||
|
||||
FinalParameterUse() { this = TFinalParameterUse(p) }
|
||||
|
||||
override string toString() { result = p.toString() }
|
||||
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
// Ideally, this should always be a `ReturnInstruction`, but if
|
||||
// someone forgets to write a `return` statement in a function
|
||||
// with a non-void return type we generate an `UnreachedInstruction`.
|
||||
// In this case we still want to generate flow out of such functions
|
||||
// if they write to a parameter. So we pick the index of the
|
||||
// `UnreachedInstruction` as the index of this use.
|
||||
// Note that a function may have both a `ReturnInstruction` and an
|
||||
// `UnreachedInstruction`. If that's the case this predicate will
|
||||
// return multiple results. I don't think this is detrimental to
|
||||
// performance, however.
|
||||
exists(Instruction return |
|
||||
return instanceof ReturnInstruction or
|
||||
return instanceof UnreachedInstruction
|
||||
|
|
||||
block.getInstruction(index) = return and
|
||||
return.getEnclosingFunction() = p.getFunction()
|
||||
)
|
||||
}
|
||||
|
||||
final override Cpp::Location getLocation() {
|
||||
// Parameters can have multiple locations. When there's a unique location we use
|
||||
// that one, but if multiple locations exist we default to an unknown location.
|
||||
result = unique( | | p.getLocation())
|
||||
or
|
||||
not exists(unique( | | p.getLocation())) and
|
||||
result instanceof UnknownDefaultLocation
|
||||
}
|
||||
|
||||
override BaseSourceVariableInstruction getBase() {
|
||||
exists(InitializeParameterInstruction init |
|
||||
init.getParameter() = p and
|
||||
// This is always a `VariableAddressInstruction`
|
||||
result = init.getAnOperand().getDef()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isCertain() { any() }
|
||||
}
|
||||
|
||||
private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
import InputSigCommon
|
||||
import SourceVariables
|
||||
|
||||
/**
|
||||
* Holds if the `i`'th write in block `bb` writes to the variable `v`.
|
||||
* `certain` is `true` if the write is guaranteed to overwrite the entire variable.
|
||||
*/
|
||||
predicate variableWrite(IRBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
DataFlowImplCommon::forceCachingInSameStage() and
|
||||
exists(DefImpl def | def.hasIndexInBlock(bb, i, v) |
|
||||
if def.isCertain() then certain = true else certain = false
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `i`'th read in block `bb` reads to the variable `v`.
|
||||
* `certain` is `true` if the read is guaranteed.
|
||||
*/
|
||||
predicate variableRead(IRBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
exists(UseImpl use | use.hasIndexInBlock(bb, i, v) |
|
||||
if use.isCertain() then certain = true else certain = false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TSsaDefOrUse =
|
||||
TDefOrUse(DefOrUseImpl defOrUse) {
|
||||
defOrUse instanceof UseImpl
|
||||
or
|
||||
// If `defOrUse` is a definition we only include it if the
|
||||
// SSA library concludes that it's live after the write.
|
||||
exists(DefinitionExt def, SourceVariable sv, IRBlock bb, int i |
|
||||
def.definesAt(sv, bb, i, _) and
|
||||
defOrUse.(DefImpl).hasIndexInBlock(bb, i, sv)
|
||||
)
|
||||
} or
|
||||
TPhi(PhiNode phi)
|
||||
|
||||
abstract private class SsaDefOrUse extends TSsaDefOrUse {
|
||||
string toString() { result = "SsaDefOrUse" }
|
||||
|
||||
DefOrUseImpl asDefOrUse() { none() }
|
||||
|
||||
PhiNode asPhi() { none() }
|
||||
|
||||
abstract Location getLocation();
|
||||
}
|
||||
|
||||
class DefOrUse extends TDefOrUse, SsaDefOrUse {
|
||||
DefOrUseImpl defOrUse;
|
||||
|
||||
DefOrUse() { this = TDefOrUse(defOrUse) }
|
||||
|
||||
final override DefOrUseImpl asDefOrUse() { result = defOrUse }
|
||||
|
||||
final override Location getLocation() { result = defOrUse.getLocation() }
|
||||
|
||||
final SourceVariable getSourceVariable() { result = defOrUse.getSourceVariable() }
|
||||
}
|
||||
|
||||
class Phi extends TPhi, SsaDefOrUse {
|
||||
PhiNode phi;
|
||||
|
||||
Phi() { this = TPhi(phi) }
|
||||
|
||||
final override PhiNode asPhi() { result = phi }
|
||||
|
||||
final override Location getLocation() { result = phi.getBasicBlock().getLocation() }
|
||||
}
|
||||
|
||||
class UseOrPhi extends SsaDefOrUse {
|
||||
UseOrPhi() {
|
||||
this.asDefOrUse() instanceof UseImpl
|
||||
or
|
||||
this instanceof Phi
|
||||
}
|
||||
|
||||
final override Location getLocation() {
|
||||
result = this.asDefOrUse().getLocation() or result = this.(Phi).getLocation()
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = this.asDefOrUse().toString()
|
||||
or
|
||||
this instanceof Phi and
|
||||
result = "Phi"
|
||||
}
|
||||
}
|
||||
|
||||
class Def extends DefOrUse {
|
||||
override DefImpl defOrUse;
|
||||
|
||||
Operand getAddressOperand() { result = defOrUse.getAddressOperand() }
|
||||
|
||||
Instruction getAddress() { result = this.getAddressOperand().getDef() }
|
||||
|
||||
Node0Impl getValue() { result = defOrUse.getValue() }
|
||||
|
||||
override string toString() { result = this.asDefOrUse().toString() }
|
||||
|
||||
BaseSourceVariableInstruction getBase() { result = defOrUse.getBase() }
|
||||
|
||||
predicate isIteratorDef() { defOrUse instanceof IteratorDef }
|
||||
}
|
||||
|
||||
private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
|
||||
|
||||
class PhiNode extends SsaImpl::DefinitionExt {
|
||||
PhiNode() {
|
||||
this instanceof SsaImpl::PhiNode or
|
||||
this instanceof SsaImpl::PhiReadNode
|
||||
}
|
||||
}
|
||||
|
||||
class DefinitionExt = SsaImpl::DefinitionExt;
|
||||
@@ -96,9 +96,6 @@ private predicate ignoreExprAndDescendants(Expr expr) {
|
||||
exists(BuiltInVarArgsStart vaStartExpr |
|
||||
vaStartExpr.getLastNamedParameter().getFullyConverted() = expr
|
||||
)
|
||||
or
|
||||
// suppress destructors of temporary variables until proper support is added for them.
|
||||
exists(Expr parent | parent.getAnImplicitDestructorCall() = expr)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -747,13 +744,9 @@ newtype TTranslatedElement =
|
||||
// The declaration/initialization part of a `ConditionDeclExpr`
|
||||
TTranslatedConditionDecl(ConditionDeclExpr expr) { not ignoreExpr(expr) } or
|
||||
// The side effects of a `Call`
|
||||
TTranslatedCallSideEffects(CallOrAllocationExpr expr) {
|
||||
not ignoreExpr(expr) and
|
||||
not ignoreSideEffects(expr)
|
||||
} or
|
||||
TTranslatedCallSideEffects(CallOrAllocationExpr expr) { not ignoreSideEffects(expr) } or
|
||||
// The non-argument-specific side effect of a `Call`
|
||||
TTranslatedCallSideEffect(Expr expr, SideEffectOpcode opcode) {
|
||||
not ignoreExpr(expr) and
|
||||
not ignoreSideEffects(expr) and
|
||||
opcode = getCallSideEffectOpcode(expr)
|
||||
} or
|
||||
@@ -771,7 +764,6 @@ newtype TTranslatedElement =
|
||||
// Constructor calls lack a qualifier (`this`) expression, so we need to handle the side effects
|
||||
// on `*this` without an `Expr`.
|
||||
TTranslatedStructorQualifierSideEffect(Call call, SideEffectOpcode opcode) {
|
||||
not ignoreExpr(call) and
|
||||
not ignoreSideEffects(call) and
|
||||
call instanceof ConstructorCall and
|
||||
opcode = getASideEffectOpcode(call, -1)
|
||||
|
||||
@@ -97,6 +97,19 @@ abstract class TranslatedExpr extends TranslatedElement {
|
||||
)
|
||||
}
|
||||
|
||||
final override predicate hasAnImplicitDestructorCall() {
|
||||
exists(expr.getAnImplicitDestructorCall())
|
||||
}
|
||||
|
||||
final override int getFirstDestructorCallIndex() {
|
||||
not this.handlesDestructorsExplicitly() and
|
||||
(
|
||||
result = max(int childId | exists(this.getChildInternal(childId))) + 1
|
||||
or
|
||||
not exists(this.getChildInternal(_)) and result = 0
|
||||
)
|
||||
}
|
||||
|
||||
final override Locatable getAst() { result = expr }
|
||||
|
||||
final override Declaration getFunction() { result = getEnclosingDeclaration(expr) }
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
## 0.9.6
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "non-constant format string" query (`cpp/non-constant-format`) has been converted to a `path-problem` query.
|
||||
* The new C/C++ dataflow and taint-tracking libraries (`semmle.code.cpp.dataflow.new.DataFlow` and `semmle.code.cpp.dataflow.new.TaintTracking`) now implicitly assume that dataflow and taint modelled via `DataFlowFunction` and `TaintFunction` always fully overwrite their buffers and thus act as flow barriers. As a result, many dataflow and taint-tracking queries now produce fewer false positives. To remove this assumption and go back to the previous behavior for a given model, one can override the new `isPartialWrite` predicate.
|
||||
|
||||
## 0.9.5
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The "non-constant format string" query (`cpp/non-constant-format`) has been converted to a `path-problem` query.
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 0.9.6
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "non-constant format string" query (`cpp/non-constant-format`) has been converted to a `path-problem` query.
|
||||
* The new C/C++ dataflow and taint-tracking libraries (`semmle.code.cpp.dataflow.new.DataFlow` and `semmle.code.cpp.dataflow.new.TaintTracking`) now implicitly assume that dataflow and taint modelled via `DataFlowFunction` and `TaintFunction` always fully overwrite their buffers and thus act as flow barriers. As a result, many dataflow and taint-tracking queries now produce fewer false positives. To remove this assumption and go back to the previous behavior for a given model, one can override the new `isPartialWrite` predicate.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.9.5
|
||||
lastReleaseVersion: 0.9.6
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.9.6-dev
|
||||
version: 0.9.6
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -12779,7 +12779,7 @@ ir.cpp:
|
||||
# 2215| r2215_1(glval<bool>) = VariableAddress[b] :
|
||||
# 2215| r2215_2(bool) = Load[b] : &:r2215_1, ~m?
|
||||
# 2215| v2215_3(void) = ConditionalBranch : r2215_2
|
||||
#-----| False -> Block 4
|
||||
#-----| False -> Block 5
|
||||
#-----| True -> Block 3
|
||||
|
||||
# 2212| Block 1
|
||||
@@ -12796,35 +12796,44 @@ ir.cpp:
|
||||
# 2216| r2216_3(char *) = Convert : r2216_2
|
||||
# 2216| mu2216_4(char *) = Store[#throw2216:7] : &:r2216_1, r2216_3
|
||||
# 2216| v2216_5(void) = ThrowValue : &:r2216_1, ~m?
|
||||
#-----| Exception -> Block 5
|
||||
#-----| Exception -> Block 6
|
||||
|
||||
# 2218| Block 4
|
||||
# 2218| r2218_1(glval<String>) = VariableAddress[s2] :
|
||||
# 2218| mu2218_2(String) = Uninitialized[s2] : &:r2218_1
|
||||
# 2218| r2218_3(glval<unknown>) = FunctionAddress[String] :
|
||||
# 2218| v2218_4(void) = Call[String] : func:r2218_3, this:r2218_1
|
||||
# 2218| mu2218_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2218| mu2218_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2218_1
|
||||
# 2219| r2219_1(glval<String>) = VariableAddress[s2] :
|
||||
# 2219| Block 4
|
||||
# 2219| r2219_1(glval<String>) = VariableAddress[s] :
|
||||
# 2219| r2219_2(glval<unknown>) = FunctionAddress[~String] :
|
||||
# 2219| v2219_3(void) = Call[~String] : func:r2219_2, this:r2219_1
|
||||
# 2219| mu2219_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 2219| v2219_5(void) = ^IndirectReadSideEffect[-1] : &:r2219_1, ~m?
|
||||
# 2219| mu2219_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2219_1
|
||||
# 2219| r2219_7(glval<String>) = VariableAddress[s] :
|
||||
# 2219| r2219_8(glval<unknown>) = FunctionAddress[~String] :
|
||||
# 2219| v2219_9(void) = Call[~String] : func:r2219_8, this:r2219_7
|
||||
# 2219| mu2219_10(unknown) = ^CallSideEffect : ~m?
|
||||
# 2219| v2219_11(void) = ^IndirectReadSideEffect[-1] : &:r2219_7, ~m?
|
||||
# 2219| mu2219_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2219_7
|
||||
#-----| Goto -> Block 10
|
||||
#-----| Goto -> Block 5
|
||||
|
||||
# 2220| Block 5
|
||||
# 2220| v2220_1(void) = CatchByType[const char *] :
|
||||
#-----| Exception -> Block 7
|
||||
#-----| Goto -> Block 6
|
||||
# 2218| Block 5
|
||||
# 2218| r2218_1(glval<String>) = VariableAddress[s2] :
|
||||
# 2218| mu2218_2(String) = Uninitialized[s2] : &:r2218_1
|
||||
# 2218| r2218_3(glval<unknown>) = FunctionAddress[String] :
|
||||
# 2218| v2218_4(void) = Call[String] : func:r2218_3, this:r2218_1
|
||||
# 2218| mu2218_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2218| mu2218_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2218_1
|
||||
# 2219| r2219_7(glval<String>) = VariableAddress[s2] :
|
||||
# 2219| r2219_8(glval<unknown>) = FunctionAddress[~String] :
|
||||
# 2219| v2219_9(void) = Call[~String] : func:r2219_8, this:r2219_7
|
||||
# 2219| mu2219_10(unknown) = ^CallSideEffect : ~m?
|
||||
# 2219| v2219_11(void) = ^IndirectReadSideEffect[-1] : &:r2219_7, ~m?
|
||||
# 2219| mu2219_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r2219_7
|
||||
# 2219| r2219_13(glval<String>) = VariableAddress[s] :
|
||||
# 2219| r2219_14(glval<unknown>) = FunctionAddress[~String] :
|
||||
# 2219| v2219_15(void) = Call[~String] : func:r2219_14, this:r2219_13
|
||||
# 2219| mu2219_16(unknown) = ^CallSideEffect : ~m?
|
||||
# 2219| v2219_17(void) = ^IndirectReadSideEffect[-1] : &:r2219_13, ~m?
|
||||
# 2219| mu2219_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r2219_13
|
||||
#-----| Goto -> Block 11
|
||||
|
||||
# 2220| Block 6
|
||||
# 2220| v2220_1(void) = CatchByType[const char *] :
|
||||
#-----| Exception -> Block 8
|
||||
#-----| Goto -> Block 7
|
||||
|
||||
# 2220| Block 7
|
||||
# 2220| r2220_2(glval<char *>) = VariableAddress[s] :
|
||||
# 2220| mu2220_3(char *) = InitializeParameter[s] : &:r2220_2
|
||||
# 2220| r2220_4(char *) = Load[s] : &:r2220_2, ~m?
|
||||
@@ -12841,25 +12850,25 @@ ir.cpp:
|
||||
# 2221| v2221_10(void) = ThrowValue : &:r2221_1, ~m?
|
||||
#-----| Exception -> Block 2
|
||||
|
||||
# 2223| Block 7
|
||||
# 2223| v2223_1(void) = CatchByType[const String &] :
|
||||
#-----| Exception -> Block 9
|
||||
#-----| Goto -> Block 8
|
||||
|
||||
# 2223| Block 8
|
||||
# 2223| v2223_1(void) = CatchByType[const String &] :
|
||||
#-----| Exception -> Block 10
|
||||
#-----| Goto -> Block 9
|
||||
|
||||
# 2223| Block 9
|
||||
# 2223| r2223_2(glval<String &>) = VariableAddress[e] :
|
||||
# 2223| mu2223_3(String &) = InitializeParameter[e] : &:r2223_2
|
||||
# 2223| r2223_4(String &) = Load[e] : &:r2223_2, ~m?
|
||||
# 2223| mu2223_5(unknown) = InitializeIndirection[e] : &:r2223_4
|
||||
# 2223| v2223_6(void) = NoOp :
|
||||
#-----| Goto -> Block 10
|
||||
#-----| Goto -> Block 11
|
||||
|
||||
# 2225| Block 9
|
||||
# 2225| Block 10
|
||||
# 2225| v2225_1(void) = CatchAny :
|
||||
# 2226| v2226_1(void) = ReThrow :
|
||||
#-----| Exception -> Block 2
|
||||
|
||||
# 2228| Block 10
|
||||
# 2228| Block 11
|
||||
# 2228| v2228_1(void) = NoOp :
|
||||
# 2212| v2212_9(void) = ReturnVoid :
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
@@ -9,6 +9,7 @@ sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
||||
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
||||
| statements.cpp:25:5:25:9 | ReThrow: re-throw exception | Instruction 'ReThrow: re-throw exception ' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
|
||||
@@ -10,6 +10,9 @@ sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
||||
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
||||
| statements.cpp:25:5:25:9 | ReThrow: re-throw exception | Instruction 'ReThrow: re-throw exception ' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| statements.cpp:26:3:26:3 | IndirectMayWriteSideEffect: inner | Instruction 'IndirectMayWriteSideEffect: inner' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| statements.cpp:28:1:28:1 | IndirectMayWriteSideEffect: before | Instruction 'IndirectMayWriteSideEffect: before' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||
| stmt_expr.cpp:29:11:32:11 | CopyValue: (statement expression) | Instruction 'CopyValue: (statement expression)' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||
| stmt_in_type.cpp:5:53:5:53 | Constant: 1 | Instruction 'Constant: 1' has no successors in function '$@'. | stmt_in_type.cpp:2:6:2:12 | void cpp_fun() | void cpp_fun() |
|
||||
|
||||
@@ -9,6 +9,7 @@ sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
||||
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
||||
| statements.cpp:25:5:25:9 | ReThrow: re-throw exception | Instruction 'ReThrow: re-throw exception ' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
|
||||
@@ -1,44 +1,44 @@
|
||||
package,sink,source,summary,sink:code-injection,sink:encryption-decryptor,sink:encryption-encryptor,sink:encryption-keyprop,sink:encryption-symmetrickey,sink:file-content-store,sink:html-injection,sink:js-injection,sink:log-injection,sink:sql-injection,source:commandargs,source:environment,source:file,source:file-write,source:local,source:remote,summary:taint,summary:value
|
||||
Amazon.Lambda.APIGatewayEvents,,6,,,,,,,,,,,,,,,,,6,,
|
||||
Amazon.Lambda.Core,10,,,,,,,,,,,10,,,,,,,,,
|
||||
Dapper,55,,,,,,,,,,,,55,,,,,,,,
|
||||
ILCompiler,,,81,,,,,,,,,,,,,,,,,81,
|
||||
ILLink.RoslynAnalyzer,,,63,,,,,,,,,,,,,,,,,63,
|
||||
ILLink.Shared,,,32,,,,,,,,,,,,,,,,,29,3
|
||||
ILLink.Tasks,,,5,,,,,,,,,,,,,,,,,5,
|
||||
Internal.IL,,,69,,,,,,,,,,,,,,,,,67,2
|
||||
Internal.Pgo,,,9,,,,,,,,,,,,,,,,,8,1
|
||||
Internal.TypeSystem,,,367,,,,,,,,,,,,,,,,,331,36
|
||||
JsonToItemsTaskFactory,,,7,,,,,,,,,,,,,,,,,7,
|
||||
Microsoft.Android.Build,,,14,,,,,,,,,,,,,,,,,14,
|
||||
Microsoft.Apple.Build,,,7,,,,,,,,,,,,,,,,,7,
|
||||
Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,,,28,,,,,,,,
|
||||
Microsoft.CSharp,,,24,,,,,,,,,,,,,,,,,24,
|
||||
Microsoft.Diagnostics.Tools.Pgo,,,13,,,,,,,,,,,,,,,,,13,
|
||||
Microsoft.EntityFrameworkCore,6,,12,,,,,,,,,,6,,,,,,,,12
|
||||
Microsoft.Extensions.Caching.Distributed,,,15,,,,,,,,,,,,,,,,,15,
|
||||
Microsoft.Extensions.Caching.Memory,,,38,,,,,,,,,,,,,,,,,37,1
|
||||
Microsoft.Extensions.Configuration,,2,89,,,,,,,,,,,,2,,,,,86,3
|
||||
Microsoft.Extensions.DependencyInjection,,,120,,,,,,,,,,,,,,,,,120,
|
||||
Microsoft.Extensions.DependencyModel,,,12,,,,,,,,,,,,,,,,,12,
|
||||
Microsoft.Extensions.Diagnostics.Metrics,,,13,,,,,,,,,,,,,,,,,13,
|
||||
Microsoft.Extensions.FileProviders,,,15,,,,,,,,,,,,,,,,,15,
|
||||
Microsoft.Extensions.FileSystemGlobbing,,,16,,,,,,,,,,,,,,,,,14,2
|
||||
Microsoft.Extensions.Hosting,,,23,,,,,,,,,,,,,,,,,22,1
|
||||
Microsoft.Extensions.Http,,,10,,,,,,,,,,,,,,,,,10,
|
||||
Microsoft.Extensions.Logging,,,60,,,,,,,,,,,,,,,,,59,1
|
||||
Microsoft.Extensions.Options,,,8,,,,,,,,,,,,,,,,,8,
|
||||
Microsoft.Extensions.Primitives,,,64,,,,,,,,,,,,,,,,,64,
|
||||
Microsoft.Interop,,,78,,,,,,,,,,,,,,,,,78,
|
||||
Microsoft.NET.Build.Tasks,,,1,,,,,,,,,,,,,,,,,1,
|
||||
Microsoft.NET.WebAssembly.Webcil,,,7,,,,,,,,,,,,,,,,,7,
|
||||
Microsoft.VisualBasic,,,10,,,,,,,,,,,,,,,,,5,5
|
||||
Microsoft.WebAssembly.Build.Tasks,,,3,,,,,,,,,,,,,,,,,3,
|
||||
Microsoft.Win32.SafeHandles,,,4,,,,,,,,,,,,,,,,,4,
|
||||
Mono.Linker,,,163,,,,,,,,,,,,,,,,,163,
|
||||
MySql.Data.MySqlClient,48,,,,,,,,,,,,48,,,,,,,,
|
||||
Newtonsoft.Json,,,91,,,,,,,,,,,,,,,,,73,18
|
||||
ServiceStack,194,,7,27,,,,,75,,,,92,,,,,,,7,
|
||||
SourceGenerators,,,4,,,,,,,,,,,,,,,,,4,
|
||||
System,67,30,11864,,8,8,9,,,4,5,,33,2,3,1,17,3,4,9898,1966
|
||||
Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,,,,,,
|
||||
package,sink,source,summary,sink:code-injection,sink:encryption-decryptor,sink:encryption-encryptor,sink:encryption-keyprop,sink:encryption-symmetrickey,sink:file-content-store,sink:html-injection,sink:js-injection,sink:log-injection,sink:sql-injection,source:file,source:file-write,source:local,source:remote,summary:taint,summary:value
|
||||
Amazon.Lambda.APIGatewayEvents,,6,,,,,,,,,,,,,,,6,,
|
||||
Amazon.Lambda.Core,10,,,,,,,,,,,10,,,,,,,
|
||||
Dapper,55,,,,,,,,,,,,55,,,,,,
|
||||
ILCompiler,,,81,,,,,,,,,,,,,,,81,
|
||||
ILLink.RoslynAnalyzer,,,63,,,,,,,,,,,,,,,63,
|
||||
ILLink.Shared,,,32,,,,,,,,,,,,,,,29,3
|
||||
ILLink.Tasks,,,5,,,,,,,,,,,,,,,5,
|
||||
Internal.IL,,,69,,,,,,,,,,,,,,,67,2
|
||||
Internal.Pgo,,,9,,,,,,,,,,,,,,,8,1
|
||||
Internal.TypeSystem,,,367,,,,,,,,,,,,,,,331,36
|
||||
JsonToItemsTaskFactory,,,7,,,,,,,,,,,,,,,7,
|
||||
Microsoft.Android.Build,,,14,,,,,,,,,,,,,,,14,
|
||||
Microsoft.Apple.Build,,,7,,,,,,,,,,,,,,,7,
|
||||
Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,,,28,,,,,,
|
||||
Microsoft.CSharp,,,24,,,,,,,,,,,,,,,24,
|
||||
Microsoft.Diagnostics.Tools.Pgo,,,13,,,,,,,,,,,,,,,13,
|
||||
Microsoft.EntityFrameworkCore,6,,12,,,,,,,,,,6,,,,,,12
|
||||
Microsoft.Extensions.Caching.Distributed,,,15,,,,,,,,,,,,,,,15,
|
||||
Microsoft.Extensions.Caching.Memory,,,38,,,,,,,,,,,,,,,37,1
|
||||
Microsoft.Extensions.Configuration,,,83,,,,,,,,,,,,,,,80,3
|
||||
Microsoft.Extensions.DependencyInjection,,,120,,,,,,,,,,,,,,,120,
|
||||
Microsoft.Extensions.DependencyModel,,,12,,,,,,,,,,,,,,,12,
|
||||
Microsoft.Extensions.Diagnostics.Metrics,,,13,,,,,,,,,,,,,,,13,
|
||||
Microsoft.Extensions.FileProviders,,,15,,,,,,,,,,,,,,,15,
|
||||
Microsoft.Extensions.FileSystemGlobbing,,,16,,,,,,,,,,,,,,,14,2
|
||||
Microsoft.Extensions.Hosting,,,23,,,,,,,,,,,,,,,22,1
|
||||
Microsoft.Extensions.Http,,,10,,,,,,,,,,,,,,,10,
|
||||
Microsoft.Extensions.Logging,,,60,,,,,,,,,,,,,,,59,1
|
||||
Microsoft.Extensions.Options,,,8,,,,,,,,,,,,,,,8,
|
||||
Microsoft.Extensions.Primitives,,,64,,,,,,,,,,,,,,,64,
|
||||
Microsoft.Interop,,,78,,,,,,,,,,,,,,,78,
|
||||
Microsoft.NET.Build.Tasks,,,1,,,,,,,,,,,,,,,1,
|
||||
Microsoft.NET.WebAssembly.Webcil,,,7,,,,,,,,,,,,,,,7,
|
||||
Microsoft.VisualBasic,,,10,,,,,,,,,,,,,,,5,5
|
||||
Microsoft.WebAssembly.Build.Tasks,,,3,,,,,,,,,,,,,,,3,
|
||||
Microsoft.Win32.SafeHandles,,,4,,,,,,,,,,,,,,,4,
|
||||
Mono.Linker,,,163,,,,,,,,,,,,,,,163,
|
||||
MySql.Data.MySqlClient,48,,,,,,,,,,,,48,,,,,,
|
||||
Newtonsoft.Json,,,91,,,,,,,,,,,,,,,73,18
|
||||
ServiceStack,194,,7,27,,,,,75,,,,92,,,,,7,
|
||||
SourceGenerators,,,4,,,,,,,,,,,,,,,4,
|
||||
System,67,25,11862,,8,8,9,,,4,5,,33,1,17,3,4,9896,1966
|
||||
Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,,,,
|
||||
|
||||
|
@@ -8,7 +8,7 @@ C# framework & library support
|
||||
|
||||
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting`
|
||||
`ServiceStack <https://servicestack.net/>`_,"``ServiceStack.*``, ``ServiceStack``",,7,194,
|
||||
System,"``System.*``, ``System``",30,11864,67,9
|
||||
Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32.SafeHandles``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",8,1547,148,
|
||||
Totals,,38,13418,409,9
|
||||
System,"``System.*``, ``System``",25,11862,67,9
|
||||
Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32.SafeHandles``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",6,1541,148,
|
||||
Totals,,31,13410,409,9
|
||||
|
||||
|
||||
@@ -814,7 +814,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
private IEnumerable<string> RestoreSolutions(IEnumerable<string> solutions, out IEnumerable<string> assets)
|
||||
{
|
||||
var successCount = 0;
|
||||
var nugetSourceFailures = 0;
|
||||
var assetFiles = new List<string>();
|
||||
var projects = solutions.SelectMany(solution =>
|
||||
{
|
||||
@@ -824,16 +823,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
successCount++;
|
||||
}
|
||||
if (res.HasNugetPackageSourceError)
|
||||
{
|
||||
nugetSourceFailures++;
|
||||
}
|
||||
assetFiles.AddRange(res.AssetsFilePaths);
|
||||
return res.RestoredProjects;
|
||||
}).ToList();
|
||||
assets = assetFiles;
|
||||
CompilationInfos.Add(("Successfully restored solution files", successCount.ToString()));
|
||||
CompilationInfos.Add(("Failed solution restore with package source error", nugetSourceFailures.ToString()));
|
||||
CompilationInfos.Add(("Restored projects through solution files", projects.Count.ToString()));
|
||||
return projects;
|
||||
}
|
||||
@@ -847,7 +841,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
private void RestoreProjects(IEnumerable<string> projects, out IEnumerable<string> assets)
|
||||
{
|
||||
var successCount = 0;
|
||||
var nugetSourceFailures = 0;
|
||||
var assetFiles = new List<string>();
|
||||
var sync = new object();
|
||||
Parallel.ForEach(projects, new ParallelOptions { MaxDegreeOfParallelism = threads }, project =>
|
||||
@@ -860,16 +853,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
successCount++;
|
||||
}
|
||||
if (res.HasNugetPackageSourceError)
|
||||
{
|
||||
nugetSourceFailures++;
|
||||
}
|
||||
assetFiles.AddRange(res.AssetsFilePaths);
|
||||
}
|
||||
});
|
||||
assets = assetFiles;
|
||||
CompilationInfos.Add(("Successfully restored project files", successCount.ToString()));
|
||||
CompilationInfos.Add(("Failed project restore with package source error", nugetSourceFailures.ToString()));
|
||||
}
|
||||
|
||||
[GeneratedRegex(@"^(.+)\.(\d+\.\d+\.\d+(-(.+))?)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
||||
|
||||
@@ -131,16 +131,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
try
|
||||
{
|
||||
var o = JObject.Parse(File.ReadAllText(path));
|
||||
var v = (string?)o?["sdk"]?["version"];
|
||||
if (v is not null)
|
||||
{
|
||||
versions.Add(v);
|
||||
}
|
||||
versions.Add((string)o?["sdk"]?["version"]!);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// not a valid `global.json` file
|
||||
logger.LogInfo($"Couldn't find .NET SDK version in '{path}'.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,9 +60,10 @@ namespace Semmle.Extraction.CSharp.Standalone
|
||||
{
|
||||
try
|
||||
{
|
||||
FileUtils.TryDelete(output.FullName);
|
||||
if (shouldCleanUpContainingFolder)
|
||||
{
|
||||
FileUtils.TryDelete(output.FullName);
|
||||
output.Directory?.Delete(true);
|
||||
}
|
||||
}
|
||||
catch
|
||||
@@ -104,19 +105,12 @@ namespace Semmle.Extraction.CSharp.Standalone
|
||||
|
||||
public void Analysed(int item, int total, string source, string output, TimeSpan time, AnalysisAction action)
|
||||
{
|
||||
var extra = action switch
|
||||
{
|
||||
AnalysisAction.Extracted => time.ToString(),
|
||||
AnalysisAction.Excluded => "excluded",
|
||||
AnalysisAction.UpToDate => "up to date",
|
||||
_ => "unknown action"
|
||||
};
|
||||
logger.LogInfo($"[{item}/{total}] {source} ({extra})");
|
||||
}
|
||||
|
||||
public void Started(int item, int total, string source)
|
||||
{
|
||||
logger.LogInfo($"[{item}/{total}] {source} (processing started)");
|
||||
logger.Log(Severity.Info, "[{0}/{1}] {2} ({3})", item, total, source,
|
||||
action == AnalysisAction.Extracted
|
||||
? time.ToString()
|
||||
: action == AnalysisAction.Excluded
|
||||
? "excluded"
|
||||
: "up to date");
|
||||
}
|
||||
|
||||
public void MissingType(string type)
|
||||
|
||||
@@ -9,20 +9,19 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private readonly string assemblyPath;
|
||||
private readonly IAssemblySymbol assembly;
|
||||
private readonly bool isOutputAssembly;
|
||||
|
||||
private Assembly(Context cx, Microsoft.CodeAnalysis.Location? init)
|
||||
: base(cx, init)
|
||||
{
|
||||
isOutputAssembly = init is null;
|
||||
if (isOutputAssembly)
|
||||
if (init is null)
|
||||
{
|
||||
// This is the output assembly
|
||||
assemblyPath = cx.Extractor.OutputPath;
|
||||
assembly = cx.Compilation.Assembly;
|
||||
}
|
||||
else
|
||||
{
|
||||
assembly = init!.MetadataModule!.ContainingAssembly;
|
||||
assembly = init.MetadataModule!.ContainingAssembly;
|
||||
var identity = assembly.Identity;
|
||||
var idString = identity.Name + " " + identity.Version;
|
||||
assemblyPath = cx.Extractor.GetAssemblyFile(idString);
|
||||
@@ -33,13 +32,8 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
if (assemblyPath is not null)
|
||||
{
|
||||
var isBuildlessOutputAssembly = isOutputAssembly && Context.Extractor.Mode.HasFlag(ExtractorMode.Standalone);
|
||||
var identifier = isBuildlessOutputAssembly
|
||||
? ""
|
||||
: assembly.ToString() ?? "";
|
||||
var name = isBuildlessOutputAssembly ? "" : assembly.Identity.Name;
|
||||
var version = isBuildlessOutputAssembly ? "" : assembly.Identity.Version.ToString();
|
||||
trapFile.assemblies(this, File.Create(Context, assemblyPath), identifier, name, version);
|
||||
trapFile.assemblies(this, File.Create(Context, assemblyPath), assembly.ToString() ?? "",
|
||||
assembly.Identity.Name, assembly.Identity.Version.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,16 +68,8 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
if (isOutputAssembly && Context.Extractor.Mode.HasFlag(ExtractorMode.Standalone))
|
||||
{
|
||||
trapFile.Write("buildlessOutputAssembly");
|
||||
}
|
||||
else
|
||||
{
|
||||
trapFile.Write(assembly.ToString());
|
||||
}
|
||||
|
||||
if (assemblyPath is not null)
|
||||
trapFile.Write(assembly.ToString());
|
||||
if (!(assemblyPath is null))
|
||||
{
|
||||
trapFile.Write("#file:///");
|
||||
trapFile.Write(assemblyPath.Replace("\\", "/"));
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
@@ -24,6 +23,8 @@ namespace Semmle.Extraction.CSharp
|
||||
private protected Entities.Compilation? compilationEntity;
|
||||
private IDisposable? compilationTrapFile;
|
||||
|
||||
private readonly object progressMutex = new object();
|
||||
|
||||
// The bulk of the extraction work, potentially executed in parallel.
|
||||
protected readonly List<Action> extractionTasks = new List<Action>();
|
||||
private int taskCount = 0;
|
||||
@@ -130,9 +131,6 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
var skipExtraction = options.Cache && File.Exists(trapWriter.TrapFile);
|
||||
|
||||
var currentTaskId = IncrementTaskCount();
|
||||
ReportProgressTaskStarted(currentTaskId, assemblyPath);
|
||||
|
||||
if (!skipExtraction)
|
||||
{
|
||||
/* Note on parallel builds:
|
||||
@@ -169,7 +167,7 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
ReportProgressTaskDone(currentTaskId, assemblyPath, trapWriter.TrapFile, stopwatch.Elapsed, skipExtraction ? AnalysisAction.UpToDate : AnalysisAction.Extracted);
|
||||
ReportProgress(assemblyPath, trapWriter.TrapFile, stopwatch.Elapsed, skipExtraction ? AnalysisAction.UpToDate : AnalysisAction.Extracted);
|
||||
}
|
||||
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
|
||||
{
|
||||
@@ -179,13 +177,11 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
private void DoExtractCIL(PortableExecutableReference r)
|
||||
{
|
||||
var currentTaskId = IncrementTaskCount();
|
||||
ReportProgressTaskStarted(currentTaskId, r.FilePath);
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
CIL.Analyser.ExtractCIL(r.FilePath!, Logger, options, out var trapFile, out var extracted);
|
||||
stopwatch.Stop();
|
||||
ReportProgressTaskDone(currentTaskId, r.FilePath, trapFile, stopwatch.Elapsed, extracted ? AnalysisAction.Extracted : AnalysisAction.UpToDate);
|
||||
ReportProgress(r.FilePath, trapFile, stopwatch.Elapsed, extracted ? AnalysisAction.Extracted : AnalysisAction.UpToDate);
|
||||
}
|
||||
|
||||
private void DoExtractTree(SyntaxTree tree)
|
||||
@@ -205,9 +201,6 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
upToDate = options.Fast && FileIsUpToDate(sourcePath, trapWriter.TrapFile);
|
||||
|
||||
var currentTaskId = IncrementTaskCount();
|
||||
ReportProgressTaskStarted(currentTaskId, sourcePath);
|
||||
|
||||
if (!upToDate)
|
||||
{
|
||||
var cx = new Context(extractor, compilation.Clone(), trapWriter, new SourceScope(tree), addAssemblyTrapPrefix);
|
||||
@@ -228,7 +221,7 @@ namespace Semmle.Extraction.CSharp
|
||||
cx.PopulateAll();
|
||||
}
|
||||
|
||||
ReportProgressTaskDone(currentTaskId, sourcePath, trapPath, stopwatch.Elapsed, upToDate ? AnalysisAction.UpToDate : AnalysisAction.Extracted);
|
||||
ReportProgress(sourcePath, trapPath, stopwatch.Elapsed, upToDate ? AnalysisAction.UpToDate : AnalysisAction.Extracted);
|
||||
}
|
||||
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
|
||||
{
|
||||
@@ -241,11 +234,6 @@ namespace Semmle.Extraction.CSharp
|
||||
try
|
||||
{
|
||||
var assemblyPath = extractor.OutputPath;
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
var currentTaskId = IncrementTaskCount();
|
||||
ReportProgressTaskStarted(currentTaskId, assemblyPath);
|
||||
|
||||
var transformedAssemblyPath = PathTransformer.Transform(assemblyPath);
|
||||
var assembly = compilation.Assembly;
|
||||
var trapWriter = transformedAssemblyPath.CreateTrapWriter(Logger, options.TrapCompression, discardDuplicates: false);
|
||||
@@ -255,8 +243,6 @@ namespace Semmle.Extraction.CSharp
|
||||
compilationEntity = Entities.Compilation.Create(cx);
|
||||
|
||||
extractor.CompilationInfos.ForEach(ci => trapWriter.Writer.compilation_info(compilationEntity, ci.key, ci.value));
|
||||
|
||||
ReportProgressTaskDone(currentTaskId, assemblyPath, trapWriter.TrapFile, stopwatch.Elapsed, AnalysisAction.Extracted);
|
||||
}
|
||||
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
|
||||
{
|
||||
@@ -293,19 +279,10 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
private int IncrementTaskCount()
|
||||
private void ReportProgress(string src, string output, TimeSpan time, AnalysisAction action)
|
||||
{
|
||||
return Interlocked.Increment(ref taskCount);
|
||||
}
|
||||
|
||||
private void ReportProgressTaskStarted(int currentCount, string src)
|
||||
{
|
||||
progressMonitor.Started(currentCount, extractionTasks.Count, src);
|
||||
}
|
||||
|
||||
private void ReportProgressTaskDone(int currentCount, string src, string output, TimeSpan time, AnalysisAction action)
|
||||
{
|
||||
progressMonitor.Analysed(currentCount, extractionTasks.Count, src, output, time, action);
|
||||
lock (progressMutex)
|
||||
progressMonitor.Analysed(++taskCount, extractionTasks.Count, src, output, time, action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -47,8 +47,6 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
public void Started(int item, int total, string source) { }
|
||||
|
||||
public void MissingNamespace(string @namespace) { }
|
||||
|
||||
public void MissingSummary(int types, int namespaces) { }
|
||||
|
||||
@@ -19,11 +19,6 @@ namespace Semmle.Extraction.CSharp
|
||||
/// <param name="action">What action was taken for the file.</param>
|
||||
void Analysed(int item, int total, string source, string output, TimeSpan time, AnalysisAction action);
|
||||
|
||||
/// <summary>
|
||||
/// Callback that processing of a particular item has been started.
|
||||
/// </summary>
|
||||
void Started(int item, int total, string source);
|
||||
|
||||
/// <summary>
|
||||
/// A "using namespace" directive was seen but the given
|
||||
/// namespace could not be found.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.7.10
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.9
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.7.10
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.9
|
||||
lastReleaseVersion: 1.7.10
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.7.10-dev
|
||||
version: 1.7.10
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.7.10
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.9
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.7.10
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.9
|
||||
lastReleaseVersion: 1.7.10
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.7.10-dev
|
||||
version: 1.7.10
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import csharp
|
||||
import cil
|
||||
private import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl as ControlFlowGraphImpl
|
||||
private import semmle.code.csharp.dataflow.internal.DataFlowImplSpecific
|
||||
private import semmle.code.csharp.dataflow.internal.TaintTrackingImplSpecific
|
||||
@@ -30,6 +31,11 @@ private module Input implements InputSig<CsharpDataFlow> {
|
||||
n instanceof FlowInsensitiveFieldNode
|
||||
}
|
||||
|
||||
predicate missingLocationExclude(Node n) {
|
||||
// Some CIL methods are missing locations
|
||||
n.asParameter() instanceof CIL::Parameter
|
||||
}
|
||||
|
||||
predicate postWithInFlowExclude(Node n) {
|
||||
n instanceof FlowSummaryNode
|
||||
or
|
||||
@@ -42,6 +48,8 @@ private module Input implements InputSig<CsharpDataFlow> {
|
||||
not exists(LocalFlow::getAPostUpdateNodeForArg(n.getControlFlowNode()))
|
||||
or
|
||||
n instanceof ParamsArgumentNode
|
||||
or
|
||||
n.asExpr() instanceof CIL::Expr
|
||||
}
|
||||
|
||||
predicate postHasUniquePreExclude(PostUpdateNode n) {
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
| Failed project restore with package source error | 1.0 |
|
||||
| Failed solution restore with package source error | 0.0 |
|
||||
| Fallback nuget restore | 1.0 |
|
||||
| Project files on filesystem | 1.0 |
|
||||
| Resolved assembly conflicts | 7.0 |
|
||||
| Restored .NET framework variants | 0.0 |
|
||||
| Restored projects through solution files | 0.0 |
|
||||
| Solution files on filesystem | 1.0 |
|
||||
| Source files generated | 0.0 |
|
||||
| Source files on filesystem | 1.0 |
|
||||
| Successfully ran fallback nuget restore | 1.0 |
|
||||
| Successfully restored project files | 0.0 |
|
||||
| Successfully restored solution files | 1.0 |
|
||||
| Unresolved references | 0.0 |
|
||||
| UseWPF set | 0.0 |
|
||||
| UseWindowsForms set | 0.0 |
|
||||
| WebView extraction enabled | 1.0 |
|
||||
@@ -1,14 +0,0 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.commons.Diagnostics
|
||||
|
||||
query predicate compilationInfo(string key, float value) {
|
||||
key != "Resolved references" and
|
||||
exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) |
|
||||
key = infoKey and
|
||||
value = infoValue.toFloat()
|
||||
or
|
||||
not exists(infoValue.toFloat()) and
|
||||
key = infoKey + ": " + infoValue and
|
||||
value = 1
|
||||
)
|
||||
}
|
||||
@@ -1,3 +1,17 @@
|
||||
## 0.8.10
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
* Improved support for flow through captured variables that properly adheres to inter-procedural control flow.
|
||||
* We no longer make use of CodeQL database stats, which may affect join-orders in custom queries. It is therefore recommended to test performance of custom queries after upgrading to this version.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* C# 12: Add QL library support (`ExperimentalAttribute`) for the experimental attribute.
|
||||
* C# 12: Add extractor and QL library support for `ref readonly` parameters.
|
||||
* C#: The table `expr_compiler_generated` has been deleted and its content has been added to `compiler_generated`.
|
||||
* Data flow via get only properties like `public object Obj { get; }` is now captured by the data flow library.
|
||||
|
||||
## 0.8.9
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Data flow via get only properties like `public object Obj { get; }` is now captured by the data flow library.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* We no longer make use of CodeQL database stats, which may affect join-orders in custom queries. It is therefore recommended to test performance of custom queries after upgrading to this version.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* C#: The table `expr_compiler_generated` has been deleted and its content has been added to `compiler_generated`.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* Improved support for flow through captured variables that properly adheres to inter-procedural control flow.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* C# 12: Add QL library support (`ExperimentalAttribute`) for the experimental attribute.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* C# 12: Add extractor and QL library support for `ref readonly` parameters.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* The QL library C# classes no longer extend their corresponding `DotNet` classes. Furthermore, CIL related data flow functionality has been deleted and all `DotNet` and `CIL` related classes have been deprecated. This effectively means that it no longer has any effect to enable CIL extraction.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The models for `System.IO.TextReader` have been modified to better model the flow of tainted text from a `TextReader`.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The .NET standard libraries APIs for accessing command line arguments and environment variables have been modeled using the `commandargs` and `environment` threat models.
|
||||
* The `cs/assembly-path-injection` query has been modified so that it's sources rely on `ThreatModelFlowSource`. In order to restore results from command line arguments, you should enable the `commandargs` threat model.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The models for `System.Net.Http.HttpRequestMessage` have been modified to better model the flow of tainted URIs.
|
||||
13
csharp/ql/lib/change-notes/released/0.8.10.md
Normal file
13
csharp/ql/lib/change-notes/released/0.8.10.md
Normal file
@@ -0,0 +1,13 @@
|
||||
## 0.8.10
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
* Improved support for flow through captured variables that properly adheres to inter-procedural control flow.
|
||||
* We no longer make use of CodeQL database stats, which may affect join-orders in custom queries. It is therefore recommended to test performance of custom queries after upgrading to this version.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* C# 12: Add QL library support (`ExperimentalAttribute`) for the experimental attribute.
|
||||
* C# 12: Add extractor and QL library support for `ref readonly` parameters.
|
||||
* C#: The table `expr_compiler_generated` has been deleted and its content has been added to `compiler_generated`.
|
||||
* Data flow via get only properties like `public object Obj { get; }` is now captured by the data flow library.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.8.9
|
||||
lastReleaseVersion: 0.8.10
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
* The default QL library for modeling .NET definitions for both C# and CIL code.
|
||||
*/
|
||||
|
||||
deprecated import semmle.code.dotnet.DotNet as DotNet
|
||||
import semmle.code.dotnet.DotNet as DotNet
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["Microsoft.Extensions.Configuration", "EnvironmentVariablesExtensions", False, "AddEnvironmentVariables", "", "", "Argument[0]", "environment", "manual"]
|
||||
- ["Microsoft.Extensions.Configuration", "EnvironmentVariablesExtensions", False, "AddEnvironmentVariables", "", "", "ReturnValue", "environment", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["Microsoft.Extensions.Configuration", "IConfiguration", True, "get_Item", "(System.String)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["Microsoft.Extensions.Configuration", "IConfigurationBuilder", True, "Build", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["Microsoft.Extensions.Configuration", "CommandLineConfigurationExtensions", False, "AddCommandLine", "", "", "Argument[1]", "Argument[0]", "taint", "manual"]
|
||||
- ["Microsoft.Extensions.Configuration", "CommandLineConfigurationExtensions", False, "AddCommandLine", "(Microsoft.Extensions.Configuration.IConfigurationBuilder,System.String[],System.Collections.Generic.IDictionary<System.String,System.String>)", "", "Argument[2]", "Argument[0]", "taint", "manual"]
|
||||
- ["Microsoft.Extensions.Configuration", "CommandLineConfigurationExtensions", False, "AddCommandLine", "", "", "Argument[1]", "ReturnValue", "taint", "manual"]
|
||||
- ["Microsoft.Extensions.Configuration", "CommandLineConfigurationExtensions", False, "AddCommandLine", "(Microsoft.Extensions.Configuration.IConfigurationBuilder,System.String[],System.Collections.Generic.IDictionary<System.String,System.String>)", "", "Argument[2]", "ReturnValue", "taint", "manual"]
|
||||
@@ -89,16 +89,14 @@ extensions:
|
||||
- ["System.IO", "StreamReader", False, "StreamReader", "(System.String,System.Text.Encoding,System.Boolean,System.Int32)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["System.IO", "StringReader", False, "StringReader", "(System.String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "Read", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "Read", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "Read", "(System.Span<System.Char>)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadAsync", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
# Post-update nodes for `Memory<T>` are currently unsupported. This model is provided for completeness
|
||||
- ["System.IO", "TextReader", True, "ReadAsync", "(System.Memory<System.Char>,System.Threading.CancellationToken)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadBlock", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadBlock", "(System.Span<System.Char>)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadBlockAsync", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
# Post-update nodes for `Memory<T>` are currently unsupported. This model is provided for completeness
|
||||
- ["System.IO", "TextReader", True, "ReadBlockAsync", "(System.Memory<System.Char>,System.Threading.CancellationToken)", "", "Argument[this]", "Argument[0].Element", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "Read", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "Read", "(System.Span<System.Char>)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadAsync", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadAsync", "(System.Memory<System.Char>,System.Threading.CancellationToken)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadBlock", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadBlock", "(System.Span<System.Char>)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadBlockAsync", "(System.Char[],System.Int32,System.Int32)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadBlockAsync", "(System.Memory<System.Char>,System.Threading.CancellationToken)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadLine", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadLineAsync", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["System.IO", "TextReader", True, "ReadToEnd", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
|
||||
@@ -8,8 +8,6 @@ extensions:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Net.Http", "HttpRequestMessage", False, "HttpRequestMessage", "(System.Net.Http.HttpMethod,System.String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["System.Net.Http", "HttpRequestMessage", False, "HttpRequestMessage", "(System.Net.Http.HttpMethod,System.String)", "", "Argument[1]", "Argument[this]", "taint", "manual"]
|
||||
- ["System.Net.Http", "HttpRequestOptions", False, "Add", "(System.Collections.Generic.KeyValuePair<System.String,System.Object>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair`2.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Key]", "value", "manual"]
|
||||
- ["System.Net.Http", "HttpRequestOptions", False, "Add", "(System.Collections.Generic.KeyValuePair<System.String,System.Object>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair`2.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Value]", "value", "manual"]
|
||||
- ["System.Net.Http", "MultipartContent", False, "Add", "(System.Net.Http.HttpContent)", "", "Argument[0]", "Argument[this].Element", "value", "manual"]
|
||||
|
||||
@@ -6,11 +6,6 @@ extensions:
|
||||
- ["System", "Console", False, "Read", "", "", "ReturnValue", "local", "manual"]
|
||||
- ["System", "Console", False, "ReadKey", "", "", "ReturnValue", "local", "manual"]
|
||||
- ["System", "Console", False, "ReadLine", "", "", "ReturnValue", "local", "manual"]
|
||||
- ["System", "Environment", False, "ExpandEnvironmentVariables", "(System.String)", "", "ReturnValue", "environment", "manual"]
|
||||
- ["System", "Environment", False, "GetCommandLineArgs", "()", "", "ReturnValue", "commandargs", "manual"]
|
||||
- ["System", "Environment", False, "get_CommandLine", "()", "", "ReturnValue", "commandargs", "manual"]
|
||||
- ["System", "Environment", False, "GetEnvironmentVariable", "", "", "ReturnValue", "environment", "manual"]
|
||||
- ["System", "Environment", False, "GetEnvironmentVariables", "", "", "ReturnValue", "environment", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-all
|
||||
version: 0.8.10-dev
|
||||
version: 0.8.10
|
||||
groups: csharp
|
||||
dbscheme: semmlecode.csharp.dbscheme
|
||||
extractor: csharp
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
private import CIL
|
||||
|
||||
/** An instruction that accesses a variable. */
|
||||
deprecated class Access extends Instruction, @cil_access {
|
||||
class Access extends Instruction, @cil_access {
|
||||
/** Gets the declaration referenced by this instruction. */
|
||||
Variable getTarget() { cil_access(this, result) }
|
||||
}
|
||||
@@ -16,59 +16,59 @@ deprecated class Access extends Instruction, @cil_access {
|
||||
* An instruction that accesses a variable.
|
||||
* This class is provided for consistency with the C# data model.
|
||||
*/
|
||||
deprecated class VariableAccess extends Access, @cil_access { }
|
||||
class VariableAccess extends Access, @cil_access { }
|
||||
|
||||
/** An instruction that reads a variable. */
|
||||
deprecated class ReadAccess extends VariableAccess, Expr, @cil_read_access {
|
||||
class ReadAccess extends VariableAccess, Expr, @cil_read_access {
|
||||
override Type getType() { result = this.getTarget().getType() }
|
||||
}
|
||||
|
||||
/** An instruction yielding an address. */
|
||||
deprecated class ReadRef extends Expr, @cil_read_ref { }
|
||||
class ReadRef extends Expr, @cil_read_ref { }
|
||||
|
||||
/** An instruction that reads the address of a variable. */
|
||||
deprecated class ReadRefAccess extends ReadAccess, ReadRef { }
|
||||
class ReadRefAccess extends ReadAccess, ReadRef { }
|
||||
|
||||
/** An instruction that writes a variable. */
|
||||
deprecated class WriteAccess extends VariableAccess, @cil_write_access {
|
||||
class WriteAccess extends VariableAccess, @cil_write_access {
|
||||
/** Gets the expression whose value is used in this variable write. */
|
||||
Expr getExpr() { none() }
|
||||
}
|
||||
|
||||
/** An instruction that accesses a parameter. */
|
||||
deprecated class ParameterAccess extends StackVariableAccess, @cil_arg_access {
|
||||
class ParameterAccess extends StackVariableAccess, @cil_arg_access {
|
||||
override MethodParameter getTarget() { result = StackVariableAccess.super.getTarget() }
|
||||
}
|
||||
|
||||
/** An instruction that reads a parameter. */
|
||||
deprecated class ParameterReadAccess extends ParameterAccess, ReadAccess {
|
||||
class ParameterReadAccess extends ParameterAccess, ReadAccess {
|
||||
override int getPopCount() { result = 0 }
|
||||
}
|
||||
|
||||
/** An instruction that writes to a parameter. */
|
||||
deprecated class ParameterWriteAccess extends ParameterAccess, WriteAccess {
|
||||
class ParameterWriteAccess extends ParameterAccess, WriteAccess {
|
||||
override int getPopCount() { result = 1 }
|
||||
|
||||
override Expr getExpr() { result = this.getOperand(0) }
|
||||
}
|
||||
|
||||
/** An access to the `this` parameter. */
|
||||
deprecated class ThisAccess extends ParameterReadAccess {
|
||||
class ThisAccess extends ParameterReadAccess {
|
||||
ThisAccess() { this.getTarget() instanceof ThisParameter }
|
||||
}
|
||||
|
||||
/** An instruction that accesses a stack variable. */
|
||||
deprecated class StackVariableAccess extends VariableAccess, @cil_stack_access {
|
||||
class StackVariableAccess extends VariableAccess, @cil_stack_access {
|
||||
override StackVariable getTarget() { result = VariableAccess.super.getTarget() }
|
||||
}
|
||||
|
||||
/** An instruction that accesses a local variable. */
|
||||
deprecated class LocalVariableAccess extends StackVariableAccess, @cil_local_access {
|
||||
class LocalVariableAccess extends StackVariableAccess, @cil_local_access {
|
||||
override LocalVariable getTarget() { result = StackVariableAccess.super.getTarget() }
|
||||
}
|
||||
|
||||
/** An instruction that writes to a local variable. */
|
||||
deprecated class LocalVariableWriteAccess extends LocalVariableAccess, WriteAccess {
|
||||
class LocalVariableWriteAccess extends LocalVariableAccess, WriteAccess {
|
||||
override int getPopCount() { result = 1 }
|
||||
|
||||
override Expr getExpr() { result = this.getOperand(0) }
|
||||
@@ -77,12 +77,12 @@ deprecated class LocalVariableWriteAccess extends LocalVariableAccess, WriteAcce
|
||||
}
|
||||
|
||||
/** An instruction that reads a local variable. */
|
||||
deprecated class LocalVariableReadAccess extends LocalVariableAccess, ReadAccess {
|
||||
class LocalVariableReadAccess extends LocalVariableAccess, ReadAccess {
|
||||
override int getPopCount() { result = 0 }
|
||||
}
|
||||
|
||||
/** An instruction that accesses a field. */
|
||||
deprecated class FieldAccess extends VariableAccess, @cil_field_access {
|
||||
class FieldAccess extends VariableAccess, @cil_field_access {
|
||||
override Field getTarget() { result = VariableAccess.super.getTarget() }
|
||||
|
||||
override string getExtra() { result = this.getTarget().getName() }
|
||||
@@ -92,7 +92,7 @@ deprecated class FieldAccess extends VariableAccess, @cil_field_access {
|
||||
}
|
||||
|
||||
/** An instruction that reads a field. */
|
||||
abstract deprecated class FieldReadAccess extends FieldAccess, ReadAccess { }
|
||||
abstract class FieldReadAccess extends FieldAccess, ReadAccess { }
|
||||
|
||||
/** An instruction that writes a field. */
|
||||
abstract deprecated class FieldWriteAccess extends FieldAccess, WriteAccess { }
|
||||
abstract class FieldWriteAccess extends FieldAccess, WriteAccess { }
|
||||
|
||||
@@ -4,7 +4,7 @@ private import CIL
|
||||
private import semmle.code.csharp.Location as CS
|
||||
|
||||
/** An attribute to a declaration, such as a method, field, type or parameter. */
|
||||
deprecated class Attribute extends Element, @cil_attribute {
|
||||
class Attribute extends Element, @cil_attribute {
|
||||
/** Gets the declaration this attribute is attached to. */
|
||||
Declaration getDeclaration() { cil_attribute(this, result, _) }
|
||||
|
||||
@@ -29,7 +29,7 @@ deprecated class Attribute extends Element, @cil_attribute {
|
||||
}
|
||||
|
||||
/** A generic attribute to a declaration. */
|
||||
deprecated class GenericAttribute extends Attribute {
|
||||
class GenericAttribute extends Attribute {
|
||||
private ConstructedType type;
|
||||
|
||||
GenericAttribute() { type = this.getType() }
|
||||
|
||||
@@ -8,7 +8,7 @@ private import CIL
|
||||
* A basic block, that is, a maximal straight-line sequence of control flow nodes
|
||||
* without branches or joins.
|
||||
*/
|
||||
deprecated class BasicBlock extends Cached::TBasicBlockStart {
|
||||
class BasicBlock extends Cached::TBasicBlockStart {
|
||||
/** Gets an immediate successor of this basic block, if any. */
|
||||
BasicBlock getASuccessor() { result.getFirstNode() = this.getLastNode().getASuccessor() }
|
||||
|
||||
@@ -249,7 +249,7 @@ deprecated class BasicBlock extends Cached::TBasicBlockStart {
|
||||
* Internal implementation details.
|
||||
*/
|
||||
cached
|
||||
deprecated private module Cached {
|
||||
private module Cached {
|
||||
/** Internal representation of basic blocks. */
|
||||
cached
|
||||
newtype TBasicBlock = TBasicBlockStart(ControlFlowNode cfn) { startsBB(cfn) }
|
||||
@@ -287,54 +287,49 @@ deprecated private module Cached {
|
||||
* Holds if the first node of basic block `succ` is a control flow
|
||||
* successor of the last node of basic block `pred`.
|
||||
*/
|
||||
deprecated private predicate succBB(BasicBlock pred, BasicBlock succ) {
|
||||
succ = pred.getASuccessor()
|
||||
}
|
||||
private predicate succBB(BasicBlock pred, BasicBlock succ) { succ = pred.getASuccessor() }
|
||||
|
||||
/** Holds if `dom` is an immediate dominator of `bb`. */
|
||||
deprecated predicate bbIDominates(BasicBlock dom, BasicBlock bb) =
|
||||
idominance(entryBB/1, succBB/2)(_, dom, bb)
|
||||
predicate bbIDominates(BasicBlock dom, BasicBlock bb) = idominance(entryBB/1, succBB/2)(_, dom, bb)
|
||||
|
||||
/** Holds if `pred` is a basic block predecessor of `succ`. */
|
||||
deprecated private predicate predBB(BasicBlock succ, BasicBlock pred) { succBB(pred, succ) }
|
||||
private predicate predBB(BasicBlock succ, BasicBlock pred) { succBB(pred, succ) }
|
||||
|
||||
/** Holds if `dom` is an immediate post-dominator of `bb`. */
|
||||
deprecated predicate bbIPostDominates(BasicBlock dom, BasicBlock bb) =
|
||||
predicate bbIPostDominates(BasicBlock dom, BasicBlock bb) =
|
||||
idominance(exitBB/1, predBB/2)(_, dom, bb)
|
||||
|
||||
/**
|
||||
* An entry basic block, that is, a basic block whose first node is
|
||||
* the entry node of a callable.
|
||||
*/
|
||||
deprecated class EntryBasicBlock extends BasicBlock {
|
||||
class EntryBasicBlock extends BasicBlock {
|
||||
EntryBasicBlock() { entryBB(this) }
|
||||
}
|
||||
|
||||
/** Holds if `bb` is an entry basic block. */
|
||||
deprecated private predicate entryBB(BasicBlock bb) {
|
||||
bb.getFirstNode() instanceof MethodImplementation
|
||||
}
|
||||
private predicate entryBB(BasicBlock bb) { bb.getFirstNode() instanceof MethodImplementation }
|
||||
|
||||
/**
|
||||
* An exit basic block, that is, a basic block whose last node is
|
||||
* an exit node.
|
||||
*/
|
||||
deprecated class ExitBasicBlock extends BasicBlock {
|
||||
class ExitBasicBlock extends BasicBlock {
|
||||
ExitBasicBlock() { exitBB(this) }
|
||||
}
|
||||
|
||||
/** Holds if `bb` is an exit basic block. */
|
||||
deprecated private predicate exitBB(BasicBlock bb) { not exists(bb.getLastNode().getASuccessor()) }
|
||||
private predicate exitBB(BasicBlock bb) { not exists(bb.getLastNode().getASuccessor()) }
|
||||
|
||||
/**
|
||||
* A basic block with more than one predecessor.
|
||||
*/
|
||||
deprecated class JoinBlock extends BasicBlock {
|
||||
class JoinBlock extends BasicBlock {
|
||||
JoinBlock() { this.getFirstNode().isJoin() }
|
||||
}
|
||||
|
||||
/** A basic block that terminates in a condition, splitting the subsequent control flow. */
|
||||
deprecated class ConditionBlock extends BasicBlock {
|
||||
class ConditionBlock extends BasicBlock {
|
||||
ConditionBlock() {
|
||||
exists(BasicBlock succ |
|
||||
succ = this.getATrueSuccessor()
|
||||
|
||||
@@ -8,26 +8,22 @@ cached
|
||||
private module Cached {
|
||||
/** Holds if method `m` always returns null. */
|
||||
cached
|
||||
deprecated predicate alwaysNullMethod(Method m) {
|
||||
forex(Expr e | m.canReturn(e) | alwaysNullExpr(e))
|
||||
}
|
||||
predicate alwaysNullMethod(Method m) { forex(Expr e | m.canReturn(e) | alwaysNullExpr(e)) }
|
||||
|
||||
/** Holds if method `m` always returns non-null. */
|
||||
cached
|
||||
deprecated predicate alwaysNotNullMethod(Method m) {
|
||||
forex(Expr e | m.canReturn(e) | alwaysNotNullExpr(e))
|
||||
}
|
||||
predicate alwaysNotNullMethod(Method m) { forex(Expr e | m.canReturn(e) | alwaysNotNullExpr(e)) }
|
||||
|
||||
/** Holds if method `m` always throws an exception. */
|
||||
cached
|
||||
deprecated predicate alwaysThrowsMethod(Method m) {
|
||||
predicate alwaysThrowsMethod(Method m) {
|
||||
m.hasBody() and
|
||||
not exists(m.getImplementation().getAnInstruction().(Return))
|
||||
}
|
||||
|
||||
/** Holds if method `m` always throws an exception of type `t`. */
|
||||
cached
|
||||
deprecated predicate alwaysThrowsException(Method m, Type t) {
|
||||
predicate alwaysThrowsException(Method m, Type t) {
|
||||
alwaysThrowsMethod(m) and
|
||||
forex(Throw ex | ex = m.getImplementation().getAnInstruction() | t = ex.getExceptionType())
|
||||
}
|
||||
@@ -36,12 +32,12 @@ private module Cached {
|
||||
import Cached
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private predicate alwaysNullVariableUpdate(VariableUpdate vu) {
|
||||
private predicate alwaysNullVariableUpdate(VariableUpdate vu) {
|
||||
forex(Expr src | src = vu.getSource() | alwaysNullExpr(src))
|
||||
}
|
||||
|
||||
/** Holds if expression `expr` always evaluates to `null`. */
|
||||
deprecated private predicate alwaysNullExpr(Expr expr) {
|
||||
private predicate alwaysNullExpr(Expr expr) {
|
||||
expr instanceof NullLiteral
|
||||
or
|
||||
alwaysNullMethod(expr.(StaticCall).getTarget())
|
||||
@@ -54,12 +50,12 @@ deprecated private predicate alwaysNullExpr(Expr expr) {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private predicate alwaysNotNullVariableUpdate(VariableUpdate vu) {
|
||||
private predicate alwaysNotNullVariableUpdate(VariableUpdate vu) {
|
||||
forex(Expr src | src = vu.getSource() | alwaysNotNullExpr(src))
|
||||
}
|
||||
|
||||
/** Holds if expression `expr` always evaluates to non-null. */
|
||||
deprecated private predicate alwaysNotNullExpr(Expr expr) {
|
||||
private predicate alwaysNotNullExpr(Expr expr) {
|
||||
expr instanceof Opcodes::NewObj
|
||||
or
|
||||
expr instanceof Literal and not expr instanceof NullLiteral
|
||||
|
||||
@@ -8,15 +8,15 @@ private import semmle.code.csharp.commons.QualifiedName
|
||||
|
||||
private newtype ConsistencyCheck =
|
||||
MissingEntityCheck() or
|
||||
deprecated TypeCheck(Type t) or
|
||||
deprecated CfgCheck(ControlFlowNode n) or
|
||||
deprecated DeclarationCheck(Declaration d) or
|
||||
TypeCheck(Type t) or
|
||||
CfgCheck(ControlFlowNode n) or
|
||||
DeclarationCheck(Declaration d) or
|
||||
MissingCSharpCheck(CS::Declaration d)
|
||||
|
||||
/**
|
||||
* A consistency violation in the database or data model.
|
||||
*/
|
||||
abstract deprecated class ConsistencyViolation extends ConsistencyCheck {
|
||||
abstract class ConsistencyViolation extends ConsistencyCheck {
|
||||
abstract string toString();
|
||||
|
||||
abstract string getMessage();
|
||||
@@ -25,14 +25,14 @@ abstract deprecated class ConsistencyViolation extends ConsistencyCheck {
|
||||
/**
|
||||
* A check that is deliberately disabled.
|
||||
*/
|
||||
abstract deprecated class DisabledCheck extends ConsistencyViolation {
|
||||
abstract class DisabledCheck extends ConsistencyViolation {
|
||||
DisabledCheck() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A consistency violation on a control flow node.
|
||||
*/
|
||||
abstract deprecated class CfgViolation extends ConsistencyViolation, CfgCheck {
|
||||
abstract class CfgViolation extends ConsistencyViolation, CfgCheck {
|
||||
ControlFlowNode node;
|
||||
|
||||
CfgViolation() { this = CfgCheck(node) }
|
||||
@@ -43,7 +43,7 @@ abstract deprecated class CfgViolation extends ConsistencyViolation, CfgCheck {
|
||||
/**
|
||||
* A consistency violation in a specific instruction.
|
||||
*/
|
||||
abstract deprecated class InstructionViolation extends CfgViolation, CfgCheck {
|
||||
abstract class InstructionViolation extends CfgViolation, CfgCheck {
|
||||
Instruction instruction;
|
||||
|
||||
InstructionViolation() { this = CfgCheck(instruction) }
|
||||
@@ -70,7 +70,7 @@ abstract deprecated class InstructionViolation extends CfgViolation, CfgCheck {
|
||||
/**
|
||||
* A literal that does not have exactly one `getValue()`.
|
||||
*/
|
||||
deprecated class MissingValue extends InstructionViolation {
|
||||
class MissingValue extends InstructionViolation {
|
||||
MissingValue() { exists(Literal l | l = instruction | count(l.getValue()) != 1) }
|
||||
|
||||
override string getMessage() { result = "Literal has invalid getValue()" }
|
||||
@@ -79,7 +79,7 @@ deprecated class MissingValue extends InstructionViolation {
|
||||
/**
|
||||
* A call that does not have exactly one `getTarget()`.
|
||||
*/
|
||||
deprecated class MissingCallTarget extends InstructionViolation {
|
||||
class MissingCallTarget extends InstructionViolation {
|
||||
MissingCallTarget() {
|
||||
exists(Call c | c = instruction |
|
||||
count(c.getTarget()) != 1 and not c instanceof Opcodes::Calli
|
||||
@@ -94,7 +94,7 @@ deprecated class MissingCallTarget extends InstructionViolation {
|
||||
/**
|
||||
* An instruction that has not been assigned a specific QL class.
|
||||
*/
|
||||
deprecated class MissingOpCode extends InstructionViolation {
|
||||
class MissingOpCode extends InstructionViolation {
|
||||
MissingOpCode() { not exists(instruction.getOpcodeName()) }
|
||||
|
||||
override string getMessage() {
|
||||
@@ -114,7 +114,7 @@ deprecated class MissingOpCode extends InstructionViolation {
|
||||
* It could also mean that the target of a call has failed and has not determined the
|
||||
* correct number of arguments.
|
||||
*/
|
||||
deprecated class MissingOperand extends InstructionViolation {
|
||||
class MissingOperand extends InstructionViolation {
|
||||
MissingOperand() {
|
||||
exists(int op | op in [0 .. instruction.getPopCount() - 1] |
|
||||
not exists(instruction.getOperand(op)) and not instruction instanceof DeadInstruction
|
||||
@@ -136,7 +136,7 @@ deprecated class MissingOperand extends InstructionViolation {
|
||||
* These should not exist, however it turns out that the Mono compiler sometimes
|
||||
* emits them.
|
||||
*/
|
||||
deprecated class DeadInstruction extends Instruction {
|
||||
class DeadInstruction extends Instruction {
|
||||
DeadInstruction() { not exists(EntryPoint e | e.getASuccessor+() = this) }
|
||||
}
|
||||
|
||||
@@ -146,20 +146,20 @@ deprecated class DeadInstruction extends Instruction {
|
||||
* If this fails, it means that the calculation of the call graph is incorrect.
|
||||
* Disabled, because Mono compiler sometimes emits dead instructions.
|
||||
*/
|
||||
deprecated class DeadInstructionViolation extends InstructionViolation, DisabledCheck {
|
||||
class DeadInstructionViolation extends InstructionViolation, DisabledCheck {
|
||||
DeadInstructionViolation() { instruction instanceof DeadInstruction }
|
||||
|
||||
override string getMessage() { result = "This instruction is not reachable" }
|
||||
}
|
||||
|
||||
deprecated class YesNoBranch extends ConditionalBranch {
|
||||
class YesNoBranch extends ConditionalBranch {
|
||||
YesNoBranch() { not this instanceof Opcodes::Switch }
|
||||
}
|
||||
|
||||
/**
|
||||
* A branch instruction that does not have exactly 2 successors.
|
||||
*/
|
||||
deprecated class InvalidBranchSuccessors extends InstructionViolation {
|
||||
class InvalidBranchSuccessors extends InstructionViolation {
|
||||
InvalidBranchSuccessors() {
|
||||
// Mono compiler sometimes generates branches to the next instruction, which is just wrong.
|
||||
// However it is valid CIL.
|
||||
@@ -174,7 +174,7 @@ deprecated class InvalidBranchSuccessors extends InstructionViolation {
|
||||
/**
|
||||
* An instruction that has a true/false successor but is not a branch.
|
||||
*/
|
||||
deprecated class OnlyYesNoBranchHasTrueFalseSuccessors extends InstructionViolation {
|
||||
class OnlyYesNoBranchHasTrueFalseSuccessors extends InstructionViolation {
|
||||
OnlyYesNoBranchHasTrueFalseSuccessors() {
|
||||
(exists(instruction.getTrueSuccessor()) or exists(instruction.getFalseSuccessor())) and
|
||||
not instruction instanceof YesNoBranch
|
||||
@@ -186,7 +186,7 @@ deprecated class OnlyYesNoBranchHasTrueFalseSuccessors extends InstructionViolat
|
||||
/**
|
||||
* An unconditional branch instruction that has more than one successor.
|
||||
*/
|
||||
deprecated class UnconditionalBranchSuccessors extends InstructionViolation {
|
||||
class UnconditionalBranchSuccessors extends InstructionViolation {
|
||||
UnconditionalBranchSuccessors() {
|
||||
exists(UnconditionalBranch i | i = instruction | count(i.getASuccessor()) != 1)
|
||||
}
|
||||
@@ -199,7 +199,7 @@ deprecated class UnconditionalBranchSuccessors extends InstructionViolation {
|
||||
/**
|
||||
* A branch instruction that does not have a true successor.
|
||||
*/
|
||||
deprecated class NoTrueSuccessor extends InstructionViolation {
|
||||
class NoTrueSuccessor extends InstructionViolation {
|
||||
NoTrueSuccessor() { exists(YesNoBranch i | i = instruction | not exists(i.getTrueSuccessor())) }
|
||||
|
||||
override string getMessage() { result = "Missing a true successor" }
|
||||
@@ -208,7 +208,7 @@ deprecated class NoTrueSuccessor extends InstructionViolation {
|
||||
/**
|
||||
* A branch instruction that does not have a false successor.
|
||||
*/
|
||||
deprecated class NoFalseSuccessor extends InstructionViolation {
|
||||
class NoFalseSuccessor extends InstructionViolation {
|
||||
NoFalseSuccessor() { exists(YesNoBranch i | i = instruction | not exists(i.getFalseSuccessor())) }
|
||||
|
||||
override string getMessage() { result = "Missing a false successor" }
|
||||
@@ -217,7 +217,7 @@ deprecated class NoFalseSuccessor extends InstructionViolation {
|
||||
/**
|
||||
* An instruction whose true successor is not a successor.
|
||||
*/
|
||||
deprecated class TrueSuccessorIsSuccessor extends InstructionViolation {
|
||||
class TrueSuccessorIsSuccessor extends InstructionViolation {
|
||||
TrueSuccessorIsSuccessor() {
|
||||
exists(instruction.getTrueSuccessor()) and
|
||||
not instruction.getTrueSuccessor() = instruction.getASuccessor()
|
||||
@@ -229,7 +229,7 @@ deprecated class TrueSuccessorIsSuccessor extends InstructionViolation {
|
||||
/**
|
||||
* An instruction whose false successor is not a successor.
|
||||
*/
|
||||
deprecated class FalseSuccessorIsSuccessor extends InstructionViolation {
|
||||
class FalseSuccessorIsSuccessor extends InstructionViolation {
|
||||
FalseSuccessorIsSuccessor() {
|
||||
exists(instruction.getFalseSuccessor()) and
|
||||
not instruction.getFalseSuccessor() = instruction.getASuccessor()
|
||||
@@ -241,7 +241,7 @@ deprecated class FalseSuccessorIsSuccessor extends InstructionViolation {
|
||||
/**
|
||||
* An access that does not have exactly one target.
|
||||
*/
|
||||
deprecated class AccessMissingTarget extends InstructionViolation {
|
||||
class AccessMissingTarget extends InstructionViolation {
|
||||
AccessMissingTarget() { exists(Access i | i = instruction | count(i.getTarget()) != 1) }
|
||||
|
||||
override string getMessage() { result = "Access has invalid getTarget()" }
|
||||
@@ -250,7 +250,7 @@ deprecated class AccessMissingTarget extends InstructionViolation {
|
||||
/**
|
||||
* A catch handler that doesn't have a caught exception type.
|
||||
*/
|
||||
deprecated class CatchHandlerMissingType extends CfgViolation {
|
||||
class CatchHandlerMissingType extends CfgViolation {
|
||||
CatchHandlerMissingType() { exists(CatchHandler h | h = node | not exists(h.getCaughtType())) }
|
||||
|
||||
override string getMessage() { result = "Catch handler missing caught type" }
|
||||
@@ -259,7 +259,7 @@ deprecated class CatchHandlerMissingType extends CfgViolation {
|
||||
/**
|
||||
* A CFG node that does not have a stack size.
|
||||
*/
|
||||
deprecated class MissingStackSize extends CfgViolation {
|
||||
class MissingStackSize extends CfgViolation {
|
||||
MissingStackSize() {
|
||||
(
|
||||
not exists(node.getStackSizeAfter()) or
|
||||
@@ -275,7 +275,7 @@ deprecated class MissingStackSize extends CfgViolation {
|
||||
* A CFG node that does not have exactly one stack size.
|
||||
* Disabled because inconsistent stack sizes have been observed.
|
||||
*/
|
||||
deprecated class InvalidStackSize extends CfgViolation, DisabledCheck {
|
||||
class InvalidStackSize extends CfgViolation, DisabledCheck {
|
||||
InvalidStackSize() {
|
||||
(
|
||||
count(node.getStackSizeAfter()) != 1 or
|
||||
@@ -294,7 +294,7 @@ deprecated class InvalidStackSize extends CfgViolation, DisabledCheck {
|
||||
/**
|
||||
* A CFG node that does not have exactly 1 `getPopCount()`.
|
||||
*/
|
||||
deprecated class InconsistentPopCount extends CfgViolation {
|
||||
class InconsistentPopCount extends CfgViolation {
|
||||
InconsistentPopCount() { count(node.getPopCount()) != 1 }
|
||||
|
||||
override string getMessage() {
|
||||
@@ -305,7 +305,7 @@ deprecated class InconsistentPopCount extends CfgViolation {
|
||||
/**
|
||||
* A CFG node that does not have exactly one `getPushCount()`.
|
||||
*/
|
||||
deprecated class InconsistentPushCount extends CfgViolation {
|
||||
class InconsistentPushCount extends CfgViolation {
|
||||
InconsistentPushCount() { count(node.getPushCount()) != 1 }
|
||||
|
||||
override string getMessage() {
|
||||
@@ -316,7 +316,7 @@ deprecated class InconsistentPushCount extends CfgViolation {
|
||||
/**
|
||||
* A return instruction that does not have a stack size of 0 after it.
|
||||
*/
|
||||
deprecated class InvalidReturn extends InstructionViolation {
|
||||
class InvalidReturn extends InstructionViolation {
|
||||
InvalidReturn() { instruction instanceof Return and instruction.getStackSizeAfter() != 0 }
|
||||
|
||||
override string getMessage() { result = "Return has invalid stack size" }
|
||||
@@ -325,7 +325,7 @@ deprecated class InvalidReturn extends InstructionViolation {
|
||||
/**
|
||||
* A throw instruction that does not have a stack size of 0 after it.
|
||||
*/
|
||||
deprecated class InvalidThrow extends InstructionViolation, DisabledCheck {
|
||||
class InvalidThrow extends InstructionViolation, DisabledCheck {
|
||||
InvalidThrow() { instruction instanceof Throw and instruction.getStackSizeAfter() != 0 }
|
||||
|
||||
override string getMessage() {
|
||||
@@ -336,7 +336,7 @@ deprecated class InvalidThrow extends InstructionViolation, DisabledCheck {
|
||||
/**
|
||||
* A field access where the field is "static" but the instruction is "instance".
|
||||
*/
|
||||
deprecated class StaticFieldTarget extends InstructionViolation {
|
||||
class StaticFieldTarget extends InstructionViolation {
|
||||
StaticFieldTarget() {
|
||||
exists(FieldAccess i | i = instruction |
|
||||
(i instanceof Opcodes::Stfld or i instanceof Opcodes::Stfld) and
|
||||
@@ -350,7 +350,7 @@ deprecated class StaticFieldTarget extends InstructionViolation {
|
||||
/**
|
||||
* A branch without a target.
|
||||
*/
|
||||
deprecated class BranchWithoutTarget extends InstructionViolation {
|
||||
class BranchWithoutTarget extends InstructionViolation {
|
||||
BranchWithoutTarget() {
|
||||
instruction = any(Branch b | not exists(b.getTarget()) and not b instanceof Opcodes::Switch)
|
||||
}
|
||||
@@ -361,7 +361,7 @@ deprecated class BranchWithoutTarget extends InstructionViolation {
|
||||
/**
|
||||
* A consistency violation in a type.
|
||||
*/
|
||||
deprecated class TypeViolation extends ConsistencyViolation, TypeCheck {
|
||||
class TypeViolation extends ConsistencyViolation, TypeCheck {
|
||||
/** Gets the type containing the violation. */
|
||||
Type getType() { this = TypeCheck(result) }
|
||||
|
||||
@@ -373,7 +373,7 @@ deprecated class TypeViolation extends ConsistencyViolation, TypeCheck {
|
||||
/**
|
||||
* A type that has both type arguments and type parameters.
|
||||
*/
|
||||
deprecated class TypeIsBothConstructedAndUnbound extends TypeViolation {
|
||||
class TypeIsBothConstructedAndUnbound extends TypeViolation {
|
||||
TypeIsBothConstructedAndUnbound() {
|
||||
this.getType() instanceof ConstructedGeneric and this.getType() instanceof UnboundGeneric
|
||||
}
|
||||
@@ -385,7 +385,7 @@ deprecated class TypeIsBothConstructedAndUnbound extends TypeViolation {
|
||||
* The location of a constructed generic type should be the same
|
||||
* as the location of its unbound generic type.
|
||||
*/
|
||||
deprecated class InconsistentTypeLocation extends TypeViolation {
|
||||
class InconsistentTypeLocation extends TypeViolation {
|
||||
InconsistentTypeLocation() {
|
||||
this.getType().getLocation() != this.getType().getUnboundDeclaration().getLocation()
|
||||
}
|
||||
@@ -396,7 +396,7 @@ deprecated class InconsistentTypeLocation extends TypeViolation {
|
||||
/**
|
||||
* A constructed type that does not match its unbound generic type.
|
||||
*/
|
||||
deprecated class TypeParameterMismatch extends TypeViolation {
|
||||
class TypeParameterMismatch extends TypeViolation {
|
||||
TypeParameterMismatch() {
|
||||
this.getType().(ConstructedGeneric).getNumberOfTypeArguments() !=
|
||||
this.getType().getUnboundType().(UnboundGeneric).getNumberOfTypeParameters()
|
||||
@@ -415,7 +415,7 @@ deprecated class TypeParameterMismatch extends TypeViolation {
|
||||
/**
|
||||
* A consistency violation in a method.
|
||||
*/
|
||||
deprecated class MethodViolation extends ConsistencyViolation, DeclarationCheck {
|
||||
class MethodViolation extends ConsistencyViolation, DeclarationCheck {
|
||||
/** Gets the method containing the violation. */
|
||||
Method getMethod() { this = DeclarationCheck(result) }
|
||||
|
||||
@@ -428,7 +428,7 @@ deprecated class MethodViolation extends ConsistencyViolation, DeclarationCheck
|
||||
* The location of a constructed method should be equal to the
|
||||
* location of its unbound generic.
|
||||
*/
|
||||
deprecated class InconsistentMethodLocation extends MethodViolation {
|
||||
class InconsistentMethodLocation extends MethodViolation {
|
||||
InconsistentMethodLocation() {
|
||||
this.getMethod().getLocation() != this.getMethod().getUnboundDeclaration().getLocation()
|
||||
}
|
||||
@@ -439,7 +439,7 @@ deprecated class InconsistentMethodLocation extends MethodViolation {
|
||||
/**
|
||||
* A constructed method that does not match its unbound method.
|
||||
*/
|
||||
deprecated class ConstructedMethodTypeParams extends MethodViolation {
|
||||
class ConstructedMethodTypeParams extends MethodViolation {
|
||||
ConstructedMethodTypeParams() {
|
||||
this.getMethod().(ConstructedGeneric).getNumberOfTypeArguments() !=
|
||||
this.getMethod().getUnboundDeclaration().(UnboundGeneric).getNumberOfTypeParameters()
|
||||
@@ -456,14 +456,14 @@ deprecated class ConstructedMethodTypeParams extends MethodViolation {
|
||||
/**
|
||||
* A violation marking an entity that should be present but is not.
|
||||
*/
|
||||
abstract deprecated class MissingEntityViolation extends ConsistencyViolation, MissingEntityCheck {
|
||||
abstract class MissingEntityViolation extends ConsistencyViolation, MissingEntityCheck {
|
||||
override string toString() { result = "Missing entity" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The type `object` is missing from the database.
|
||||
*/
|
||||
deprecated class MissingObjectViolation extends MissingEntityViolation {
|
||||
class MissingObjectViolation extends MissingEntityViolation {
|
||||
MissingObjectViolation() {
|
||||
exists(this) and
|
||||
not exists(ObjectType o)
|
||||
@@ -475,7 +475,7 @@ deprecated class MissingObjectViolation extends MissingEntityViolation {
|
||||
/**
|
||||
* An override that is invalid because the overridden method is not in a base class.
|
||||
*/
|
||||
deprecated class InvalidOverride extends MethodViolation {
|
||||
class InvalidOverride extends MethodViolation {
|
||||
private Method base;
|
||||
|
||||
InvalidOverride() {
|
||||
@@ -497,7 +497,7 @@ deprecated class InvalidOverride extends MethodViolation {
|
||||
/**
|
||||
* A pointer type that does not have a pointee type.
|
||||
*/
|
||||
deprecated class InvalidPointerType extends TypeViolation {
|
||||
class InvalidPointerType extends TypeViolation {
|
||||
InvalidPointerType() {
|
||||
exists(PointerType p | p = this.getType() | count(p.getReferentType()) != 1)
|
||||
}
|
||||
@@ -508,7 +508,7 @@ deprecated class InvalidPointerType extends TypeViolation {
|
||||
/**
|
||||
* An array with an invalid `getElementType`.
|
||||
*/
|
||||
deprecated class ArrayTypeMissingElement extends TypeViolation {
|
||||
class ArrayTypeMissingElement extends TypeViolation {
|
||||
ArrayTypeMissingElement() {
|
||||
exists(ArrayType t | t = this.getType() | count(t.getElementType()) != 1)
|
||||
}
|
||||
@@ -519,7 +519,7 @@ deprecated class ArrayTypeMissingElement extends TypeViolation {
|
||||
/**
|
||||
* An array with an invalid `getRank`.
|
||||
*/
|
||||
deprecated class ArrayTypeInvalidRank extends TypeViolation {
|
||||
class ArrayTypeInvalidRank extends TypeViolation {
|
||||
ArrayTypeInvalidRank() { exists(ArrayType t | t = this.getType() | not t.getRank() > 0) }
|
||||
|
||||
override string getMessage() { result = "Invalid ArrayType.getRank()" }
|
||||
@@ -529,7 +529,7 @@ deprecated class ArrayTypeInvalidRank extends TypeViolation {
|
||||
* A type should have at most one kind, except for missing referenced types
|
||||
* where the interface/class is unknown.
|
||||
*/
|
||||
deprecated class KindViolation extends TypeViolation {
|
||||
class KindViolation extends TypeViolation {
|
||||
KindViolation() {
|
||||
count(typeKind(this.getType())) != 1 and
|
||||
exists(this.getType().getLocation())
|
||||
@@ -544,7 +544,7 @@ deprecated class KindViolation extends TypeViolation {
|
||||
* The type of a kind must be consistent between a constructed generic and its
|
||||
* unbound generic.
|
||||
*/
|
||||
deprecated class InconsistentKind extends TypeViolation {
|
||||
class InconsistentKind extends TypeViolation {
|
||||
InconsistentKind() {
|
||||
typeKind(this.getType()) != typeKind(this.getType().getUnboundDeclaration())
|
||||
}
|
||||
@@ -552,7 +552,7 @@ deprecated class InconsistentKind extends TypeViolation {
|
||||
override string getMessage() { result = "Inconsistent type kind of source declaration" }
|
||||
}
|
||||
|
||||
deprecated private string typeKind(Type t) {
|
||||
private string typeKind(Type t) {
|
||||
t instanceof Interface and result = "interface"
|
||||
or
|
||||
t instanceof Class and result = "class"
|
||||
@@ -567,7 +567,7 @@ deprecated private string typeKind(Type t) {
|
||||
/**
|
||||
* A violation in a `Member`.
|
||||
*/
|
||||
abstract deprecated class DeclarationViolation extends ConsistencyViolation, DeclarationCheck {
|
||||
abstract class DeclarationViolation extends ConsistencyViolation, DeclarationCheck {
|
||||
abstract override string getMessage();
|
||||
|
||||
/** Gets the member containing the potential violation. */
|
||||
@@ -579,7 +579,7 @@ abstract deprecated class DeclarationViolation extends ConsistencyViolation, Dec
|
||||
/**
|
||||
* Properties that have no accessors.
|
||||
*/
|
||||
deprecated class PropertyWithNoAccessors extends DeclarationViolation {
|
||||
class PropertyWithNoAccessors extends DeclarationViolation {
|
||||
PropertyWithNoAccessors() {
|
||||
exists(Property p | p = this.getDeclaration() | not exists(p.getAnAccessor()))
|
||||
}
|
||||
@@ -590,7 +590,7 @@ deprecated class PropertyWithNoAccessors extends DeclarationViolation {
|
||||
/**
|
||||
* An expression that have an unexpected push count.
|
||||
*/
|
||||
deprecated class ExprPushCount extends InstructionViolation {
|
||||
class ExprPushCount extends InstructionViolation {
|
||||
ExprPushCount() {
|
||||
instruction instanceof Expr and
|
||||
not instruction instanceof Opcodes::Dup and
|
||||
@@ -608,7 +608,7 @@ deprecated class ExprPushCount extends InstructionViolation {
|
||||
* An expression that does not have exactly one type.
|
||||
* Note that calls with no return have type `System.Void`.
|
||||
*/
|
||||
deprecated class ExprMissingType extends InstructionViolation {
|
||||
class ExprMissingType extends InstructionViolation {
|
||||
ExprMissingType() {
|
||||
// Don't have types for the following op codes:
|
||||
not instruction instanceof Opcodes::Ldftn and
|
||||
@@ -632,7 +632,7 @@ deprecated class ExprMissingType extends InstructionViolation {
|
||||
/**
|
||||
* An instruction that has a push count of 0, yet is still used as an operand
|
||||
*/
|
||||
deprecated class InvalidExpressionViolation extends InstructionViolation {
|
||||
class InvalidExpressionViolation extends InstructionViolation {
|
||||
InvalidExpressionViolation() {
|
||||
instruction.getPushCount() = 0 and
|
||||
exists(Instruction expr | instruction = expr.getAnOperand())
|
||||
@@ -647,7 +647,7 @@ deprecated class InvalidExpressionViolation extends InstructionViolation {
|
||||
* A type that has multiple entities with the same qualified name in `System`.
|
||||
* .NET Core does sometimes duplicate types, so this check is disabled.
|
||||
*/
|
||||
deprecated class TypeMultiplyDefined extends TypeViolation, DisabledCheck {
|
||||
class TypeMultiplyDefined extends TypeViolation, DisabledCheck {
|
||||
TypeMultiplyDefined() {
|
||||
this.getType().getParent().getName() = "System" and
|
||||
not this.getType() instanceof ConstructedGeneric and
|
||||
@@ -672,7 +672,7 @@ deprecated class TypeMultiplyDefined extends TypeViolation, DisabledCheck {
|
||||
/**
|
||||
* A C# declaration which is expected to have a corresponding CIL declaration, but for some reason does not.
|
||||
*/
|
||||
deprecated class MissingCilDeclaration extends ConsistencyViolation, MissingCSharpCheck {
|
||||
class MissingCilDeclaration extends ConsistencyViolation, MissingCSharpCheck {
|
||||
MissingCilDeclaration() {
|
||||
exists(CS::Declaration decl | this = MissingCSharpCheck(decl) |
|
||||
expectedCilDeclaration(decl) and
|
||||
@@ -694,7 +694,7 @@ deprecated class MissingCilDeclaration extends ConsistencyViolation, MissingCSha
|
||||
/**
|
||||
* Holds if the C# declaration is expected to have a CIl declaration.
|
||||
*/
|
||||
deprecated private predicate expectedCilDeclaration(CS::Declaration decl) {
|
||||
private predicate expectedCilDeclaration(CS::Declaration decl) {
|
||||
decl = decl.getUnboundDeclaration() and
|
||||
not decl instanceof CS::ArrayType and
|
||||
decl.getALocation() instanceof CS::Assembly and
|
||||
@@ -730,7 +730,7 @@ deprecated private predicate expectedCilDeclaration(CS::Declaration decl) {
|
||||
}
|
||||
|
||||
/** A member with an invalid name. */
|
||||
deprecated class MemberWithInvalidName extends DeclarationViolation {
|
||||
class MemberWithInvalidName extends DeclarationViolation {
|
||||
MemberWithInvalidName() {
|
||||
exists(string name | name = this.getDeclaration().(Member).getName() |
|
||||
exists(name.indexOf(".")) and
|
||||
@@ -744,7 +744,7 @@ deprecated class MemberWithInvalidName extends DeclarationViolation {
|
||||
}
|
||||
}
|
||||
|
||||
deprecated class ConstructedSourceDeclarationMethod extends MethodViolation {
|
||||
class ConstructedSourceDeclarationMethod extends MethodViolation {
|
||||
Method method;
|
||||
|
||||
ConstructedSourceDeclarationMethod() {
|
||||
@@ -762,7 +762,7 @@ deprecated class ConstructedSourceDeclarationMethod extends MethodViolation {
|
||||
}
|
||||
|
||||
/** A declaration with multiple labels. */
|
||||
deprecated class DeclarationWithMultipleLabels extends DeclarationViolation {
|
||||
class DeclarationWithMultipleLabels extends DeclarationViolation {
|
||||
DeclarationWithMultipleLabels() {
|
||||
exists(Declaration d | this = DeclarationCheck(d) | strictcount(d.getLabel()) > 1)
|
||||
}
|
||||
@@ -773,7 +773,7 @@ deprecated class DeclarationWithMultipleLabels extends DeclarationViolation {
|
||||
}
|
||||
|
||||
/** A declaration without a label. */
|
||||
deprecated class DeclarationWithoutLabel extends DeclarationViolation {
|
||||
class DeclarationWithoutLabel extends DeclarationViolation {
|
||||
DeclarationWithoutLabel() {
|
||||
exists(Declaration d | this = DeclarationCheck(d) |
|
||||
d.isUnboundDeclaration() and
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
private import CIL
|
||||
|
||||
/** A node in the control flow graph. */
|
||||
deprecated class ControlFlowNode extends @cil_controlflow_node {
|
||||
class ControlFlowNode extends @cil_controlflow_node {
|
||||
/** Gets a textual representation of this control flow node. */
|
||||
string toString() { none() }
|
||||
|
||||
@@ -149,31 +149,31 @@ deprecated class ControlFlowNode extends @cil_controlflow_node {
|
||||
*
|
||||
* Handlers are control flow nodes because they push the handled exception onto the stack.
|
||||
*/
|
||||
deprecated class EntryPoint extends ControlFlowNode, @cil_entry_point {
|
||||
class EntryPoint extends ControlFlowNode, @cil_entry_point {
|
||||
override int getStackSizeBefore() { result = 0 }
|
||||
}
|
||||
|
||||
deprecated private newtype TFlowType =
|
||||
private newtype TFlowType =
|
||||
TNormalFlow() or
|
||||
TTrueFlow() or
|
||||
TFalseFlow()
|
||||
|
||||
/** A type of control flow. Either normal flow (`NormalFlow`), true flow (`TrueFlow`) or false flow (`FalseFlow`). */
|
||||
abstract deprecated class FlowType extends TFlowType {
|
||||
abstract class FlowType extends TFlowType {
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
/** Normal control flow. */
|
||||
deprecated class NormalFlow extends FlowType, TNormalFlow {
|
||||
class NormalFlow extends FlowType, TNormalFlow {
|
||||
override string toString() { result = "" }
|
||||
}
|
||||
|
||||
/** True control flow. */
|
||||
deprecated class TrueFlow extends FlowType, TTrueFlow {
|
||||
class TrueFlow extends FlowType, TTrueFlow {
|
||||
override string toString() { result = "true" }
|
||||
}
|
||||
|
||||
/** False control flow. */
|
||||
deprecated class FalseFlow extends FlowType, TFalseFlow {
|
||||
class FalseFlow extends FlowType, TFalseFlow {
|
||||
override string toString() { result = "false" }
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ private import dotnet
|
||||
* - the type of parameters.
|
||||
* A `CustomModifierReceiver` is therefore either a `Field`, `Property`, `Method`, or `Parameter`.
|
||||
*/
|
||||
deprecated class CustomModifierReceiver extends Declaration, @cil_custom_modifier_receiver {
|
||||
class CustomModifierReceiver extends Declaration, @cil_custom_modifier_receiver {
|
||||
/** Holds if this targeted type has `modifier` applied as `modreq`. */
|
||||
predicate hasRequiredCustomModifier(Type modifier) { cil_custom_modifiers(this, modifier, 1) }
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ private import CIL
|
||||
*
|
||||
* Either an instruction (`Instruction`), a method return (`Method`), or a variable (`Variable`).
|
||||
*/
|
||||
deprecated class DataFlowNode extends @cil_dataflow_node {
|
||||
class DataFlowNode extends @cil_dataflow_node {
|
||||
/** Gets a textual representation of this data flow node. */
|
||||
abstract string toString();
|
||||
|
||||
@@ -24,7 +24,7 @@ deprecated class DataFlowNode extends @cil_dataflow_node {
|
||||
}
|
||||
|
||||
/** A node that updates a variable. */
|
||||
abstract deprecated class VariableUpdate extends DataFlowNode {
|
||||
abstract class VariableUpdate extends DataFlowNode {
|
||||
/** Gets the value assigned, if any. */
|
||||
abstract DataFlowNode getSource();
|
||||
|
||||
@@ -35,7 +35,7 @@ abstract deprecated class VariableUpdate extends DataFlowNode {
|
||||
abstract predicate updatesAt(BasicBlock bb, int i);
|
||||
}
|
||||
|
||||
deprecated private class MethodParameterDef extends VariableUpdate, MethodParameter {
|
||||
private class MethodParameterDef extends VariableUpdate, MethodParameter {
|
||||
override MethodParameter getSource() { result = this }
|
||||
|
||||
override MethodParameter getVariable() { result = this }
|
||||
@@ -46,7 +46,7 @@ deprecated private class MethodParameterDef extends VariableUpdate, MethodParame
|
||||
}
|
||||
}
|
||||
|
||||
deprecated private class VariableWrite extends VariableUpdate, WriteAccess {
|
||||
private class VariableWrite extends VariableUpdate, WriteAccess {
|
||||
override Expr getSource() { result = this.getExpr() }
|
||||
|
||||
override Variable getVariable() { result = this.getTarget() }
|
||||
@@ -54,7 +54,7 @@ deprecated private class VariableWrite extends VariableUpdate, WriteAccess {
|
||||
override predicate updatesAt(BasicBlock bb, int i) { this = bb.getNode(i) }
|
||||
}
|
||||
|
||||
deprecated private class MethodOutOrRefTarget extends VariableUpdate, Call {
|
||||
private class MethodOutOrRefTarget extends VariableUpdate, Call {
|
||||
int parameterIndex;
|
||||
|
||||
MethodOutOrRefTarget() { this.getTarget().getRawParameter(parameterIndex).hasOutFlag() }
|
||||
|
||||
@@ -10,7 +10,7 @@ private import semmle.code.csharp.commons.QualifiedName
|
||||
/**
|
||||
* A declaration. Either a member (`Member`) or a variable (`Variable`).
|
||||
*/
|
||||
deprecated class Declaration extends DotNet::Declaration, Element, @cil_declaration {
|
||||
class Declaration extends DotNet::Declaration, Element, @cil_declaration {
|
||||
/** Gets an attribute (for example `[Obsolete]`) of this declaration, if any. */
|
||||
Attribute getAnAttribute() { result.getDeclaration() = this }
|
||||
|
||||
@@ -42,18 +42,14 @@ deprecated class Declaration extends DotNet::Declaration, Element, @cil_declarat
|
||||
}
|
||||
}
|
||||
|
||||
deprecated private CS::Declaration toCSharpNonTypeParameter(Declaration d) {
|
||||
result.(DotNet::Declaration).matchesHandle(d)
|
||||
}
|
||||
private CS::Declaration toCSharpNonTypeParameter(Declaration d) { result.matchesHandle(d) }
|
||||
|
||||
deprecated private CS::TypeParameter toCSharpTypeParameter(TypeParameter tp) {
|
||||
private CS::TypeParameter toCSharpTypeParameter(TypeParameter tp) {
|
||||
toCSharpTypeParameterJoin(tp, result.getIndex(), result.getGeneric())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
deprecated private predicate toCSharpTypeParameterJoin(
|
||||
TypeParameter tp, int i, CS::UnboundGeneric ug
|
||||
) {
|
||||
private predicate toCSharpTypeParameterJoin(TypeParameter tp, int i, CS::UnboundGeneric ug) {
|
||||
exists(TypeContainer tc |
|
||||
tp.getIndex() = i and
|
||||
tc = tp.getGeneric() and
|
||||
@@ -64,7 +60,7 @@ deprecated private predicate toCSharpTypeParameterJoin(
|
||||
/**
|
||||
* A member of a type. Either a type (`Type`), a method (`Method`), a property (`Property`), or an event (`Event`).
|
||||
*/
|
||||
deprecated class Member extends DotNet::Member, Declaration, @cil_member {
|
||||
class Member extends DotNet::Member, Declaration, @cil_member {
|
||||
override predicate isPublic() { cil_public(this) }
|
||||
|
||||
override predicate isProtected() { cil_protected(this) }
|
||||
@@ -86,7 +82,7 @@ deprecated class Member extends DotNet::Member, Declaration, @cil_member {
|
||||
}
|
||||
|
||||
/** A property. */
|
||||
deprecated class Property extends DotNet::Property, Member, CustomModifierReceiver, @cil_property {
|
||||
class Property extends DotNet::Property, Member, CustomModifierReceiver, @cil_property {
|
||||
override string getName() { cil_property(this, _, result, _) }
|
||||
|
||||
/** Gets the type of this property. */
|
||||
@@ -113,7 +109,7 @@ deprecated class Property extends DotNet::Property, Member, CustomModifierReceiv
|
||||
}
|
||||
|
||||
/** A property that is trivial (wraps a field). */
|
||||
deprecated class TrivialProperty extends Property {
|
||||
class TrivialProperty extends Property {
|
||||
TrivialProperty() {
|
||||
this.getGetter().(TrivialGetter).getField() = this.getSetter().(TrivialSetter).getField()
|
||||
}
|
||||
@@ -123,7 +119,7 @@ deprecated class TrivialProperty extends Property {
|
||||
}
|
||||
|
||||
/** An event. */
|
||||
deprecated class Event extends DotNet::Event, Member, @cil_event {
|
||||
class Event extends DotNet::Event, Member, @cil_event {
|
||||
override string getName() { cil_event(this, _, result, _) }
|
||||
|
||||
/** Gets the type of this event. */
|
||||
|
||||
@@ -4,12 +4,12 @@ private import dotnet
|
||||
import semmle.code.csharp.Location
|
||||
|
||||
/** An element. */
|
||||
deprecated class Element extends DotNet::Element, @cil_element {
|
||||
class Element extends DotNet::Element, @cil_element {
|
||||
override Location getLocation() { result = bestLocation(this) }
|
||||
}
|
||||
|
||||
cached
|
||||
deprecated private Location bestLocation(Element e) {
|
||||
private Location bestLocation(Element e) {
|
||||
result = e.getALocation() and
|
||||
(e.getALocation().getFile().isPdbSourceFile() implies result.getFile().isPdbSourceFile())
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ private import dotnet
|
||||
* A generic declaration. Either an unbound generic (`UnboundGeneric`) or a
|
||||
* constructed generic (`ConstructedGeneric`).
|
||||
*/
|
||||
deprecated class Generic extends DotNet::Generic, Declaration, TypeContainer {
|
||||
class Generic extends DotNet::Generic, Declaration, TypeContainer {
|
||||
Generic() {
|
||||
cil_type_parameter(this, _, _) or
|
||||
cil_type_argument(this, _, _)
|
||||
@@ -15,14 +15,14 @@ deprecated class Generic extends DotNet::Generic, Declaration, TypeContainer {
|
||||
}
|
||||
|
||||
/** An unbound generic type or method. */
|
||||
deprecated class UnboundGeneric extends Generic, DotNet::UnboundGeneric {
|
||||
class UnboundGeneric extends Generic, DotNet::UnboundGeneric {
|
||||
UnboundGeneric() { cil_type_parameter(this, _, _) }
|
||||
|
||||
final override TypeParameter getTypeParameter(int n) { cil_type_parameter(this, n, result) }
|
||||
}
|
||||
|
||||
/** A constructed generic type or method. */
|
||||
deprecated class ConstructedGeneric extends Generic, DotNet::ConstructedGeneric {
|
||||
class ConstructedGeneric extends Generic, DotNet::ConstructedGeneric {
|
||||
ConstructedGeneric() { cil_type_argument(this, _, _) }
|
||||
|
||||
final override Type getTypeArgument(int n) { cil_type_argument(this, n, result) }
|
||||
@@ -30,18 +30,18 @@ deprecated class ConstructedGeneric extends Generic, DotNet::ConstructedGeneric
|
||||
|
||||
/** Gets the concatenation of the `getName()` of type arguments. */
|
||||
language[monotonicAggregates]
|
||||
deprecated private string getTypeArgumentsNames(ConstructedGeneric cg) {
|
||||
private string getTypeArgumentsNames(ConstructedGeneric cg) {
|
||||
result = strictconcat(Type t, int i | t = cg.getTypeArgument(i) | t.getName(), "," order by i)
|
||||
}
|
||||
|
||||
/** An unbound generic type. */
|
||||
deprecated class UnboundGenericType extends UnboundGeneric, Type { }
|
||||
class UnboundGenericType extends UnboundGeneric, Type { }
|
||||
|
||||
/** An unbound generic method. */
|
||||
deprecated class UnboundGenericMethod extends UnboundGeneric, Method { }
|
||||
class UnboundGenericMethod extends UnboundGeneric, Method { }
|
||||
|
||||
/** A constructed generic type. */
|
||||
deprecated class ConstructedType extends ConstructedGeneric, Type {
|
||||
class ConstructedType extends ConstructedGeneric, Type {
|
||||
final override UnboundGenericType getUnboundGeneric() { result = this.getUnboundType() }
|
||||
|
||||
override predicate isInterface() { this.getUnboundType().isInterface() }
|
||||
@@ -54,6 +54,6 @@ deprecated class ConstructedType extends ConstructedGeneric, Type {
|
||||
}
|
||||
|
||||
/** A constructed generic method. */
|
||||
deprecated class ConstructedMethod extends ConstructedGeneric, Method {
|
||||
class ConstructedMethod extends ConstructedGeneric, Method {
|
||||
final override UnboundGenericMethod getUnboundGeneric() { result = this.getUnboundMethod() }
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ private import CIL
|
||||
* Either a finally handler (`FinallyHandler`), filter handler (`FilterHandler`),
|
||||
* catch handler (`CatchHandler`), or a fault handler (`FaultHandler`).
|
||||
*/
|
||||
deprecated class Handler extends Element, EntryPoint, @cil_handler {
|
||||
class Handler extends Element, EntryPoint, @cil_handler {
|
||||
override MethodImplementation getImplementation() { cil_handler(this, result, _, _, _, _, _) }
|
||||
|
||||
/** Gets the 0-based index of this handler. Handlers are evaluated in this sequence. */
|
||||
@@ -56,12 +56,12 @@ deprecated class Handler extends Element, EntryPoint, @cil_handler {
|
||||
}
|
||||
|
||||
/** A handler corresponding to a `finally` block. */
|
||||
deprecated class FinallyHandler extends Handler, @cil_finally_handler {
|
||||
class FinallyHandler extends Handler, @cil_finally_handler {
|
||||
override string toString() { result = "finally {...}" }
|
||||
}
|
||||
|
||||
/** A handler corresponding to a `where()` clause. */
|
||||
deprecated class FilterHandler extends Handler, @cil_filter_handler {
|
||||
class FilterHandler extends Handler, @cil_filter_handler {
|
||||
override string toString() { result = "where (...)" }
|
||||
|
||||
/** Gets the filter clause - the start of a sequence of instructions to evaluate the filter function. */
|
||||
@@ -71,13 +71,13 @@ deprecated class FilterHandler extends Handler, @cil_filter_handler {
|
||||
}
|
||||
|
||||
/** A handler corresponding to a `catch` clause. */
|
||||
deprecated class CatchHandler extends Handler, @cil_catch_handler {
|
||||
class CatchHandler extends Handler, @cil_catch_handler {
|
||||
override string toString() { result = "catch(" + this.getCaughtType().getName() + ") {...}" }
|
||||
|
||||
override int getPushCount() { result = 1 }
|
||||
}
|
||||
|
||||
/** A handler for memory faults. */
|
||||
deprecated class FaultHandler extends Handler, @cil_fault_handler {
|
||||
class FaultHandler extends Handler, @cil_fault_handler {
|
||||
override string toString() { result = "fault {...}" }
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
private import CIL
|
||||
|
||||
/** An instruction. */
|
||||
deprecated class Instruction extends Element, ControlFlowNode, DataFlowNode, @cil_instruction {
|
||||
class Instruction extends Element, ControlFlowNode, DataFlowNode, @cil_instruction {
|
||||
override string toString() { result = this.getOpcodeName() }
|
||||
|
||||
/** Gets a more verbose textual representation of this instruction. */
|
||||
|
||||
@@ -9,7 +9,7 @@ private import dotnet
|
||||
/**
|
||||
* An instruction that pushes a value onto the stack.
|
||||
*/
|
||||
deprecated class Expr extends DotNet::Expr, Instruction, @cil_expr {
|
||||
class Expr extends DotNet::Expr, Instruction, @cil_expr {
|
||||
override int getPushCount() { result = 1 }
|
||||
|
||||
override Type getType() { result = Instruction.super.getType() }
|
||||
@@ -24,7 +24,7 @@ deprecated class Expr extends DotNet::Expr, Instruction, @cil_expr {
|
||||
}
|
||||
|
||||
/** An instruction that changes control flow. */
|
||||
deprecated class Branch extends Instruction, @cil_jump {
|
||||
class Branch extends Instruction, @cil_jump {
|
||||
/** Gets the instruction that is jumped to. */
|
||||
Instruction getTarget() { cil_jump(this, result) }
|
||||
|
||||
@@ -32,7 +32,7 @@ deprecated class Branch extends Instruction, @cil_jump {
|
||||
}
|
||||
|
||||
/** An instruction that unconditionally jumps to another instruction. */
|
||||
deprecated class UnconditionalBranch extends Branch, @cil_unconditional_jump {
|
||||
class UnconditionalBranch extends Branch, @cil_unconditional_jump {
|
||||
override Instruction getASuccessorType(FlowType t) {
|
||||
t instanceof NormalFlow and result = this.getTarget()
|
||||
}
|
||||
@@ -41,7 +41,7 @@ deprecated class UnconditionalBranch extends Branch, @cil_unconditional_jump {
|
||||
}
|
||||
|
||||
/** An instruction that jumps to a target based on a condition. */
|
||||
deprecated class ConditionalBranch extends Branch, @cil_conditional_jump {
|
||||
class ConditionalBranch extends Branch, @cil_conditional_jump {
|
||||
override Instruction getASuccessorType(FlowType t) {
|
||||
t instanceof TrueFlow and result = this.getTarget()
|
||||
or
|
||||
@@ -52,12 +52,12 @@ deprecated class ConditionalBranch extends Branch, @cil_conditional_jump {
|
||||
}
|
||||
|
||||
/** An expression with two operands. */
|
||||
deprecated class BinaryExpr extends Expr, @cil_binary_expr {
|
||||
class BinaryExpr extends Expr, @cil_binary_expr {
|
||||
override int getPopCount() { result = 2 }
|
||||
}
|
||||
|
||||
/** An expression with one operand. */
|
||||
deprecated class UnaryExpr extends Expr, @cil_unary_expr {
|
||||
class UnaryExpr extends Expr, @cil_unary_expr {
|
||||
override int getPopCount() { result = 1 }
|
||||
|
||||
/** Gets the operand of this unary expression. */
|
||||
@@ -65,12 +65,12 @@ deprecated class UnaryExpr extends Expr, @cil_unary_expr {
|
||||
}
|
||||
|
||||
/** A binary expression that compares two values. */
|
||||
deprecated class ComparisonOperation extends BinaryExpr, @cil_comparison_operation {
|
||||
class ComparisonOperation extends BinaryExpr, @cil_comparison_operation {
|
||||
override BoolType getType() { exists(result) }
|
||||
}
|
||||
|
||||
/** A binary arithmetic expression. */
|
||||
deprecated class BinaryArithmeticExpr extends BinaryExpr, @cil_binary_arithmetic_operation {
|
||||
class BinaryArithmeticExpr extends BinaryExpr, @cil_binary_arithmetic_operation {
|
||||
override Type getType() {
|
||||
exists(Type t0, Type t1 |
|
||||
t0 = this.getOperandType(0).getUnderlyingType() and
|
||||
@@ -86,28 +86,28 @@ deprecated class BinaryArithmeticExpr extends BinaryExpr, @cil_binary_arithmetic
|
||||
}
|
||||
|
||||
/** A binary bitwise expression. */
|
||||
deprecated class BinaryBitwiseOperation extends BinaryExpr, @cil_binary_bitwise_operation {
|
||||
class BinaryBitwiseOperation extends BinaryExpr, @cil_binary_bitwise_operation {
|
||||
// This is wrong but efficient - should depend on the types of the operands.
|
||||
override IntType getType() { exists(result) }
|
||||
}
|
||||
|
||||
/** A unary bitwise expression. */
|
||||
deprecated class UnaryBitwiseOperation extends UnaryExpr, @cil_unary_bitwise_operation {
|
||||
class UnaryBitwiseOperation extends UnaryExpr, @cil_unary_bitwise_operation {
|
||||
// This is wrong but efficient - should depend on the types of the operands.
|
||||
override IntType getType() { exists(result) }
|
||||
}
|
||||
|
||||
/** A unary expression that converts a value from one primitive type to another. */
|
||||
deprecated class Conversion extends UnaryExpr, @cil_conversion_operation {
|
||||
class Conversion extends UnaryExpr, @cil_conversion_operation {
|
||||
/** Gets the expression being converted. */
|
||||
Expr getExpr() { result = this.getOperand(0) }
|
||||
}
|
||||
|
||||
/** A branch that leaves the scope of a `Handler`. */
|
||||
deprecated class Leave extends UnconditionalBranch, @cil_leave_any { }
|
||||
class Leave extends UnconditionalBranch, @cil_leave_any { }
|
||||
|
||||
/** An expression that pushes a literal value onto the stack. */
|
||||
deprecated class Literal extends DotNet::Literal, Expr, @cil_literal {
|
||||
class Literal extends DotNet::Literal, Expr, @cil_literal {
|
||||
/** Gets the pushed value. */
|
||||
override string getValue() { cil_value(this, result) }
|
||||
|
||||
@@ -115,37 +115,37 @@ deprecated class Literal extends DotNet::Literal, Expr, @cil_literal {
|
||||
}
|
||||
|
||||
/** An integer literal. */
|
||||
deprecated class IntLiteral extends Literal, @cil_ldc_i {
|
||||
class IntLiteral extends Literal, @cil_ldc_i {
|
||||
override string getExtra() { none() }
|
||||
|
||||
override IntType getType() { exists(result) }
|
||||
}
|
||||
|
||||
/** An expression that pushes a `float`/`Single`. */
|
||||
deprecated class FloatLiteral extends Literal, @cil_ldc_r { }
|
||||
class FloatLiteral extends Literal, @cil_ldc_r { }
|
||||
|
||||
/** An expression that pushes a `null` value onto the stack. */
|
||||
deprecated class NullLiteral extends Literal, @cil_ldnull { }
|
||||
class NullLiteral extends Literal, @cil_ldnull { }
|
||||
|
||||
/** An expression that pushes a string onto the stack. */
|
||||
deprecated class StringLiteral extends Literal, @cil_ldstr { }
|
||||
class StringLiteral extends Literal, @cil_ldstr { }
|
||||
|
||||
/** A branch with one operand. */
|
||||
deprecated class UnaryBranch extends ConditionalBranch, @cil_unary_jump {
|
||||
class UnaryBranch extends ConditionalBranch, @cil_unary_jump {
|
||||
override int getPopCount() { result = 1 }
|
||||
|
||||
override int getPushCount() { result = 0 }
|
||||
}
|
||||
|
||||
/** A branch with two operands. */
|
||||
deprecated class BinaryBranch extends ConditionalBranch, @cil_binary_jump {
|
||||
class BinaryBranch extends ConditionalBranch, @cil_binary_jump {
|
||||
override int getPopCount() { result = 2 }
|
||||
|
||||
override int getPushCount() { result = 0 }
|
||||
}
|
||||
|
||||
/** A call. */
|
||||
deprecated class Call extends Expr, DotNet::Call, @cil_call_any {
|
||||
class Call extends Expr, DotNet::Call, @cil_call_any {
|
||||
/** Gets the method that is called. */
|
||||
override Method getTarget() { cil_access(this, result) }
|
||||
|
||||
@@ -198,24 +198,24 @@ deprecated class Call extends Expr, DotNet::Call, @cil_call_any {
|
||||
}
|
||||
|
||||
/** A tail call. */
|
||||
deprecated class TailCall extends Call {
|
||||
class TailCall extends Call {
|
||||
TailCall() { this.isTailCall() }
|
||||
|
||||
override predicate canFlowNext() { none() }
|
||||
}
|
||||
|
||||
/** A call to a static target. */
|
||||
deprecated class StaticCall extends Call {
|
||||
class StaticCall extends Call {
|
||||
StaticCall() { not this.isVirtual() }
|
||||
}
|
||||
|
||||
/** A call to a virtual target. */
|
||||
deprecated class VirtualCall extends Call {
|
||||
class VirtualCall extends Call {
|
||||
VirtualCall() { this.isVirtual() }
|
||||
}
|
||||
|
||||
/** A read of an array element. */
|
||||
deprecated class ReadArrayElement extends BinaryExpr, @cil_read_array {
|
||||
class ReadArrayElement extends BinaryExpr, @cil_read_array {
|
||||
/** Gets the array being read. */
|
||||
Expr getArray() { result = this.getOperand(1) }
|
||||
|
||||
@@ -224,14 +224,14 @@ deprecated class ReadArrayElement extends BinaryExpr, @cil_read_array {
|
||||
}
|
||||
|
||||
/** A write of an array element. */
|
||||
deprecated class WriteArrayElement extends Instruction, @cil_write_array {
|
||||
class WriteArrayElement extends Instruction, @cil_write_array {
|
||||
override int getPushCount() { result = 0 }
|
||||
|
||||
override int getPopCount() { result = 3 }
|
||||
}
|
||||
|
||||
/** A `return` statement. */
|
||||
deprecated class Return extends Instruction, @cil_ret {
|
||||
class Return extends Instruction, @cil_ret {
|
||||
/** Gets the expression being returned, if any. */
|
||||
Expr getExpr() { result = this.getOperand(0) }
|
||||
|
||||
@@ -239,7 +239,7 @@ deprecated class Return extends Instruction, @cil_ret {
|
||||
}
|
||||
|
||||
/** A `throw` statement. */
|
||||
deprecated class Throw extends Instruction, DotNet::Throw, @cil_throw_any {
|
||||
class Throw extends Instruction, DotNet::Throw, @cil_throw_any {
|
||||
override Expr getExpr() { result = this.getOperand(0) }
|
||||
|
||||
/** Gets the type of the exception being thrown. */
|
||||
@@ -249,7 +249,7 @@ deprecated class Throw extends Instruction, DotNet::Throw, @cil_throw_any {
|
||||
}
|
||||
|
||||
/** Stores a value at an address/location. */
|
||||
deprecated class StoreIndirect extends Instruction, @cil_stind {
|
||||
class StoreIndirect extends Instruction, @cil_stind {
|
||||
override int getPopCount() { result = 2 }
|
||||
|
||||
/** Gets the location to store the value at. */
|
||||
@@ -260,4 +260,4 @@ deprecated class StoreIndirect extends Instruction, @cil_stind {
|
||||
}
|
||||
|
||||
/** Loads a value from an address/location. */
|
||||
deprecated class LoadIndirect extends UnaryExpr, @cil_ldind { }
|
||||
class LoadIndirect extends UnaryExpr, @cil_ldind { }
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
private import CIL
|
||||
private import semmle.code.dotnet.Variable as DotNet
|
||||
|
||||
deprecated module Opcodes {
|
||||
module Opcodes {
|
||||
/** An `ldc.i4.m1` instruction. */
|
||||
class Ldc_i4_m1 extends IntLiteral, @cil_ldc_i4_m1 {
|
||||
override string getOpcodeName() { result = "ldc.i4.m1" }
|
||||
|
||||
@@ -12,7 +12,7 @@ private import dotnet
|
||||
/**
|
||||
* An implementation of a method in an assembly.
|
||||
*/
|
||||
deprecated class MethodImplementation extends EntryPoint, @cil_method_implementation {
|
||||
class MethodImplementation extends EntryPoint, @cil_method_implementation {
|
||||
/** Gets the method of this implementation. */
|
||||
Method getMethod() { cil_method_implementation(this, result, _) }
|
||||
|
||||
@@ -66,7 +66,7 @@ deprecated class MethodImplementation extends EntryPoint, @cil_method_implementa
|
||||
* A method, which corresponds to any callable in C#, including constructors,
|
||||
* destructors, operators, accessors and so on.
|
||||
*/
|
||||
deprecated class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowNode,
|
||||
class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowNode,
|
||||
CustomModifierReceiver, Parameterizable, @cil_method
|
||||
{
|
||||
/**
|
||||
@@ -191,27 +191,27 @@ deprecated class Method extends DotNet::Callable, Element, Member, TypeContainer
|
||||
}
|
||||
|
||||
/** A destructor/finalizer. */
|
||||
deprecated class Destructor extends Method, DotNet::Destructor {
|
||||
class Destructor extends Method, DotNet::Destructor {
|
||||
Destructor() { this.isFinalizer() }
|
||||
}
|
||||
|
||||
/** A constructor. */
|
||||
deprecated class Constructor extends Method, DotNet::Constructor {
|
||||
class Constructor extends Method, DotNet::Constructor {
|
||||
Constructor() { this.isConstructor() }
|
||||
}
|
||||
|
||||
/** A static/class constructor. */
|
||||
deprecated class StaticConstructor extends Constructor {
|
||||
class StaticConstructor extends Constructor {
|
||||
StaticConstructor() { this.isStaticConstructor() }
|
||||
}
|
||||
|
||||
/** An instance constructor. */
|
||||
deprecated class InstanceConstructor extends Constructor {
|
||||
class InstanceConstructor extends Constructor {
|
||||
InstanceConstructor() { this.isInstanceConstructor() }
|
||||
}
|
||||
|
||||
/** A method that always returns the `this` parameter. */
|
||||
deprecated class ChainingMethod extends Method {
|
||||
class ChainingMethod extends Method {
|
||||
ChainingMethod() {
|
||||
forex(Return ret | ret = this.getImplementation().getAnInstruction() |
|
||||
ret.getExpr() instanceof ThisAccess
|
||||
@@ -220,13 +220,13 @@ deprecated class ChainingMethod extends Method {
|
||||
}
|
||||
|
||||
/** An accessor. */
|
||||
abstract deprecated class Accessor extends Method {
|
||||
abstract class Accessor extends Method {
|
||||
/** Gets the property declaring this accessor. */
|
||||
abstract Property getProperty();
|
||||
}
|
||||
|
||||
/** A getter. */
|
||||
deprecated class Getter extends Accessor {
|
||||
class Getter extends Accessor {
|
||||
Getter() { cil_getter(_, this) }
|
||||
|
||||
override Property getProperty() { cil_getter(result, this) }
|
||||
@@ -236,7 +236,7 @@ deprecated class Getter extends Accessor {
|
||||
* A method that does nothing but retrieve a field.
|
||||
* Note that this is not necessarily a property getter.
|
||||
*/
|
||||
deprecated class TrivialGetter extends Method {
|
||||
class TrivialGetter extends Method {
|
||||
TrivialGetter() {
|
||||
exists(MethodImplementation impl | impl = this.getAnImplementation() |
|
||||
impl.getInstruction(0) instanceof ThisAccess and
|
||||
@@ -252,7 +252,7 @@ deprecated class TrivialGetter extends Method {
|
||||
}
|
||||
|
||||
/** A setter. */
|
||||
deprecated class Setter extends Accessor {
|
||||
class Setter extends Accessor {
|
||||
Setter() { cil_setter(_, this) }
|
||||
|
||||
override Property getProperty() { cil_setter(result, this) }
|
||||
@@ -269,7 +269,7 @@ deprecated class Setter extends Accessor {
|
||||
* A method that does nothing but set a field.
|
||||
* This is not necessarily a property setter.
|
||||
*/
|
||||
deprecated class TrivialSetter extends Method {
|
||||
class TrivialSetter extends Method {
|
||||
TrivialSetter() {
|
||||
exists(MethodImplementation impl | impl = this.getAnImplementation() |
|
||||
impl.getInstruction(0) instanceof ThisAccess and
|
||||
@@ -285,10 +285,10 @@ deprecated class TrivialSetter extends Method {
|
||||
}
|
||||
|
||||
/** An alias for `Method` for compatibility with the C# data model. */
|
||||
deprecated class Callable = Method;
|
||||
class Callable = Method;
|
||||
|
||||
/** An operator. */
|
||||
deprecated class Operator extends Method {
|
||||
class Operator extends Method {
|
||||
Operator() { this.isOperator() }
|
||||
|
||||
/** Gets the name of the implementing method (for compatibility with C# data model). */
|
||||
|
||||
@@ -8,7 +8,7 @@ private import dotnet
|
||||
/**
|
||||
* A parameterizable entity, such as `FunctionPointerType` or `Method`.
|
||||
*/
|
||||
deprecated class Parameterizable extends DotNet::Parameterizable, Element, @cil_parameterizable {
|
||||
class Parameterizable extends DotNet::Parameterizable, Element, @cil_parameterizable {
|
||||
override Parameter getRawParameter(int n) { cil_parameter(result, this, n, _) }
|
||||
|
||||
override Parameter getParameter(int n) { cil_parameter(result, this, n, _) }
|
||||
|
||||
@@ -7,7 +7,7 @@ private import CIL
|
||||
/**
|
||||
* Provides classes for working with static single assignment (SSA) form.
|
||||
*/
|
||||
deprecated module Ssa {
|
||||
module Ssa {
|
||||
private import internal.SsaImpl as SsaImpl
|
||||
|
||||
/** An SSA definition. */
|
||||
|
||||
@@ -8,7 +8,7 @@ import CIL
|
||||
* The average number of instructions per method,
|
||||
* below which an assembly is probably a stub.
|
||||
*/
|
||||
deprecated private float stubInstructionThreshold() { result = 5.1 }
|
||||
private float stubInstructionThreshold() { result = 5.1 }
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
@@ -18,7 +18,7 @@ private module Cached {
|
||||
* Look at the average number of instructions per method.
|
||||
*/
|
||||
cached
|
||||
deprecated predicate assemblyIsStubImpl(Assembly asm) {
|
||||
predicate assemblyIsStubImpl(Assembly asm) {
|
||||
exists(int totalInstructions, int totalImplementations |
|
||||
totalInstructions = count(Instruction i | i.getImplementation().getLocation() = asm) and
|
||||
totalImplementations =
|
||||
@@ -28,7 +28,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
deprecated predicate bestImplementation(MethodImplementation mi) {
|
||||
predicate bestImplementation(MethodImplementation mi) {
|
||||
exists(Assembly asm |
|
||||
asm = mi.getLocation() and
|
||||
(assemblyIsStubImpl(asm) implies asm.getFile().extractedQlTest()) and
|
||||
@@ -45,13 +45,13 @@ private module Cached {
|
||||
|
||||
private import Cached
|
||||
|
||||
deprecated predicate assemblyIsStub = assemblyIsStubImpl/1;
|
||||
predicate assemblyIsStub = assemblyIsStubImpl/1;
|
||||
|
||||
/**
|
||||
* A method implementation that is the "best" one for a particular method,
|
||||
* if there are several potential implementations to choose between, and
|
||||
* excludes implementations that are probably from stub/reference assemblies.
|
||||
*/
|
||||
deprecated class BestImplementation extends MethodImplementation {
|
||||
class BestImplementation extends MethodImplementation {
|
||||
BestImplementation() { bestImplementation(this) }
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ private import semmle.code.csharp.commons.QualifiedName
|
||||
*
|
||||
* Either a type (`Type`), a method(`Method`), or a namespace (`Namespace`).
|
||||
*/
|
||||
deprecated class TypeContainer extends DotNet::NamedElement, @cil_type_container {
|
||||
class TypeContainer extends DotNet::NamedElement, @cil_type_container {
|
||||
/** Gets the parent of this type container, if any. */
|
||||
TypeContainer getParent() { none() }
|
||||
|
||||
@@ -19,7 +19,7 @@ deprecated class TypeContainer extends DotNet::NamedElement, @cil_type_container
|
||||
}
|
||||
|
||||
/** A namespace. */
|
||||
deprecated class Namespace extends DotNet::Namespace, TypeContainer, @namespace {
|
||||
class Namespace extends DotNet::Namespace, TypeContainer, @namespace {
|
||||
override string toString() { result = this.getFullName() }
|
||||
|
||||
override Namespace getParent() { result = this.getParentNamespace() }
|
||||
@@ -32,7 +32,7 @@ deprecated class Namespace extends DotNet::Namespace, TypeContainer, @namespace
|
||||
/**
|
||||
* A type.
|
||||
*/
|
||||
deprecated class Type extends DotNet::Type, Declaration, TypeContainer, @cil_type {
|
||||
class Type extends DotNet::Type, Declaration, TypeContainer, @cil_type {
|
||||
override TypeContainer getParent() { cil_type(this, _, _, result, _) }
|
||||
|
||||
override string getName() { cil_type(this, result, _, _, _) }
|
||||
|
||||
@@ -6,7 +6,7 @@ private import CIL
|
||||
private import dotnet
|
||||
|
||||
/** A type parameter. */
|
||||
deprecated class TypeParameter extends DotNet::TypeParameter, Type, @cil_typeparameter {
|
||||
class TypeParameter extends DotNet::TypeParameter, Type, @cil_typeparameter {
|
||||
override int getIndex() { cil_type_parameter(_, result, this) }
|
||||
|
||||
/** Gets the generic type/method declaring this type parameter. */
|
||||
@@ -33,7 +33,7 @@ deprecated class TypeParameter extends DotNet::TypeParameter, Type, @cil_typepar
|
||||
}
|
||||
|
||||
/** A value or reference type. */
|
||||
deprecated class ValueOrRefType extends DotNet::ValueOrRefType, Type, @cil_valueorreftype {
|
||||
class ValueOrRefType extends DotNet::ValueOrRefType, Type, @cil_valueorreftype {
|
||||
override ValueOrRefType getDeclaringType() { result = this.getParent() }
|
||||
|
||||
override string getUndecoratedName() { cil_type(this, result, _, _, _) }
|
||||
@@ -44,7 +44,7 @@ deprecated class ValueOrRefType extends DotNet::ValueOrRefType, Type, @cil_value
|
||||
}
|
||||
|
||||
/** An `enum`. */
|
||||
deprecated class Enum extends ValueOrRefType {
|
||||
class Enum extends ValueOrRefType {
|
||||
Enum() { this.isEnum() }
|
||||
|
||||
override IntegralType getUnderlyingType() {
|
||||
@@ -56,17 +56,17 @@ deprecated class Enum extends ValueOrRefType {
|
||||
}
|
||||
|
||||
/** A `class`. */
|
||||
deprecated class Class extends ValueOrRefType {
|
||||
class Class extends ValueOrRefType {
|
||||
Class() { this.isClass() }
|
||||
}
|
||||
|
||||
/** An `interface`. */
|
||||
deprecated class Interface extends ValueOrRefType {
|
||||
class Interface extends ValueOrRefType {
|
||||
Interface() { this.isInterface() }
|
||||
}
|
||||
|
||||
/** An array. */
|
||||
deprecated class ArrayType extends DotNet::ArrayType, Type, @cil_array_type {
|
||||
class ArrayType extends DotNet::ArrayType, Type, @cil_array_type {
|
||||
override Type getElementType() { cil_array_type(this, result, _) }
|
||||
|
||||
/** Gets the rank of this array. */
|
||||
@@ -80,7 +80,7 @@ deprecated class ArrayType extends DotNet::ArrayType, Type, @cil_array_type {
|
||||
}
|
||||
|
||||
/** A pointer type. */
|
||||
deprecated class PointerType extends DotNet::PointerType, PrimitiveType, @cil_pointer_type {
|
||||
class PointerType extends DotNet::PointerType, PrimitiveType, @cil_pointer_type {
|
||||
override Type getReferentType() { cil_pointer_type(this, result) }
|
||||
|
||||
override IntType getUnderlyingType() { any() }
|
||||
@@ -95,31 +95,31 @@ deprecated class PointerType extends DotNet::PointerType, PrimitiveType, @cil_po
|
||||
}
|
||||
|
||||
/** A primitive type, built into the runtime. */
|
||||
abstract deprecated class PrimitiveType extends Type { }
|
||||
abstract class PrimitiveType extends Type { }
|
||||
|
||||
/**
|
||||
* A primitive numeric type.
|
||||
* Either an integral type (`IntegralType`) or a floating point type (`FloatingPointType`).
|
||||
*/
|
||||
abstract deprecated class NumericType extends PrimitiveType, ValueOrRefType { }
|
||||
abstract class NumericType extends PrimitiveType, ValueOrRefType { }
|
||||
|
||||
/** A floating point type. Either single precision (`FloatType`) or double precision (`DoubleType`). */
|
||||
abstract deprecated class FloatingPointType extends NumericType { }
|
||||
abstract class FloatingPointType extends NumericType { }
|
||||
|
||||
/**
|
||||
* An integral numeric type. Either a signed integral type (`SignedIntegralType`)
|
||||
* or an unsigned integral type (`UnsignedIntegralType`).
|
||||
*/
|
||||
abstract deprecated class IntegralType extends NumericType { }
|
||||
abstract class IntegralType extends NumericType { }
|
||||
|
||||
/** A signed integral type. */
|
||||
abstract deprecated class SignedIntegralType extends IntegralType { }
|
||||
abstract class SignedIntegralType extends IntegralType { }
|
||||
|
||||
/** An unsigned integral type. */
|
||||
abstract deprecated class UnsignedIntegralType extends IntegralType { }
|
||||
abstract class UnsignedIntegralType extends IntegralType { }
|
||||
|
||||
/** The `void` type, `System.Void`. */
|
||||
deprecated class VoidType extends PrimitiveType {
|
||||
class VoidType extends PrimitiveType {
|
||||
VoidType() { this.isSystemType("Void") }
|
||||
|
||||
override string toString() { result = "void" }
|
||||
@@ -128,7 +128,7 @@ deprecated class VoidType extends PrimitiveType {
|
||||
}
|
||||
|
||||
/** The type `System.Int32`. */
|
||||
deprecated class IntType extends SignedIntegralType {
|
||||
class IntType extends SignedIntegralType {
|
||||
IntType() { this.isSystemType("Int32") }
|
||||
|
||||
override string toStringWithTypes() { result = "int" }
|
||||
@@ -139,21 +139,21 @@ deprecated class IntType extends SignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.IntPtr`. */
|
||||
deprecated class IntPtrType extends PrimitiveType {
|
||||
class IntPtrType extends PrimitiveType {
|
||||
IntPtrType() { this.isSystemType("IntPtr") }
|
||||
|
||||
override IntType getUnderlyingType() { any() }
|
||||
}
|
||||
|
||||
/** The type `System.UIntPtr`. */
|
||||
deprecated class UIntPtrType extends PrimitiveType {
|
||||
class UIntPtrType extends PrimitiveType {
|
||||
UIntPtrType() { this.isSystemType("UIntPtr") }
|
||||
|
||||
override IntType getUnderlyingType() { any() }
|
||||
}
|
||||
|
||||
/** The type `System.UInt32`. */
|
||||
deprecated class UIntType extends UnsignedIntegralType {
|
||||
class UIntType extends UnsignedIntegralType {
|
||||
UIntType() { this.isSystemType("UInt32") }
|
||||
|
||||
override string toStringWithTypes() { result = "uint" }
|
||||
@@ -164,7 +164,7 @@ deprecated class UIntType extends UnsignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.SByte`. */
|
||||
deprecated class SByteType extends SignedIntegralType {
|
||||
class SByteType extends SignedIntegralType {
|
||||
SByteType() { this.isSystemType("SByte") }
|
||||
|
||||
override string toStringWithTypes() { result = "sbyte" }
|
||||
@@ -173,7 +173,7 @@ deprecated class SByteType extends SignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.Byte`. */
|
||||
deprecated class ByteType extends UnsignedIntegralType {
|
||||
class ByteType extends UnsignedIntegralType {
|
||||
ByteType() { this.isSystemType("Byte") }
|
||||
|
||||
override string toStringWithTypes() { result = "byte" }
|
||||
@@ -184,7 +184,7 @@ deprecated class ByteType extends UnsignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.Int16`. */
|
||||
deprecated class ShortType extends SignedIntegralType {
|
||||
class ShortType extends SignedIntegralType {
|
||||
ShortType() { this.isSystemType("Int16") }
|
||||
|
||||
override string toStringWithTypes() { result = "short" }
|
||||
@@ -193,7 +193,7 @@ deprecated class ShortType extends SignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.UInt16`. */
|
||||
deprecated class UShortType extends UnsignedIntegralType {
|
||||
class UShortType extends UnsignedIntegralType {
|
||||
UShortType() { this.isSystemType("UInt16") }
|
||||
|
||||
override string toStringWithTypes() { result = "ushort" }
|
||||
@@ -204,7 +204,7 @@ deprecated class UShortType extends UnsignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.Int64`. */
|
||||
deprecated class LongType extends SignedIntegralType {
|
||||
class LongType extends SignedIntegralType {
|
||||
LongType() { this.isSystemType("Int64") }
|
||||
|
||||
override string toStringWithTypes() { result = "long" }
|
||||
@@ -213,7 +213,7 @@ deprecated class LongType extends SignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.UInt64`. */
|
||||
deprecated class ULongType extends UnsignedIntegralType {
|
||||
class ULongType extends UnsignedIntegralType {
|
||||
ULongType() { this.isSystemType("UInt64") }
|
||||
|
||||
override string toStringWithTypes() { result = "ulong" }
|
||||
@@ -224,7 +224,7 @@ deprecated class ULongType extends UnsignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.Decimal`. */
|
||||
deprecated class DecimalType extends SignedIntegralType {
|
||||
class DecimalType extends SignedIntegralType {
|
||||
DecimalType() { this.isSystemType("Decimal") }
|
||||
|
||||
override string toStringWithTypes() { result = "decimal" }
|
||||
@@ -233,21 +233,21 @@ deprecated class DecimalType extends SignedIntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.String`. */
|
||||
deprecated class StringType extends PrimitiveType, ValueOrRefType {
|
||||
class StringType extends PrimitiveType, ValueOrRefType {
|
||||
StringType() { this.isSystemType("String") }
|
||||
|
||||
override string toStringWithTypes() { result = "string" }
|
||||
}
|
||||
|
||||
/** The type `System.Object`. */
|
||||
deprecated class ObjectType extends ValueOrRefType {
|
||||
class ObjectType extends ValueOrRefType {
|
||||
ObjectType() { this.isSystemType("Object") }
|
||||
|
||||
override string toStringWithTypes() { result = "object" }
|
||||
}
|
||||
|
||||
/** The type `System.Boolean`. */
|
||||
deprecated class BoolType extends PrimitiveType, ValueOrRefType {
|
||||
class BoolType extends PrimitiveType, ValueOrRefType {
|
||||
BoolType() { this.isSystemType("Boolean") }
|
||||
|
||||
override string toStringWithTypes() { result = "bool" }
|
||||
@@ -256,7 +256,7 @@ deprecated class BoolType extends PrimitiveType, ValueOrRefType {
|
||||
}
|
||||
|
||||
/** The type `System.Double`. */
|
||||
deprecated class DoubleType extends FloatingPointType {
|
||||
class DoubleType extends FloatingPointType {
|
||||
DoubleType() { this.isSystemType("Double") }
|
||||
|
||||
override string toStringWithTypes() { result = "double" }
|
||||
@@ -265,7 +265,7 @@ deprecated class DoubleType extends FloatingPointType {
|
||||
}
|
||||
|
||||
/** The type `System.Single`. */
|
||||
deprecated class FloatType extends FloatingPointType {
|
||||
class FloatType extends FloatingPointType {
|
||||
FloatType() { this.isSystemType("Single") }
|
||||
|
||||
override string toStringWithTypes() { result = "float" }
|
||||
@@ -274,7 +274,7 @@ deprecated class FloatType extends FloatingPointType {
|
||||
}
|
||||
|
||||
/** The type `System.Char`. */
|
||||
deprecated class CharType extends IntegralType {
|
||||
class CharType extends IntegralType {
|
||||
CharType() { this.isSystemType("Char") }
|
||||
|
||||
override string toStringWithTypes() { result = "char" }
|
||||
@@ -285,7 +285,7 @@ deprecated class CharType extends IntegralType {
|
||||
}
|
||||
|
||||
/** The type `System.Type`. */
|
||||
deprecated class SystemType extends ValueOrRefType {
|
||||
class SystemType extends ValueOrRefType {
|
||||
SystemType() { this.isSystemType("Type") }
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ deprecated class SystemType extends ValueOrRefType {
|
||||
* delegate*<int, void>
|
||||
* ```
|
||||
*/
|
||||
deprecated class FunctionPointerType extends Type, CustomModifierReceiver, Parameterizable,
|
||||
class FunctionPointerType extends Type, CustomModifierReceiver, Parameterizable,
|
||||
@cil_function_pointer_type
|
||||
{
|
||||
/** Gets the return type of this function pointer. */
|
||||
|
||||
@@ -6,7 +6,7 @@ private import CIL
|
||||
private import dotnet
|
||||
|
||||
/** A variable. Either a stack variable (`StackVariable`) or a field (`Field`). */
|
||||
deprecated class Variable extends DotNet::Variable, Declaration, DataFlowNode, @cil_variable {
|
||||
class Variable extends DotNet::Variable, Declaration, DataFlowNode, @cil_variable {
|
||||
/** Gets the type of this variable. */
|
||||
override Type getType() { none() }
|
||||
|
||||
@@ -28,7 +28,7 @@ deprecated class Variable extends DotNet::Variable, Declaration, DataFlowNode, @
|
||||
}
|
||||
|
||||
/** A stack variable. Either a local variable (`LocalVariable`) or a parameter (`Parameter`). */
|
||||
deprecated class StackVariable extends Variable, @cil_stack_variable {
|
||||
class StackVariable extends Variable, @cil_stack_variable {
|
||||
deprecated override predicate hasQualifiedName(string qualifier, string name) { none() }
|
||||
|
||||
override predicate hasFullyQualifiedName(string qualifier, string name) { none() }
|
||||
@@ -39,7 +39,7 @@ deprecated class StackVariable extends Variable, @cil_stack_variable {
|
||||
*
|
||||
* Each method in CIL has a number of typed local variables, in addition to the evaluation stack.
|
||||
*/
|
||||
deprecated class LocalVariable extends StackVariable, @cil_local_variable {
|
||||
class LocalVariable extends StackVariable, @cil_local_variable {
|
||||
override string toString() {
|
||||
result =
|
||||
"Local variable " + this.getIndex() + " of method " +
|
||||
@@ -60,7 +60,7 @@ deprecated class LocalVariable extends StackVariable, @cil_local_variable {
|
||||
}
|
||||
|
||||
/** A parameter of a `Method` or `FunctionPointerType`. */
|
||||
deprecated class Parameter extends DotNet::Parameter, CustomModifierReceiver, @cil_parameter {
|
||||
class Parameter extends DotNet::Parameter, CustomModifierReceiver, @cil_parameter {
|
||||
override Parameterizable getDeclaringElement() { cil_parameter(this, result, _, _) }
|
||||
|
||||
/** Gets the index of this parameter. */
|
||||
@@ -107,7 +107,7 @@ deprecated class Parameter extends DotNet::Parameter, CustomModifierReceiver, @c
|
||||
}
|
||||
|
||||
/** A method parameter. */
|
||||
deprecated class MethodParameter extends Parameter, StackVariable {
|
||||
class MethodParameter extends Parameter, StackVariable {
|
||||
/** Gets the method declaring this parameter. */
|
||||
override Method getMethod() { this = result.getARawParameter() }
|
||||
|
||||
@@ -132,7 +132,7 @@ deprecated class MethodParameter extends Parameter, StackVariable {
|
||||
}
|
||||
|
||||
/** A parameter corresponding to `this`. */
|
||||
deprecated class ThisParameter extends MethodParameter {
|
||||
class ThisParameter extends MethodParameter {
|
||||
ThisParameter() {
|
||||
not this.getMethod().isStatic() and
|
||||
this.getIndex() = 0
|
||||
@@ -140,7 +140,7 @@ deprecated class ThisParameter extends MethodParameter {
|
||||
}
|
||||
|
||||
/** A field. */
|
||||
deprecated class Field extends DotNet::Field, Variable, Member, CustomModifierReceiver, @cil_field {
|
||||
class Field extends DotNet::Field, Variable, Member, CustomModifierReceiver, @cil_field {
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
override string toStringWithTypes() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
private import cil
|
||||
private import codeql.ssa.Ssa as SsaImplCommon
|
||||
|
||||
deprecated private module SsaInput implements SsaImplCommon::InputSig<CIL::Location> {
|
||||
private module SsaInput implements SsaImplCommon::InputSig<CIL::Location> {
|
||||
class BasicBlock = CIL::BasicBlock;
|
||||
|
||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() }
|
||||
@@ -29,17 +29,17 @@ deprecated private module SsaInput implements SsaImplCommon::InputSig<CIL::Locat
|
||||
}
|
||||
}
|
||||
|
||||
deprecated import SsaImplCommon::Make<CIL::Location, SsaInput>
|
||||
import SsaImplCommon::Make<CIL::Location, SsaInput>
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
private import CIL
|
||||
|
||||
cached
|
||||
deprecated predicate forceCachingInSameStage() { any() }
|
||||
predicate forceCachingInSameStage() { any() }
|
||||
|
||||
cached
|
||||
deprecated ReadAccess getARead(Definition def) {
|
||||
ReadAccess getARead(Definition def) {
|
||||
exists(BasicBlock bb, int i |
|
||||
ssaDefReachesRead(_, def, bb, i) and
|
||||
result = bb.getNode(i)
|
||||
@@ -47,7 +47,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
deprecated ReadAccess getAFirstReadExt(DefinitionExt def) {
|
||||
ReadAccess getAFirstReadExt(DefinitionExt def) {
|
||||
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
|
||||
def.definesAt(_, bb1, i1, _) and
|
||||
adjacentDefReadExt(def, _, bb1, i1, bb2, i2) and
|
||||
@@ -56,7 +56,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
deprecated predicate hasAdjacentReadsExt(DefinitionExt def, ReadAccess first, ReadAccess second) {
|
||||
predicate hasAdjacentReadsExt(DefinitionExt def, ReadAccess first, ReadAccess second) {
|
||||
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
|
||||
first = bb1.getNode(i1) and
|
||||
adjacentDefReadExt(def, _, bb1, i1, bb2, i2) and
|
||||
@@ -65,12 +65,10 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
deprecated Definition getAPhiInput(PhiNode phi) { phiHasInputFromBlock(phi, result, _) }
|
||||
Definition getAPhiInput(PhiNode phi) { phiHasInputFromBlock(phi, result, _) }
|
||||
|
||||
cached
|
||||
deprecated predicate lastRefBeforeRedefExt(
|
||||
DefinitionExt def, BasicBlock bb, int i, DefinitionExt next
|
||||
) {
|
||||
predicate lastRefBeforeRedefExt(DefinitionExt def, BasicBlock bb, int i, DefinitionExt next) {
|
||||
lastRefRedefExt(def, _, bb, i, next)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import Stmt
|
||||
import Type
|
||||
import exprs.Call
|
||||
private import commons.QualifiedName
|
||||
private import dotnet
|
||||
private import semmle.code.csharp.ExprOrStmtParent
|
||||
private import semmle.code.csharp.metrics.Complexity
|
||||
private import TypeRef
|
||||
@@ -20,73 +21,8 @@ private import TypeRef
|
||||
* an anonymous function (`AnonymousFunctionExpr`), or a local function
|
||||
* (`LocalFunction`).
|
||||
*/
|
||||
class Callable extends Parameterizable, ExprOrStmtParent, @callable {
|
||||
pragma[noinline]
|
||||
deprecated private string getDeclaringTypeLabel() { result = this.getDeclaringType().getLabel() }
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private string getParameterTypeLabelNonGeneric(int p) {
|
||||
not this instanceof Generic and
|
||||
result = this.getParameter(p).getType().getLabel()
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
pragma[nomagic]
|
||||
deprecated private string getMethodParamListNonGeneric() {
|
||||
result =
|
||||
concat(int p |
|
||||
p in [0 .. this.getNumberOfParameters() - 1]
|
||||
|
|
||||
this.getParameterTypeLabelNonGeneric(p), "," order by p
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private string getParameterTypeLabelGeneric(int p) {
|
||||
this instanceof Generic and
|
||||
result = this.getParameter(p).getType().getLabel()
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
pragma[nomagic]
|
||||
deprecated private string getMethodParamListGeneric() {
|
||||
result =
|
||||
concat(int p |
|
||||
p in [0 .. this.getNumberOfParameters() - 1]
|
||||
|
|
||||
this.getParameterTypeLabelGeneric(p), "," order by p
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private string getLabelNonGeneric() {
|
||||
not this instanceof Generic and
|
||||
result =
|
||||
this.getReturnTypeLabel() + " " + this.getDeclaringTypeLabel() + "." +
|
||||
this.getUndecoratedName() + "(" + this.getMethodParamListNonGeneric() + ")"
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private string getLabelGeneric() {
|
||||
result =
|
||||
this.getReturnTypeLabel() + " " + this.getDeclaringTypeLabel() + "." +
|
||||
this.getUndecoratedName() + getGenericsLabel(this) + "(" + this.getMethodParamListGeneric() +
|
||||
")"
|
||||
}
|
||||
|
||||
deprecated final override string getLabel() {
|
||||
result = this.getLabelNonGeneric() or
|
||||
result = this.getLabelGeneric()
|
||||
}
|
||||
|
||||
deprecated private string getReturnTypeLabel() {
|
||||
result = this.getReturnType().getLabel()
|
||||
or
|
||||
not exists(this.getReturnType()) and result = "System.Void"
|
||||
}
|
||||
|
||||
/** Gets the return type of this callable. */
|
||||
Type getReturnType() { none() }
|
||||
class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @callable {
|
||||
override Type getReturnType() { none() }
|
||||
|
||||
/** Gets the annotated return type of this callable. */
|
||||
final AnnotatedType getAnnotatedReturnType() { result.appliesTo(this) }
|
||||
@@ -129,8 +65,7 @@ class Callable extends Parameterizable, ExprOrStmtParent, @callable {
|
||||
result = this.getExpressionBody()
|
||||
}
|
||||
|
||||
/** Holds if this callable has a body or an implementation. */
|
||||
predicate hasBody() { exists(this.getBody()) }
|
||||
override predicate hasBody() { exists(this.getBody()) }
|
||||
|
||||
/**
|
||||
* Holds if this callable has a non-empty body. That is, either it has
|
||||
@@ -261,8 +196,7 @@ class Callable extends Parameterizable, ExprOrStmtParent, @callable {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if this callable can return expression `e`. */
|
||||
predicate canReturn(Expr e) {
|
||||
override predicate canReturn(DotNet::Expr e) {
|
||||
exists(ReturnStmt ret | ret.getEnclosingCallable() = this | e = ret.getExpr())
|
||||
or
|
||||
e = this.getExpressionBody() and
|
||||
@@ -284,6 +218,8 @@ class Callable extends Parameterizable, ExprOrStmtParent, @callable {
|
||||
|
||||
/** Gets a `Call` that has this callable as a target. */
|
||||
Call getACall() { this = result.getTarget() }
|
||||
|
||||
override Parameter getAParameter() { result = Parameterizable.super.getAParameter() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -389,7 +325,7 @@ class ExtensionMethod extends Method {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class Constructor extends Callable, Member, Attributable, @constructor {
|
||||
class Constructor extends DotNet::Constructor, Callable, Member, Attributable, @constructor {
|
||||
override string getName() { constructors(this, result, _, _) }
|
||||
|
||||
override Type getReturnType() {
|
||||
@@ -499,7 +435,7 @@ class PrimaryConstructor extends Constructor {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class Destructor extends Callable, Member, Attributable, @destructor {
|
||||
class Destructor extends DotNet::Destructor, Callable, Member, Attributable, @destructor {
|
||||
override string getName() { destructors(this, result, _, _) }
|
||||
|
||||
override Type getReturnType() {
|
||||
@@ -561,33 +497,10 @@ class Operator extends Callable, Member, Attributable, Overridable, @operator {
|
||||
override Parameter getRawParameter(int i) { result = this.getParameter(i) }
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ValueOrRefType getARecordBaseType(ValueOrRefType t) {
|
||||
exists(Callable c |
|
||||
c.hasName("<Clone>$") and
|
||||
c.getNumberOfParameters() = 0 and
|
||||
t = c.getDeclaringType() and
|
||||
result = t
|
||||
)
|
||||
or
|
||||
result = getARecordBaseType(t).getABaseType()
|
||||
}
|
||||
|
||||
/** A clone method on a record. */
|
||||
class RecordCloneMethod extends Method {
|
||||
RecordCloneMethod() {
|
||||
this.hasName("<Clone>$") and
|
||||
this.getNumberOfParameters() = 0 and
|
||||
this.getReturnType() = getARecordBaseType(this.getDeclaringType()) and
|
||||
this.isPublic() and
|
||||
not this.isStatic()
|
||||
}
|
||||
|
||||
/** Gets the constructor that this clone method calls. */
|
||||
Constructor getConstructor() {
|
||||
result.getDeclaringType() = this.getDeclaringType() and
|
||||
result.getNumberOfParameters() = 1 and
|
||||
result.getParameter(0).getType() = this.getDeclaringType()
|
||||
class RecordCloneMethod extends Method, DotNet::RecordCloneCallable {
|
||||
override Constructor getConstructor() {
|
||||
result = DotNet::RecordCloneCallable.super.getConstructor()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import Location
|
||||
private import semmle.code.csharp.ExprOrStmtParent
|
||||
private import dotnet
|
||||
private import commons.QualifiedName
|
||||
|
||||
/**
|
||||
@@ -13,64 +14,18 @@ private import commons.QualifiedName
|
||||
* (`NamespaceDeclaration`), a `using` directive (`UsingDirective`), or type
|
||||
* parameter constraints (`TypeParameterConstraints`).
|
||||
*/
|
||||
class Element extends @element {
|
||||
/** Gets a textual representation of this element. */
|
||||
cached
|
||||
string toString() { none() }
|
||||
|
||||
/** Gets the file containing this element. */
|
||||
final File getFile() { result = this.getLocation().getFile() }
|
||||
|
||||
/** Holds if this element is from source code. */
|
||||
predicate fromSource() { this.getFile().fromSource() }
|
||||
|
||||
/** Holds if this element is from an assembly. */
|
||||
predicate fromLibrary() { this.getFile().fromLibrary() }
|
||||
|
||||
/**
|
||||
* Gets the "language" of this program element, as defined by the extension of the filename.
|
||||
* For example, C# has language "cs", and Visual Basic has language "vb".
|
||||
*/
|
||||
deprecated final string getLanguage() { result = this.getLocation().getFile().getExtension() }
|
||||
|
||||
/**
|
||||
* Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs.
|
||||
*
|
||||
* If no primary class can be determined, the result is `"???"`.
|
||||
*/
|
||||
final string getPrimaryQlClasses() {
|
||||
result = strictconcat(this.getAPrimaryQlClass(), ",")
|
||||
or
|
||||
not exists(this.getAPrimaryQlClass()) and
|
||||
result = "???"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of a primary CodeQL class to which this element belongs.
|
||||
*
|
||||
* For most elements, this is simply the most precise syntactic category to
|
||||
* which they belong; for example, `AddExpr` is a primary class, but
|
||||
* `BinaryOperation` is not.
|
||||
*
|
||||
* If no primary classes match, this predicate has no result. If multiple
|
||||
* primary classes match, this predicate can have multiple results.
|
||||
*
|
||||
* See also `getPrimaryQlClasses`, which is better to use in most cases.
|
||||
*/
|
||||
string getAPrimaryQlClass() { none() }
|
||||
|
||||
/** Gets the full textual representation of this element, including type information. */
|
||||
string toStringWithTypes() { result = this.toString() }
|
||||
class Element extends DotNet::Element, @element {
|
||||
override string toStringWithTypes() { result = this.toString() }
|
||||
|
||||
/**
|
||||
* Gets the location of this element. Where an element has locations in
|
||||
* source and assemblies, choose the source location. If there are multiple
|
||||
* assembly locations, choose only one.
|
||||
*/
|
||||
final Location getLocation() { result = bestLocation(this) }
|
||||
final override Location getLocation() { result = bestLocation(this) }
|
||||
|
||||
/** Gets a location of this element, including sources and assemblies. */
|
||||
Location getALocation() { none() }
|
||||
override Location getALocation() { none() }
|
||||
|
||||
/** Gets the parent of this element, if any. */
|
||||
Element getParent() { result.getAChild() = this }
|
||||
@@ -91,96 +46,3 @@ class Element extends @element {
|
||||
*/
|
||||
int getIndex() { exists(Element parent | parent.getChild(result) = this) }
|
||||
}
|
||||
|
||||
/** An element that has a name. */
|
||||
class NamedElement extends Element, @named_element {
|
||||
/** Gets the name of this element. */
|
||||
cached
|
||||
string getName() { none() }
|
||||
|
||||
/** Holds if this element has name 'name'. */
|
||||
final predicate hasName(string name) { name = this.getName() }
|
||||
|
||||
/**
|
||||
* Gets the fully qualified name of this element, for example the
|
||||
* fully qualified name of `M` on line 3 is `N.C.M` in
|
||||
*
|
||||
* ```csharp
|
||||
* namespace N {
|
||||
* class C {
|
||||
* void M(int i, string s) { }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
cached
|
||||
deprecated final string getQualifiedName() {
|
||||
exists(string qualifier, string name | this.hasQualifiedName(qualifier, name) |
|
||||
if qualifier = "" then result = name else result = qualifier + "." + name
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fully qualified name of this element, for example the
|
||||
* fully qualified name of `M` on line 3 is `N.C.M` in
|
||||
*
|
||||
* ```csharp
|
||||
* namespace N {
|
||||
* class C {
|
||||
* void M(int i, string s) { }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Unbound generic types, such as `IList<T>`, are represented as
|
||||
* ``System.Collections.Generic.IList`1``.
|
||||
*/
|
||||
cached
|
||||
final string getFullyQualifiedName() {
|
||||
exists(string qualifier, string name | this.hasFullyQualifiedName(qualifier, name) |
|
||||
if qualifier = "" then result = name else result = qualifier + "." + name
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `hasFullyQualifiedName` instead.
|
||||
*
|
||||
* Holds if this element has the qualified name `qualifier`.`name`.
|
||||
*/
|
||||
cached
|
||||
deprecated predicate hasQualifiedName(string qualifier, string name) {
|
||||
qualifier = "" and name = this.getName()
|
||||
}
|
||||
|
||||
/** Holds if this element has the fully qualified name `qualifier`.`name`. */
|
||||
cached
|
||||
predicate hasFullyQualifiedName(string qualifier, string name) {
|
||||
qualifier = "" and name = this.getName()
|
||||
}
|
||||
|
||||
/** Gets a unique string label for this element. */
|
||||
cached
|
||||
deprecated string getLabel() { none() }
|
||||
|
||||
/** Holds if `other` has the same metadata handle in the same assembly. */
|
||||
deprecated predicate matchesHandle(NamedElement other) {
|
||||
exists(Assembly asm, int handle |
|
||||
metadata_handle(this, asm, handle) and
|
||||
metadata_handle(other, asm, handle)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this element was compiled from source code that is also present in the
|
||||
* database. That is, this element corresponds to another element from source.
|
||||
*/
|
||||
deprecated predicate compiledFromSource() {
|
||||
not this.fromSource() and
|
||||
exists(NamedElement other | other != this |
|
||||
this.matchesHandle(other) and
|
||||
other.fromSource()
|
||||
)
|
||||
}
|
||||
|
||||
override string toString() { result = this.getName() }
|
||||
}
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
import Location
|
||||
import Namespace
|
||||
private import commons.QualifiedName
|
||||
private import dotnet
|
||||
private import TypeRef
|
||||
|
||||
/**
|
||||
* A generic declaration. Either an unbound generic (`UnboundGeneric`) or a
|
||||
* constructed generic (`ConstructedGeneric`).
|
||||
*/
|
||||
class Generic extends Declaration, @generic {
|
||||
class Generic extends DotNet::Generic, Declaration, @generic {
|
||||
Generic() {
|
||||
type_parameters(_, _, this, _) or
|
||||
type_arguments(_, _, this) or
|
||||
@@ -36,23 +37,16 @@ class Generic extends Declaration, @generic {
|
||||
* Either an unbound generic type (`UnboundGenericType`) or an unbound generic method
|
||||
* (`UnboundGenericMethod`).
|
||||
*/
|
||||
class UnboundGeneric extends Generic {
|
||||
class UnboundGeneric extends DotNet::UnboundGeneric, Generic {
|
||||
UnboundGeneric() { type_parameters(_, _, this, _) }
|
||||
|
||||
/** Gets the `i`th type parameter, if any. */
|
||||
final TypeParameter getTypeParameter(int n) { type_parameters(result, n, this, _) }
|
||||
final override TypeParameter getTypeParameter(int n) { type_parameters(result, n, this, _) }
|
||||
|
||||
/** Gets a type parameter. */
|
||||
TypeParameter getATypeParameter() { result = this.getTypeParameter(_) }
|
||||
override ConstructedGeneric getAConstructedGeneric() { result.getUnboundGeneric() = this }
|
||||
|
||||
/**
|
||||
* Gets one of the constructed versions of this declaration,
|
||||
* which has been bound to a specific set of types.
|
||||
*/
|
||||
ConstructedGeneric getAConstructedGeneric() { result.getUnboundGeneric() = this }
|
||||
|
||||
/** Gets the total number of type parameters. */
|
||||
int getNumberOfTypeParameters() { result = count(int i | exists(this.getTypeParameter(i))) }
|
||||
override TypeParameter getATypeParameter() {
|
||||
result = DotNet::UnboundGeneric.super.getATypeParameter()
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets the type parameters as a comma-separated string. */
|
||||
@@ -73,61 +67,25 @@ private string getTypeParameterBacktick(UnboundGeneric ug) {
|
||||
* Either a constructed generic type (`ConstructedType`) or a constructed
|
||||
* generic method (`ConstructedMethod`).
|
||||
*/
|
||||
class ConstructedGeneric extends Generic {
|
||||
class ConstructedGeneric extends DotNet::ConstructedGeneric, Generic {
|
||||
ConstructedGeneric() {
|
||||
type_arguments(_, _, this)
|
||||
or
|
||||
nullable_underlying_type(this, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unbound generic declaration from which this declaration was
|
||||
* constructed.
|
||||
*/
|
||||
UnboundGeneric getUnboundGeneric() { constructed_generic(this, result) }
|
||||
override UnboundGeneric getUnboundGeneric() { constructed_generic(this, result) }
|
||||
|
||||
override UnboundGeneric getUnboundDeclaration() {
|
||||
result = this.getUnboundGeneric().getUnboundDeclaration()
|
||||
}
|
||||
|
||||
/** Gets the `i`th type argument, if any. */
|
||||
Type getTypeArgument(int i) { none() }
|
||||
override Type getTypeArgument(int i) { none() }
|
||||
|
||||
/** Gets a type argument. */
|
||||
Type getATypeArgument() { result = this.getTypeArgument(_) }
|
||||
override Type getATypeArgument() { result = this.getTypeArgument(_) }
|
||||
|
||||
/** Gets the annotated type of type argument `i`. */
|
||||
final AnnotatedType getAnnotatedTypeArgument(int i) { result.appliesToTypeArgument(this, i) }
|
||||
|
||||
/** Gets the total number of type arguments. */
|
||||
final int getNumberOfTypeArguments() { result = count(int i | exists(this.getTypeArgument(i))) }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Constructs the label suffix for a generic method or type.
|
||||
*/
|
||||
deprecated string getGenericsLabel(Generic g) {
|
||||
result = "`" + g.(UnboundGeneric).getNumberOfTypeParameters()
|
||||
or
|
||||
result = "<" + typeArgs(g) + ">"
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private string getTypeArgumentLabel(ConstructedGeneric generic, int p) {
|
||||
result = generic.getTypeArgument(p).getLabel()
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
pragma[nomagic]
|
||||
deprecated private string typeArgs(ConstructedGeneric generic) {
|
||||
result =
|
||||
concat(int p |
|
||||
p in [0 .. generic.getNumberOfTypeArguments() - 1]
|
||||
|
|
||||
getTypeArgumentLabel(generic, p), ","
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the type arguments as a comma-separated string. */
|
||||
@@ -202,10 +160,7 @@ class UnboundGenericType extends ValueOrRefType, UnboundGeneric {
|
||||
/**
|
||||
* A type parameter, for example `T` in `List<T>`.
|
||||
*/
|
||||
class TypeParameter extends Type, @type_parameter {
|
||||
/** Gets the generic type or method declaring this type parameter. */
|
||||
UnboundGeneric getDeclaringGeneric() { this = result.getATypeParameter() }
|
||||
|
||||
class TypeParameter extends DotNet::TypeParameter, Type, @type_parameter {
|
||||
/** Gets the constraints on this type parameter, if any. */
|
||||
TypeParameterConstraints getConstraints() { result.getTypeParameter() = this }
|
||||
|
||||
@@ -261,13 +216,8 @@ class TypeParameter extends Type, @type_parameter {
|
||||
result = this.getASuppliedType().(TypeParameter).getAnUltimatelySuppliedType()
|
||||
}
|
||||
|
||||
/** Gets the index of this type parameter. For example the index of `U` in `Func<T,U>` is 1. */
|
||||
override int getIndex() { type_parameters(this, result, _, _) }
|
||||
|
||||
deprecated final override string getLabel() { result = "!" + this.getIndex() }
|
||||
|
||||
override string getUndecoratedName() { result = "!" + this.getIndex() }
|
||||
|
||||
/** Gets the generic that defines this type parameter. */
|
||||
UnboundGeneric getGeneric() { type_parameters(this, _, result, _) }
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import Callable
|
||||
import Element
|
||||
import Modifier
|
||||
import Variable
|
||||
private import dotnet
|
||||
private import Implements
|
||||
private import TypeRef
|
||||
private import commons.QualifiedName
|
||||
@@ -25,46 +26,8 @@ private module FullyQualifiedNameInput implements QualifiedNameInputSig {
|
||||
*
|
||||
* Either a modifiable (`Modifiable`) or an assignable (`Assignable`).
|
||||
*/
|
||||
class Declaration extends NamedElement, @declaration {
|
||||
/** Gets the name of this declaration, without additional decoration such as `<...>`. */
|
||||
string getUndecoratedName() { none() }
|
||||
|
||||
/** Holds if this element has undecorated name 'name'. */
|
||||
final predicate hasUndecoratedName(string name) { name = this.getUndecoratedName() }
|
||||
|
||||
/**
|
||||
* Gets the unbound version of this declaration, that is, the declaration where
|
||||
* all type arguments have been removed. For example, in
|
||||
*
|
||||
* ```csharp
|
||||
* class C<T>
|
||||
* {
|
||||
* class Nested
|
||||
* {
|
||||
* }
|
||||
*
|
||||
* void Method<S>() { }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* we have the following
|
||||
*
|
||||
* | Declaration | Unbound declaration |
|
||||
* |-------------------------|---------------------|
|
||||
* | `C<int>` | ``C`1`` |
|
||||
* | ``C`1.Nested`` | ``C`1.Nested`` |
|
||||
* | `C<int>.Nested` | ``C`1.Nested`` |
|
||||
* | ``C`1.Method`1`` | ``C`1.Method`1`` |
|
||||
* | ``C<int>.Method`1`` | ``C`1.Method`1`` |
|
||||
* | `C<int>.Method<string>` | ``C`1.Method`1`` |
|
||||
*/
|
||||
Declaration getUnboundDeclaration() { result = this }
|
||||
|
||||
/** Holds if this declaration is unbound. */
|
||||
final predicate isUnboundDeclaration() { this.getUnboundDeclaration() = this }
|
||||
|
||||
/** Gets the type containing this declaration, if any. */
|
||||
ValueOrRefType getDeclaringType() { none() }
|
||||
class Declaration extends DotNet::Declaration, Element, @declaration {
|
||||
override ValueOrRefType getDeclaringType() { none() }
|
||||
|
||||
/** Holds if this declaration is unconstructed and in source code. */
|
||||
final predicate isSourceDeclaration() { this.fromSource() and this.isUnboundDeclaration() }
|
||||
@@ -259,27 +222,33 @@ class Modifiable extends Declaration, @modifiable {
|
||||
}
|
||||
|
||||
/** A declaration that is a member of a type. */
|
||||
class Member extends Modifiable, @member {
|
||||
class Member extends DotNet::Member, Modifiable, @member {
|
||||
/** Gets an access to this member. */
|
||||
MemberAccess getAnAccess() { result.getTarget() = this }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `hasFullyQualifiedName` instead.
|
||||
*
|
||||
* Holds if this member has name `name` and is defined in type `type`
|
||||
* with namespace `namespace`.
|
||||
*/
|
||||
cached
|
||||
deprecated final predicate hasQualifiedName(string namespace, string type, string name) {
|
||||
override predicate isPublic() { Modifiable.super.isPublic() }
|
||||
|
||||
override predicate isProtected() { Modifiable.super.isProtected() }
|
||||
|
||||
override predicate isPrivate() { Modifiable.super.isPrivate() }
|
||||
|
||||
override predicate isInternal() { Modifiable.super.isInternal() }
|
||||
|
||||
override predicate isSealed() { Modifiable.super.isSealed() }
|
||||
|
||||
override predicate isAbstract() { Modifiable.super.isAbstract() }
|
||||
|
||||
override predicate isStatic() { Modifiable.super.isStatic() }
|
||||
|
||||
override predicate isRequired() { Modifiable.super.isRequired() }
|
||||
|
||||
override predicate isFile() { Modifiable.super.isFile() }
|
||||
|
||||
deprecated final override predicate hasQualifiedName(string namespace, string type, string name) {
|
||||
QualifiedName<QualifiedNameInput>::hasQualifiedName(this, namespace, type, name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this member has name `name` and is defined in type `type`
|
||||
* with namespace `namespace`.
|
||||
*/
|
||||
cached
|
||||
final predicate hasFullyQualifiedName(string namespace, string type, string name) {
|
||||
final override predicate hasFullyQualifiedName(string namespace, string type, string name) {
|
||||
QualifiedName<FullyQualifiedNameInput>::hasQualifiedName(this, namespace, type, name)
|
||||
}
|
||||
}
|
||||
@@ -508,24 +477,10 @@ class Virtualizable extends Overridable, Member, @virtualizable {
|
||||
* A parameterizable declaration. Either a callable (`Callable`), a delegate
|
||||
* type (`DelegateType`), or an indexer (`Indexer`).
|
||||
*/
|
||||
class Parameterizable extends Declaration, @parameterizable {
|
||||
/** Gets raw parameter `i`, including the `this` parameter at index 0. */
|
||||
Parameter getRawParameter(int i) { params(result, _, _, i, _, this, _) }
|
||||
class Parameterizable extends DotNet::Parameterizable, Declaration, @parameterizable {
|
||||
override Parameter getRawParameter(int i) { params(result, _, _, i, _, this, _) }
|
||||
|
||||
/** Gets the `i`th parameter, excluding the `this` parameter. */
|
||||
Parameter getParameter(int i) { params(result, _, _, i, _, this, _) }
|
||||
|
||||
/** Gets the number of parameters of this callable. */
|
||||
int getNumberOfParameters() { result = count(this.getAParameter()) }
|
||||
|
||||
/** Holds if this declaration has no parameters. */
|
||||
predicate hasNoParameters() { not exists(this.getAParameter()) }
|
||||
|
||||
/** Gets a parameter, if any. */
|
||||
Parameter getAParameter() { result = this.getParameter(_) }
|
||||
|
||||
/** Gets a raw parameter (including the qualifier), if any. */
|
||||
final Parameter getARawParameter() { result = this.getRawParameter(_) }
|
||||
override Parameter getParameter(int i) { params(result, _, _, i, _, this, _) }
|
||||
|
||||
/**
|
||||
* Gets the type of the parameter, possibly prefixed
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/** Provides classes for namespaces. */
|
||||
|
||||
private import semmle.code.csharp.commons.QualifiedName
|
||||
import Element
|
||||
import Type
|
||||
private import dotnet
|
||||
|
||||
/**
|
||||
* A type container. Either a namespace (`Namespace`) or a type (`Type`).
|
||||
@@ -18,44 +18,24 @@ class TypeContainer extends Declaration, @type_container { }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class Namespace extends TypeContainer, Declaration, @namespace {
|
||||
class Namespace extends DotNet::Namespace, TypeContainer, Declaration, @namespace {
|
||||
override Namespace getParent() { result = this.getParentNamespace() }
|
||||
|
||||
/**
|
||||
* Gets the parent namespace, if any. For example the parent namespace of `System.IO`
|
||||
* is `System`. The parent namespace of `System` is the global namespace.
|
||||
*/
|
||||
Namespace getParentNamespace() { parent_namespace(this, result) }
|
||||
override Namespace getParentNamespace() { parent_namespace(this, result) }
|
||||
|
||||
/**
|
||||
* Gets a child namespace, if any. For example `System.IO` is a child in
|
||||
* the namespace `System`.
|
||||
*/
|
||||
Namespace getAChildNamespace() { parent_namespace(result, this) }
|
||||
override Namespace getAChildNamespace() { parent_namespace(result, this) }
|
||||
|
||||
override TypeContainer getChild(int i) {
|
||||
i = 0 and
|
||||
parent_namespace(result, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this namespace has the qualified name `qualifier`.`name`.
|
||||
*
|
||||
* For example if the qualified name is `System.Collections.Generic`, then
|
||||
* `qualifier`=`System.Collections` and `name`=`Generic`.
|
||||
*/
|
||||
deprecated override predicate hasQualifiedName(string qualifier, string name) {
|
||||
namespaceHasQualifiedName(this, qualifier, name)
|
||||
DotNet::Namespace.super.hasQualifiedName(qualifier, name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this namespace has the qualified name `qualifier`.`name`.
|
||||
*
|
||||
* For example if the qualified name is `System.Collections.Generic`, then
|
||||
* `qualifier`=`System.Collections` and `name`=`Generic`.
|
||||
*/
|
||||
override predicate hasFullyQualifiedName(string qualifier, string name) {
|
||||
namespaceHasQualifiedName(this, qualifier, name)
|
||||
DotNet::Namespace.super.hasFullyQualifiedName(qualifier, name)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,28 +123,7 @@ class Namespace extends TypeContainer, Declaration, @namespace {
|
||||
|
||||
override Location getALocation() { result = this.getADeclaration().getALocation() }
|
||||
|
||||
/** Gets a textual representation of this namespace. */
|
||||
override string toString() { result = this.getFullName() }
|
||||
|
||||
/** Holds if this is the global namespace. */
|
||||
final predicate isGlobalNamespace() { this.getName() = "" }
|
||||
|
||||
/** Gets the simple name of this namespace, for example `IO` in `System.IO`. */
|
||||
final override string getName() { namespaces(this, result) }
|
||||
|
||||
final override string getUndecoratedName() { namespaces(this, result) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "Namespace" }
|
||||
|
||||
/**
|
||||
* Get the fully qualified name of this namespace.
|
||||
*/
|
||||
string getFullName() {
|
||||
exists(string namespace, string name |
|
||||
namespaceHasQualifiedName(this, namespace, name) and
|
||||
result = getQualifiedName(namespace, name)
|
||||
)
|
||||
}
|
||||
override string toString() { result = DotNet::Namespace.super.toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
import Member
|
||||
import Stmt
|
||||
import Type
|
||||
private import cil
|
||||
private import dotnet
|
||||
private import semmle.code.csharp.ExprOrStmtParent
|
||||
private import TypeRef
|
||||
|
||||
@@ -111,7 +113,7 @@ class DeclarationWithGetSetAccessors extends DeclarationWithAccessors, TopLevelE
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class Property extends DeclarationWithGetSetAccessors, @property {
|
||||
class Property extends DotNet::Property, DeclarationWithGetSetAccessors, @property {
|
||||
override string getName() { properties(this, result, _, _, _) }
|
||||
|
||||
override string getUndecoratedName() { properties(this, result, _, _, _) }
|
||||
@@ -556,6 +558,8 @@ class TrivialProperty extends Property {
|
||||
this.isAutoImplemented()
|
||||
or
|
||||
this.getGetter().trivialGetterField() = this.getSetter().trivialSetterField()
|
||||
or
|
||||
exists(CIL::TrivialProperty prop | this.matchesHandle(prop))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import Location
|
||||
import Namespace
|
||||
import Property
|
||||
private import Conversion
|
||||
private import dotnet
|
||||
private import semmle.code.csharp.metrics.Coupling
|
||||
private import TypeRef
|
||||
private import semmle.code.csharp.frameworks.System
|
||||
@@ -19,10 +20,7 @@ private import semmle.code.csharp.frameworks.system.runtime.CompilerServices
|
||||
* a pointer type (`PointerType`), the arglist type (`ArglistType`), an unknown
|
||||
* type (`UnknownType`), or a type parameter (`TypeParameter`).
|
||||
*/
|
||||
class Type extends Member, TypeContainer, @type {
|
||||
/** Gets the name of this type without additional syntax such as `[]` or `*`. */
|
||||
override string getUndecoratedName() { none() }
|
||||
|
||||
class Type extends DotNet::Type, Member, TypeContainer, @type {
|
||||
override string getName() { types(this, _, result) }
|
||||
|
||||
override Type getUnboundDeclaration() { result = this }
|
||||
@@ -58,7 +56,7 @@ private predicate isObjectClass(Class c) { c instanceof ObjectType }
|
||||
*
|
||||
* Either a value type (`ValueType`) or a reference type (`RefType`).
|
||||
*/
|
||||
class ValueOrRefType extends Type, Attributable, @value_or_ref_type {
|
||||
class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_or_ref_type {
|
||||
/** Gets the namespace containing this type. */
|
||||
Namespace getNamespace() {
|
||||
if exists(this.getDeclaringType())
|
||||
@@ -66,8 +64,7 @@ class ValueOrRefType extends Type, Attributable, @value_or_ref_type {
|
||||
else result.getATypeDeclaration() = this
|
||||
}
|
||||
|
||||
/** Gets the namespace declaring this type, if any. */
|
||||
Namespace getDeclaringNamespace() { this = result.getATypeDeclaration() }
|
||||
override Namespace getDeclaringNamespace() { this = result.getATypeDeclaration() }
|
||||
|
||||
override ValueOrRefType getDeclaringType() { none() }
|
||||
|
||||
@@ -76,30 +73,6 @@ class ValueOrRefType extends Type, Attributable, @value_or_ref_type {
|
||||
/** Gets a nested child type, if any. */
|
||||
NestedType getAChildType() { nested_types(result, this, _) }
|
||||
|
||||
deprecated private string getPrefixWithTypes() {
|
||||
result = this.getDeclaringType().getLabel() + "."
|
||||
or
|
||||
if this.getDeclaringNamespace().isGlobalNamespace()
|
||||
then result = ""
|
||||
else result = this.getDeclaringNamespace().getFullName() + "."
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private string getLabelNonGeneric() {
|
||||
not this instanceof Generic and
|
||||
result = this.getPrefixWithTypes() + this.getUndecoratedName()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private string getLabelGeneric() {
|
||||
result = this.getPrefixWithTypes() + this.getUndecoratedName() + getGenericsLabel(this)
|
||||
}
|
||||
|
||||
deprecated override string getLabel() {
|
||||
result = this.getLabelNonGeneric() or
|
||||
result = this.getLabelGeneric()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source namespace declaration in which this type is declared, if any.
|
||||
* This only holds for non-nested types.
|
||||
@@ -147,7 +120,7 @@ class ValueOrRefType extends Type, Attributable, @value_or_ref_type {
|
||||
}
|
||||
|
||||
/** Gets an immediate base type of this type, if any. */
|
||||
ValueOrRefType getABaseType() {
|
||||
override ValueOrRefType getABaseType() {
|
||||
result = this.getBaseClass() or
|
||||
result = this.getABaseInterface()
|
||||
}
|
||||
@@ -387,8 +360,7 @@ class ValueOrRefType extends Type, Attributable, @value_or_ref_type {
|
||||
nested_types(this, _, result)
|
||||
}
|
||||
|
||||
/** Holds if this type is a `record`. */
|
||||
predicate isRecord() { this.hasModifier("record") }
|
||||
override predicate isRecord() { this.hasModifier("record") }
|
||||
|
||||
override string toString() { result = Type.super.toString() }
|
||||
}
|
||||
@@ -997,7 +969,7 @@ class FunctionPointerType extends Type, Parameterizable, @function_pointer_type
|
||||
|
||||
override string getAPrimaryQlClass() { result = "FunctionPointerType" }
|
||||
|
||||
deprecated override string getLabel() { result = this.getName() }
|
||||
override string getLabel() { result = this.getName() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1092,7 +1064,7 @@ class InlineArrayType extends ValueType, @inline_array_type {
|
||||
/**
|
||||
* An array type, for example `int[]`.
|
||||
*/
|
||||
class ArrayType extends RefType, @array_type {
|
||||
class ArrayType extends DotNet::ArrayType, RefType, @array_type {
|
||||
/**
|
||||
* Gets the dimension of this array type. For example `int[][]` is of
|
||||
* dimension 2, while `int[]` is of dimension 1.
|
||||
@@ -1109,15 +1081,13 @@ class ArrayType extends RefType, @array_type {
|
||||
predicate isMultiDimensional() { this.getRank() > 1 }
|
||||
|
||||
/** Gets the element type of this array, for example `int` in `int[]`. */
|
||||
Type getElementType() {
|
||||
override Type getElementType() {
|
||||
array_element_type(this, _, _, result)
|
||||
or
|
||||
not array_element_type(this, _, _, any(Type t)) and
|
||||
array_element_type(this, _, _, getTypeRef(result))
|
||||
}
|
||||
|
||||
deprecated final override string getLabel() { result = this.getElementType().getLabel() + "[]" }
|
||||
|
||||
/** Holds if this array type has the same shape (dimension and rank) as `that` array type. */
|
||||
predicate hasSameShapeAs(ArrayType that) {
|
||||
this.getDimension() = that.getDimension() and
|
||||
@@ -1158,36 +1128,33 @@ class ArrayType extends RefType, @array_type {
|
||||
not type_location(this, _) and
|
||||
result = this.getElementType().getALocation()
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "ArrayType" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A pointer type, for example `char*`.
|
||||
*/
|
||||
class PointerType extends Type, @pointer_type {
|
||||
/** Gets the type referred by this pointer type, for example `char` in `char*`. */
|
||||
Type getReferentType() {
|
||||
class PointerType extends DotNet::PointerType, Type, @pointer_type {
|
||||
override Type getReferentType() {
|
||||
pointer_referent_type(this, result)
|
||||
or
|
||||
not pointer_referent_type(this, any(Type t)) and
|
||||
pointer_referent_type(this, getTypeRef(result))
|
||||
}
|
||||
|
||||
override string toStringWithTypes() { result = this.getReferentType().toStringWithTypes() + "*" }
|
||||
override string toStringWithTypes() { result = DotNet::PointerType.super.toStringWithTypes() }
|
||||
|
||||
override Type getChild(int n) { result = this.getReferentType() and n = 0 }
|
||||
|
||||
final override string getName() { types(this, _, result) }
|
||||
|
||||
deprecated final override string getLabel() { result = this.getReferentType().getLabel() + "*" }
|
||||
|
||||
final override string getUndecoratedName() {
|
||||
result = this.getReferentType().getUndecoratedName()
|
||||
}
|
||||
|
||||
override Location getALocation() { result = this.getReferentType().getALocation() }
|
||||
|
||||
override string toString() { result = DotNet::PointerType.super.toString() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "PointerType" }
|
||||
}
|
||||
|
||||
@@ -1271,7 +1238,7 @@ class TupleType extends ValueType, @tuple_type {
|
||||
")"
|
||||
}
|
||||
|
||||
deprecated override string getLabel() { result = this.getUnderlyingType().getLabel() }
|
||||
override string getLabel() { result = this.getUnderlyingType().getLabel() }
|
||||
|
||||
override Type getChild(int i) { result = this.getUnderlyingType().getChild(i) }
|
||||
|
||||
|
||||
@@ -7,18 +7,18 @@ import Assignable
|
||||
import Callable
|
||||
import Element
|
||||
import Type
|
||||
private import dotnet
|
||||
private import semmle.code.csharp.ExprOrStmtParent
|
||||
private import TypeRef
|
||||
|
||||
/**
|
||||
* A variable. Either a variable with local scope (`LocalScopeVariable`) or a field (`Field`).
|
||||
*/
|
||||
class Variable extends Assignable, @variable {
|
||||
class Variable extends Assignable, DotNet::Variable, @variable {
|
||||
override Variable getUnboundDeclaration() { result = this }
|
||||
|
||||
override VariableAccess getAnAccess() { result.getTarget() = this }
|
||||
|
||||
/** Gets the type of this variable. */
|
||||
override Type getType() { none() }
|
||||
|
||||
/** Gets the expression used to initialise this variable, if any. */
|
||||
@@ -87,10 +87,9 @@ class LocalScopeVariable extends Variable, @local_scope_variable {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class Parameter extends LocalScopeVariable, Attributable, TopLevelExprParent, @parameter {
|
||||
/** Gets the raw position of this parameter, including the `this` parameter at index 0. */
|
||||
final int getRawPosition() { this = this.getDeclaringElement().getRawParameter(result) }
|
||||
|
||||
class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, TopLevelExprParent,
|
||||
@parameter
|
||||
{
|
||||
/**
|
||||
* Gets the position of this parameter. For example, the position of `x` is
|
||||
* 0 and the position of `y` is 1 in
|
||||
@@ -101,7 +100,7 @@ class Parameter extends LocalScopeVariable, Attributable, TopLevelExprParent, @p
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
int getPosition() { params(this, _, _, result, _, _, _) }
|
||||
override int getPosition() { params(this, _, _, result, _, _, _) }
|
||||
|
||||
override int getIndex() { result = this.getPosition() }
|
||||
|
||||
@@ -139,7 +138,7 @@ class Parameter extends LocalScopeVariable, Attributable, TopLevelExprParent, @p
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
predicate isOut() { params(this, _, _, _, 2, _, _) }
|
||||
override predicate isOut() { params(this, _, _, _, 2, _, _) }
|
||||
|
||||
/**
|
||||
* Holds if this parameter is a value type that is passed in by reference.
|
||||
@@ -194,7 +193,7 @@ class Parameter extends LocalScopeVariable, Attributable, TopLevelExprParent, @p
|
||||
predicate hasExtensionMethodModifier() { params(this, _, _, _, 4, _, _) }
|
||||
|
||||
/** Gets the declaring element of this parameter. */
|
||||
Parameterizable getDeclaringElement() { params(this, _, _, _, _, result, _) }
|
||||
override Parameterizable getDeclaringElement() { params(this, _, _, _, _, result, _) }
|
||||
|
||||
override Parameter getUnboundDeclaration() { params(this, _, _, _, _, _, result) }
|
||||
|
||||
@@ -397,7 +396,9 @@ class LocalConstant extends LocalVariable, @local_constant {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class Field extends Variable, AssignableMember, Attributable, TopLevelExprParent, @field {
|
||||
class Field extends Variable, AssignableMember, Attributable, TopLevelExprParent, DotNet::Field,
|
||||
@field
|
||||
{
|
||||
/**
|
||||
* Gets the initial value of this field, if any. For example, the initial
|
||||
* value of `F` on line 2 is `20` in
|
||||
|
||||
@@ -3,13 +3,56 @@
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import cil
|
||||
private import dotnet
|
||||
|
||||
private predicate isDisposeMethod(Callable method) {
|
||||
private predicate isDisposeMethod(DotNet::Callable method) {
|
||||
method.getName() = "Dispose" and
|
||||
method.getNumberOfParameters() = 0
|
||||
}
|
||||
|
||||
private predicate cilVariableReadFlowsToNode(CIL::Variable variable, DataFlow::Node n) {
|
||||
n.asExpr() = variable.getARead()
|
||||
or
|
||||
exists(DataFlow::Node mid |
|
||||
cilVariableReadFlowsToNode(variable, mid) and
|
||||
DataFlow::localFlowStep(mid, n)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate cilVariableReadFlowsTo(CIL::Variable variable, CIL::DataFlowNode n) {
|
||||
cilVariableReadFlowsToNode(variable, DataFlow::exprNode(n))
|
||||
}
|
||||
|
||||
private predicate disposedCilVariable(CIL::Variable variable) {
|
||||
// `variable` is the `this` parameter on a dispose method.
|
||||
isDisposeMethod(variable.(CIL::ThisParameter).getMethod())
|
||||
or
|
||||
// `variable` is passed to a method that disposes it.
|
||||
exists(CIL::Call call, CIL::Parameter param |
|
||||
cilVariableReadFlowsTo(variable, call.getArgumentForParameter(param)) and
|
||||
disposedCilVariable(param)
|
||||
)
|
||||
or
|
||||
// A parameter is disposed if its source declaration is disposed
|
||||
disposedCilVariable(variable.(CIL::Parameter).getUnboundDeclaration())
|
||||
or
|
||||
// A variable is disposed if it's assigned to another variable
|
||||
// that may be disposed.
|
||||
exists(CIL::WriteAccess write |
|
||||
cilVariableReadFlowsTo(variable, write.getExpr()) and
|
||||
disposedCilVariable(write.getTarget())
|
||||
)
|
||||
}
|
||||
|
||||
private predicate disposedCSharpVariable(Variable variable) {
|
||||
// A C# parameter is disposed if its corresponding CIL parameter is disposed
|
||||
exists(CIL::Method m, CIL::Parameter p, int i |
|
||||
disposedCilVariable(p) and p = m.getRawParameter(i)
|
||||
|
|
||||
variable = any(Callable c2 | c2.matchesHandle(m)).getRawParameter(i)
|
||||
)
|
||||
or
|
||||
// Call to a method that disposes it
|
||||
exists(Call call, int arg, VariableRead read |
|
||||
read.getTarget() = variable and
|
||||
@@ -40,4 +83,7 @@ private predicate disposedCSharpVariable(Variable variable) {
|
||||
* Hold if `variable` might be disposed.
|
||||
* This is a conservative overestimate.
|
||||
*/
|
||||
predicate mayBeDisposed(Variable variable) { disposedCSharpVariable(variable) }
|
||||
predicate mayBeDisposed(DotNet::Variable variable) {
|
||||
disposedCSharpVariable(variable) or
|
||||
disposedCilVariable(variable)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** Provides predicates for working with fully qualified names. */
|
||||
|
||||
private import csharp
|
||||
private import dotnet
|
||||
|
||||
/**
|
||||
* Holds if namespace `n` has the qualified name `qualifier`.`name`.
|
||||
@@ -8,8 +9,8 @@ private import csharp
|
||||
* For example if the qualified name is `System.Collections.Generic`, then
|
||||
* `qualifier`=`System.Collections` and `name`=`Generic`.
|
||||
*/
|
||||
predicate namespaceHasQualifiedName(Namespace n, string qualifier, string name) {
|
||||
if n instanceof GlobalNamespace
|
||||
predicate namespaceHasQualifiedName(DotNet::Namespace n, string qualifier, string name) {
|
||||
if n instanceof DotNet::GlobalNamespace
|
||||
then qualifier = "" and name = ""
|
||||
else (
|
||||
exists(string pqualifier, string pname |
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import cil
|
||||
private import dotnet
|
||||
private import ControlFlow::SuccessorTypes
|
||||
private import semmle.code.csharp.commons.Assertions
|
||||
private import semmle.code.csharp.commons.ComparisonTest
|
||||
@@ -842,6 +844,8 @@ class NullGuardedDataFlowNode extends GuardedDataFlowNode {
|
||||
|
||||
/** INTERNAL: Do not use. */
|
||||
module Internal {
|
||||
private import semmle.code.cil.CallableReturns
|
||||
|
||||
newtype TAbstractValue =
|
||||
TBooleanValue(boolean b) { b = true or b = false } or
|
||||
TIntegerValue(int i) { i = any(Expr e).getValue().toInt() } or
|
||||
@@ -852,11 +856,20 @@ module Internal {
|
||||
} or
|
||||
TEmptyCollectionValue(boolean b) { b = true or b = false }
|
||||
|
||||
/** A callable that always returns a `null` value. */
|
||||
private class NullCallable extends Callable {
|
||||
NullCallable() {
|
||||
exists(CIL::Method m | m.matchesHandle(this) | alwaysNullMethod(m) and not m.isVirtual())
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if expression `e` is a `null` value. */
|
||||
predicate nullValue(Expr e) {
|
||||
e instanceof NullLiteral
|
||||
or
|
||||
e instanceof DefaultValueExpr and e.getType().isRefType()
|
||||
or
|
||||
e.(Call).getTarget().getUnboundDeclaration() instanceof NullCallable
|
||||
}
|
||||
|
||||
/** Holds if expression `e2` is a `null` value whenever `e1` is. */
|
||||
@@ -877,7 +890,11 @@ module Internal {
|
||||
|
||||
/** A callable that always returns a non-`null` value. */
|
||||
private class NonNullCallable extends Callable {
|
||||
NonNullCallable() { this = any(SystemObjectClass c).getGetTypeMethod() }
|
||||
NonNullCallable() {
|
||||
exists(CIL::Method m | m.matchesHandle(this) | alwaysNotNullMethod(m) and not m.isVirtual())
|
||||
or
|
||||
this = any(SystemObjectClass c).getGetTypeMethod()
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if expression `e` is a non-`null` value. */
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import cil
|
||||
private import semmle.code.cil.CallableReturns
|
||||
private import semmle.code.csharp.ExprOrStmtParent
|
||||
private import semmle.code.csharp.commons.Assertions
|
||||
private import semmle.code.csharp.frameworks.System
|
||||
@@ -37,6 +39,15 @@ private class ThrowingCall extends NonReturningCall {
|
||||
or
|
||||
this.(FailingAssertion).getAssertionFailure().isException(c.getExceptionClass())
|
||||
or
|
||||
exists(Callable target, CIL::Method m, CIL::Type ex |
|
||||
target = this.getTarget() and
|
||||
not target.hasBody() and
|
||||
target.matchesHandle(m) and
|
||||
alwaysThrowsException(m, ex) and
|
||||
c.getExceptionClass().matchesHandle(ex) and
|
||||
not m.isVirtual()
|
||||
)
|
||||
or
|
||||
this =
|
||||
any(MethodCall mc |
|
||||
mc.getTarget()
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import cil
|
||||
private import semmle.code.csharp.dataflow.Nullness
|
||||
private import semmle.code.cil.CallableReturns as CR
|
||||
|
||||
private predicate finalCallable(Callable c) {
|
||||
not c.(Virtualizable).isVirtual() and
|
||||
@@ -13,11 +15,19 @@ private predicate finalCallable(Callable c) {
|
||||
/** Holds if callable `c` always returns null. */
|
||||
predicate alwaysNullCallable(Callable c) {
|
||||
finalCallable(c) and
|
||||
forex(Expr e | c.canReturn(e) | e instanceof AlwaysNullExpr)
|
||||
(
|
||||
exists(CIL::Method m | m.matchesHandle(c) | CR::alwaysNullMethod(m))
|
||||
or
|
||||
forex(Expr e | c.canReturn(e) | e instanceof AlwaysNullExpr)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if callable `c` always returns a non-null value. */
|
||||
predicate alwaysNotNullCallable(Callable c) {
|
||||
finalCallable(c) and
|
||||
forex(Expr e | c.canReturn(e) | e instanceof NonNullExpr)
|
||||
(
|
||||
exists(CIL::Method m | m.matchesHandle(c) | CR::alwaysNotNullMethod(m))
|
||||
or
|
||||
forex(Expr e | c.canReturn(e) | e instanceof NonNullExpr)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
private import csharp
|
||||
private import cil
|
||||
private import dotnet
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
private import DataFlowPublic
|
||||
private import DataFlowPrivate
|
||||
@@ -12,11 +14,30 @@ private import semmle.code.csharp.frameworks.system.collections.Generic
|
||||
/**
|
||||
* Gets a source declaration of callable `c` that has a body or has
|
||||
* a flow summary.
|
||||
*
|
||||
* If the callable has both CIL and source code, return only the source
|
||||
* code version.
|
||||
*/
|
||||
Callable getCallableForDataFlow(Callable c) {
|
||||
result = c.getUnboundDeclaration() and
|
||||
result.hasBody() and
|
||||
result.getFile().fromSource()
|
||||
DotNet::Callable getCallableForDataFlow(DotNet::Callable c) {
|
||||
exists(DotNet::Callable unboundDecl | unboundDecl = c.getUnboundDeclaration() |
|
||||
result.hasBody() and
|
||||
if unboundDecl.getFile().fromSource()
|
||||
then
|
||||
// C# callable with C# implementation in the database
|
||||
result = unboundDecl
|
||||
else
|
||||
if unboundDecl instanceof CIL::Callable
|
||||
then
|
||||
// CIL callable with C# implementation in the database
|
||||
unboundDecl.matchesHandle(result.(Callable))
|
||||
or
|
||||
// CIL callable without C# implementation in the database
|
||||
not unboundDecl.matchesHandle(any(Callable k | k.hasBody())) and
|
||||
result = unboundDecl
|
||||
else
|
||||
// C# callable without C# implementation in the database
|
||||
unboundDecl.matchesHandle(result.(CIL::Callable))
|
||||
)
|
||||
}
|
||||
|
||||
newtype TReturnKind =
|
||||
@@ -46,7 +67,7 @@ private module Cached {
|
||||
*/
|
||||
cached
|
||||
newtype TDataFlowCallable =
|
||||
TCallable(Callable c) { c.isUnboundDeclaration() } or
|
||||
TDotNetCallable(DotNet::Callable c) { c.isUnboundDeclaration() } or
|
||||
TSummarizedCallable(DataFlowSummarizedCallable sc) or
|
||||
TFieldOrPropertyCallable(FieldOrProperty f) or
|
||||
TCapturedVariableCallable(LocalScopeVariable v) { v.isCaptured() }
|
||||
@@ -60,6 +81,10 @@ private module Cached {
|
||||
TExplicitDelegateLikeCall(ControlFlow::Nodes::ElementNode cfn, DelegateLikeCall dc) {
|
||||
cfn.getAstNode() = dc
|
||||
} or
|
||||
TCilCall(CIL::Call call) {
|
||||
// No need to include calls that are compiled from source
|
||||
not call.getImplementation().getMethod().compiledFromSource()
|
||||
} or
|
||||
TSummaryCall(FlowSummary::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver) {
|
||||
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
|
||||
}
|
||||
@@ -172,7 +197,7 @@ class RefReturnKind extends OutRefReturnKind, TRefReturnKind {
|
||||
/** A callable used for data flow. */
|
||||
class DataFlowCallable extends TDataFlowCallable {
|
||||
/** Gets the underlying source code callable, if any. */
|
||||
Callable asCallable() { this = TCallable(result) }
|
||||
DotNet::Callable asCallable() { this = TDotNetCallable(result) }
|
||||
|
||||
/** Gets the underlying summarized callable, if any. */
|
||||
FlowSummary::SummarizedCallable asSummarizedCallable() { this = TSummarizedCallable(result) }
|
||||
@@ -183,7 +208,7 @@ class DataFlowCallable extends TDataFlowCallable {
|
||||
LocalScopeVariable asCapturedVariable() { this = TCapturedVariableCallable(result) }
|
||||
|
||||
/** Gets the underlying callable. */
|
||||
Callable getUnderlyingCallable() {
|
||||
DotNet::Callable getUnderlyingCallable() {
|
||||
result = this.asCallable() or result = this.asSummarizedCallable()
|
||||
}
|
||||
|
||||
@@ -210,7 +235,8 @@ class DataFlowCallable extends TDataFlowCallable {
|
||||
abstract class DataFlowCall extends TDataFlowCall {
|
||||
/**
|
||||
* Gets a run-time target of this call. A target is always a source
|
||||
* declaration.
|
||||
* declaration, and if the callable has both CIL and source code, only
|
||||
* the source code version is returned.
|
||||
*/
|
||||
abstract DataFlowCallable getARuntimeTarget();
|
||||
|
||||
@@ -224,7 +250,7 @@ abstract class DataFlowCall extends TDataFlowCall {
|
||||
abstract DataFlowCallable getEnclosingCallable();
|
||||
|
||||
/** Gets the underlying expression, if any. */
|
||||
final Expr getExpr() { result = this.getNode().asExpr() }
|
||||
final DotNet::Expr getExpr() { result = this.getNode().asExpr() }
|
||||
|
||||
/** Gets the argument at position `pos` of this call. */
|
||||
final ArgumentNode getArgument(ArgumentPosition pos) { result.argumentOf(this, pos) }
|
||||
@@ -322,6 +348,33 @@ class ExplicitDelegateLikeDataFlowCall extends DelegateDataFlowCall, TExplicitDe
|
||||
override Location getLocation() { result = cfn.getLocation() }
|
||||
}
|
||||
|
||||
/** A CIL call relevant for data flow. */
|
||||
class CilDataFlowCall extends DataFlowCall, TCilCall {
|
||||
private CIL::Call call;
|
||||
|
||||
CilDataFlowCall() { this = TCilCall(call) }
|
||||
|
||||
/** Gets the underlying CIL call. */
|
||||
CIL::Call getCilCall() { result = call }
|
||||
|
||||
override DataFlowCallable getARuntimeTarget() {
|
||||
// There is no dispatch library for CIL, so do not consider overrides for now
|
||||
result.getUnderlyingCallable() = getCallableForDataFlow(call.getTarget())
|
||||
}
|
||||
|
||||
override ControlFlow::Nodes::ElementNode getControlFlowNode() { none() }
|
||||
|
||||
override DataFlow::ExprNode getNode() { result.getExpr() = call }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.asCallable() = call.getEnclosingCallable()
|
||||
}
|
||||
|
||||
override string toString() { result = call.toString() }
|
||||
|
||||
override Location getLocation() { result = call.getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A synthesized call inside a callable with a flow summary.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
private import csharp
|
||||
private import cil
|
||||
private import dotnet
|
||||
private import DataFlowPublic
|
||||
private import DataFlowDispatch
|
||||
private import DataFlowImplCommon
|
||||
@@ -16,6 +18,8 @@ private import semmle.code.csharp.frameworks.NHibernate
|
||||
private import semmle.code.csharp.frameworks.Razor
|
||||
private import semmle.code.csharp.frameworks.system.Collections
|
||||
private import semmle.code.csharp.frameworks.system.threading.Tasks
|
||||
private import semmle.code.cil.Ssa::Ssa as CilSsa
|
||||
private import semmle.code.cil.internal.SsaImpl as CilSsaImpl
|
||||
private import codeql.util.Unit
|
||||
private import codeql.util.Boolean
|
||||
|
||||
@@ -53,15 +57,15 @@ abstract class NodeImpl extends Node {
|
||||
|
||||
/** Do not call: use `getType()` instead. */
|
||||
cached
|
||||
abstract Type getTypeImpl();
|
||||
abstract DotNet::Type getTypeImpl();
|
||||
|
||||
/** Gets the type of this node used for type pruning. */
|
||||
DataFlowType getDataFlowType() {
|
||||
forceCachingInSameStage() and
|
||||
exists(Type t0 | result.asGvnType() = Gvn::getGlobalValueNumber(t0) |
|
||||
t0 = this.getType()
|
||||
t0 = getCSharpType(this.getType())
|
||||
or
|
||||
not exists(this.getType()) and
|
||||
not exists(getCSharpType(this.getType())) and
|
||||
t0 instanceof ObjectType
|
||||
)
|
||||
}
|
||||
@@ -92,12 +96,16 @@ private DataFlowCallable getEnclosingStaticFieldOrProperty(Expr e) {
|
||||
|
||||
private class ExprNodeImpl extends ExprNode, NodeImpl {
|
||||
override DataFlowCallable getEnclosingCallableImpl() {
|
||||
result.asCallable() = this.getControlFlowNodeImpl().getEnclosingCallable()
|
||||
result.asCallable() =
|
||||
[
|
||||
this.getExpr().(CIL::Expr).getEnclosingCallable().(DotNet::Callable),
|
||||
this.getControlFlowNodeImpl().getEnclosingCallable()
|
||||
]
|
||||
or
|
||||
result = getEnclosingStaticFieldOrProperty(this.asExpr())
|
||||
}
|
||||
|
||||
override Type getTypeImpl() {
|
||||
override DotNet::Type getTypeImpl() {
|
||||
forceCachingInSameStage() and
|
||||
result = this.getExpr().getType()
|
||||
}
|
||||
@@ -113,6 +121,11 @@ private class ExprNodeImpl extends ExprNode, NodeImpl {
|
||||
override string toStringImpl() {
|
||||
forceCachingInSameStage() and
|
||||
result = this.getControlFlowNodeImpl().toString()
|
||||
or
|
||||
exists(CIL::Expr e |
|
||||
this = TCilExprNode(e) and
|
||||
result = e.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +148,7 @@ abstract private class LocalFunctionCreationNode extends NodeImpl, TLocalFunctio
|
||||
LocalFunction getFunction() { result = function }
|
||||
|
||||
ExprNode getAnAccess(boolean inSameCallable) {
|
||||
isLocalFunctionCallReceiver(_, result.getExpr(), this.getFunction()) and
|
||||
result.getExpr().(LocalFunctionAccess).getTarget() = this.getFunction() and
|
||||
if result.getEnclosingCallable() = this.getEnclosingCallable()
|
||||
then inSameCallable = true
|
||||
else inSameCallable = false
|
||||
@@ -247,6 +260,12 @@ predicate hasNodePath(ControlFlowReachabilityConfiguration conf, ExprNode n1, No
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the CIL data-flow node for `node`, if any. */
|
||||
CIL::DataFlowNode asCilDataFlowNode(Node node) {
|
||||
result = node.asParameter() or
|
||||
result = node.asExpr()
|
||||
}
|
||||
|
||||
/** Provides logic related to captured variables. */
|
||||
module VariableCapture {
|
||||
private import codeql.dataflow.VariableCapture as Shared
|
||||
@@ -380,11 +399,7 @@ module VariableCapture {
|
||||
|
||||
predicate hasBody(Callable body) { body = c }
|
||||
|
||||
predicate hasAliasedAccess(Expr f) {
|
||||
closureFlowStep+(this, f) and not closureFlowStep(f, _)
|
||||
or
|
||||
isLocalFunctionCallReceiver(_, f.getAstNode(), c)
|
||||
}
|
||||
predicate hasAliasedAccess(Expr f) { closureFlowStep+(this, f) and not closureFlowStep(f, _) }
|
||||
}
|
||||
|
||||
class Callable extends Cs::Callable {
|
||||
@@ -712,6 +727,79 @@ module LocalFlow {
|
||||
)
|
||||
}
|
||||
|
||||
private module CilFlow {
|
||||
/**
|
||||
* Holds if `nodeFrom` is a last node referencing SSA definition `def`, which
|
||||
* can reach `next`.
|
||||
*/
|
||||
private predicate localFlowCilSsaInput(
|
||||
Node nodeFrom, CilSsaImpl::DefinitionExt def, CilSsaImpl::DefinitionExt next
|
||||
) {
|
||||
exists(CIL::BasicBlock bb, int i | CilSsaImpl::lastRefBeforeRedefExt(def, bb, i, next) |
|
||||
def.definesAt(_, bb, i, _) and
|
||||
def = nodeFrom.(CilSsaDefinitionExtNode).getDefinition() and
|
||||
def != next
|
||||
or
|
||||
nodeFrom = TCilExprNode(bb.getNode(i).(CIL::ReadAccess))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving
|
||||
* CIL SSA definition `def`.
|
||||
*/
|
||||
private predicate localCilSsaFlowStep(CilSsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) {
|
||||
// Flow into SSA definition
|
||||
exists(CIL::VariableUpdate vu |
|
||||
vu = def.(CilSsa::Definition).getVariableUpdate() and
|
||||
vu.getSource() = asCilDataFlowNode(nodeFrom) and
|
||||
def = nodeTo.(CilSsaDefinitionExtNode).getDefinition()
|
||||
)
|
||||
or
|
||||
// Flow from SSA definition to first read
|
||||
def = nodeFrom.(CilSsaDefinitionExtNode).getDefinition() and
|
||||
nodeTo = TCilExprNode(CilSsaImpl::getAFirstReadExt(def))
|
||||
or
|
||||
// Flow from read to next read
|
||||
exists(CIL::ReadAccess readFrom, CIL::ReadAccess readTo |
|
||||
CilSsaImpl::hasAdjacentReadsExt(def, readFrom, readTo) and
|
||||
nodeTo = TCilExprNode(readTo) and
|
||||
nodeFrom = TCilExprNode(readFrom) and
|
||||
nodeFrom != nodeTo
|
||||
)
|
||||
or
|
||||
// Flow into phi (read) node
|
||||
exists(CilSsaImpl::DefinitionExt phi |
|
||||
localFlowCilSsaInput(nodeFrom, def, phi) and
|
||||
phi = nodeTo.(CilSsaDefinitionExtNode).getDefinition()
|
||||
|
|
||||
phi instanceof CilSsa::PhiNode
|
||||
or
|
||||
phi instanceof CilSsaImpl::PhiReadNode
|
||||
)
|
||||
}
|
||||
|
||||
private predicate localExactStep(CIL::DataFlowNode src, CIL::DataFlowNode sink) {
|
||||
src = sink.(CIL::Opcodes::Dup).getAnOperand()
|
||||
or
|
||||
src = sink.(CIL::Conversion).getExpr()
|
||||
or
|
||||
src = sink.(CIL::WriteAccess).getExpr()
|
||||
or
|
||||
src = sink.(CIL::Method).getAnImplementation().getAnInstruction().(CIL::Return)
|
||||
or
|
||||
src = sink.(CIL::Return).getExpr()
|
||||
or
|
||||
src = sink.(CIL::ConditionalBranch).getAnOperand()
|
||||
}
|
||||
|
||||
predicate localFlowStepCil(Node nodeFrom, Node nodeTo) {
|
||||
localExactStep(asCilDataFlowNode(nodeFrom), asCilDataFlowNode(nodeTo))
|
||||
or
|
||||
localCilSsaFlowStep(_, nodeFrom, nodeTo)
|
||||
}
|
||||
}
|
||||
|
||||
predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) {
|
||||
hasNodePath(any(LocalExprStepConfiguration x), nodeFrom, nodeTo)
|
||||
or
|
||||
@@ -720,6 +808,8 @@ module LocalFlow {
|
||||
or
|
||||
ThisFlow::adjacentThisRefs(nodeFrom.(PostUpdateNode).getPreUpdateNode(), nodeTo)
|
||||
or
|
||||
CilFlow::localFlowStepCil(nodeFrom, nodeTo)
|
||||
or
|
||||
exists(AssignableDefinition def, ControlFlow::Node cfn, Ssa::ExplicitDefinition ssaDef |
|
||||
ssaDef.getADefinition() = def and
|
||||
ssaDef.getControlFlowNode() = cfn and
|
||||
@@ -791,7 +881,7 @@ module LocalFlow {
|
||||
exists(SsaImpl::getAReadAtNode(def, node2.(ExprNode).getControlFlowNode()))
|
||||
)
|
||||
or
|
||||
node2 = node1.(LocalFunctionCreationNode).getAnAccess(true)
|
||||
delegateCreationStep(node1, node2)
|
||||
or
|
||||
node1 =
|
||||
unique(FlowSummaryNode n1 |
|
||||
@@ -1021,6 +1111,13 @@ private predicate arrayStore(Expr e, Expr src, Expr a, boolean postUpdate) {
|
||||
*/
|
||||
private predicate arrayRead(Expr e1, ArrayRead e2) { e1 = e2.getQualifier() }
|
||||
|
||||
private Type getCSharpType(DotNet::Type t) {
|
||||
result = t
|
||||
or
|
||||
not t instanceof Type and
|
||||
result.matchesHandle(t)
|
||||
}
|
||||
|
||||
private class RelevantGvnType extends Gvn::GvnType {
|
||||
RelevantGvnType() { this = any(NodeImpl n).getDataFlowType().asGvnType() }
|
||||
}
|
||||
@@ -1092,6 +1189,8 @@ private module Cached {
|
||||
cached
|
||||
newtype TNode =
|
||||
TExprNode(ControlFlow::Nodes::ElementNode cfn) { cfn.getAstNode() instanceof Expr } or
|
||||
TCilExprNode(CIL::Expr e) { e.getImplementation() instanceof CIL::BestImplementation } or
|
||||
TCilSsaDefinitionExtNode(CilSsaImpl::DefinitionExt def) or
|
||||
TSsaDefinitionExtNode(SsaImpl::DefinitionExt def) {
|
||||
// Handled by `TExplicitParameterNode` below
|
||||
not def.(Ssa::ExplicitDefinition).getADefinition() instanceof
|
||||
@@ -1102,7 +1201,7 @@ private module Cached {
|
||||
// Handled by `TExplicitParameterNode` below
|
||||
not def instanceof AssignableDefinitions::ImplicitParameterDefinition
|
||||
} or
|
||||
TExplicitParameterNode(Parameter p) {
|
||||
TExplicitParameterNode(DotNet::Parameter p) {
|
||||
p = any(DataFlowCallable dfc).asCallable().getAParameter()
|
||||
} or
|
||||
TInstanceParameterNode(InstanceCallable c) or
|
||||
@@ -1272,6 +1371,28 @@ predicate nodeIsHidden(Node n) {
|
||||
n instanceof CaptureNode
|
||||
}
|
||||
|
||||
/** A CIL SSA definition, viewed as a node in a data flow graph. */
|
||||
class CilSsaDefinitionExtNode extends NodeImpl, TCilSsaDefinitionExtNode {
|
||||
CilSsaImpl::DefinitionExt def;
|
||||
|
||||
CilSsaDefinitionExtNode() { this = TCilSsaDefinitionExtNode(def) }
|
||||
|
||||
/** Gets the underlying SSA definition. */
|
||||
CilSsaImpl::DefinitionExt getDefinition() { result = def }
|
||||
|
||||
override DataFlowCallable getEnclosingCallableImpl() {
|
||||
result.asCallable() = def.getBasicBlock().getFirstNode().getImplementation().getMethod()
|
||||
}
|
||||
|
||||
override CIL::Type getTypeImpl() { result = def.getSourceVariable().getType() }
|
||||
|
||||
override ControlFlow::Node getControlFlowNodeImpl() { none() }
|
||||
|
||||
override Location getLocationImpl() { result = def.getBasicBlock().getLocation() }
|
||||
|
||||
override string toStringImpl() { result = def.toString() }
|
||||
}
|
||||
|
||||
/** An SSA definition, viewed as a node in a data flow graph. */
|
||||
class SsaDefinitionExtNode extends NodeImpl, TSsaDefinitionExtNode {
|
||||
SsaImpl::DefinitionExt def;
|
||||
@@ -1343,7 +1464,7 @@ private module ParameterNodes {
|
||||
* flow graph.
|
||||
*/
|
||||
class ExplicitParameterNode extends ParameterNodeImpl, TExplicitParameterNode {
|
||||
private Parameter parameter;
|
||||
private DotNet::Parameter parameter;
|
||||
|
||||
ExplicitParameterNode() { this = TExplicitParameterNode(parameter) }
|
||||
|
||||
@@ -1361,7 +1482,7 @@ private module ParameterNodes {
|
||||
result.asCallable() = parameter.getCallable()
|
||||
}
|
||||
|
||||
override Type getTypeImpl() { result = parameter.getType() }
|
||||
override DotNet::Type getTypeImpl() { result = parameter.getType() }
|
||||
|
||||
override ControlFlow::Node getControlFlowNodeImpl() { none() }
|
||||
|
||||
@@ -1418,7 +1539,7 @@ private module ParameterNodes {
|
||||
|
||||
override Location getLocationImpl() { result = callable.getLocation() }
|
||||
|
||||
override Type getTypeImpl() { none() }
|
||||
override DotNet::Type getTypeImpl() { none() }
|
||||
|
||||
override DataFlowType getDataFlowType() { callable = result.asDelegate() }
|
||||
|
||||
@@ -1487,7 +1608,11 @@ private module ArgumentNodes {
|
||||
|
||||
/** A data-flow node that represents an explicit call argument. */
|
||||
class ExplicitArgumentNode extends ArgumentNodeImpl {
|
||||
ExplicitArgumentNode() { this.asExpr() instanceof Argument }
|
||||
ExplicitArgumentNode() {
|
||||
this.asExpr() instanceof Argument
|
||||
or
|
||||
this.asExpr() = any(CilDataFlowCall cc).getCilCall().getAnArgument()
|
||||
}
|
||||
|
||||
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
|
||||
exists(ArgumentConfiguration x, Expr c, Argument arg |
|
||||
@@ -1496,6 +1621,12 @@ private module ArgumentNodes {
|
||||
arg.isArgumentOf(c, pos) and
|
||||
x.hasExprPath(_, this.getControlFlowNode(), _, call.getControlFlowNode())
|
||||
)
|
||||
or
|
||||
exists(CIL::Call c, CIL::Expr arg |
|
||||
arg = this.asExpr() and
|
||||
c = call.getExpr() and
|
||||
arg = c.getArgument(pos.getPosition())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1612,7 +1743,7 @@ private module ReturnNodes {
|
||||
*/
|
||||
class ExprReturnNode extends ReturnNode, ExprNode {
|
||||
ExprReturnNode() {
|
||||
exists(Callable c, Expr e | e = this.getExpr() |
|
||||
exists(DotNet::Callable c, DotNet::Expr e | e = this.getExpr() |
|
||||
c.canReturn(e) and not c.(Modifiable).isAsync()
|
||||
)
|
||||
}
|
||||
@@ -1746,13 +1877,17 @@ private module OutNodes {
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node that reads a value returned directly by a callable.
|
||||
* A data-flow node that reads a value returned directly by a callable,
|
||||
* either via a C# call or a CIL call.
|
||||
*/
|
||||
class ExprOutNode extends OutNode, ExprNode {
|
||||
private DataFlowCall call;
|
||||
|
||||
ExprOutNode() {
|
||||
exists(Expr e | e = this.getExpr() | call = csharpCall(e, this.getControlFlowNode()))
|
||||
exists(DotNet::Expr e | e = this.getExpr() |
|
||||
call = csharpCall(e, this.getControlFlowNode()) or
|
||||
call = TCilCall(e)
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlowCall getCall(ReturnKind kind) {
|
||||
@@ -1834,7 +1969,7 @@ class FlowSummaryNode extends NodeImpl, TFlowSummaryNode {
|
||||
result = FlowSummaryImpl::Private::summaryNodeType(this.getSummaryNode())
|
||||
}
|
||||
|
||||
override Type getTypeImpl() { none() }
|
||||
override DotNet::Type getTypeImpl() { none() }
|
||||
|
||||
override ControlFlow::Node getControlFlowNodeImpl() { none() }
|
||||
|
||||
@@ -1995,6 +2130,8 @@ class FieldOrProperty extends Assignable, Modifiable {
|
||||
or
|
||||
p.isAutoImplementedReadOnly()
|
||||
or
|
||||
p.matchesHandle(any(CIL::TrivialProperty tp))
|
||||
or
|
||||
p.getDeclaringType() instanceof AnonymousClass
|
||||
)
|
||||
)
|
||||
@@ -2412,10 +2549,9 @@ class DataFlowType extends TDataFlowType {
|
||||
* creations associated with the same type.
|
||||
*/
|
||||
ControlFlowElement getADelegateCreation() {
|
||||
exists(Callable callable | this = TDelegateDataFlowType(callable) |
|
||||
lambdaCreationExpr(result, callable)
|
||||
or
|
||||
isLocalFunctionCallReceiver(_, result, callable)
|
||||
exists(Callable callable |
|
||||
lambdaCreationExpr(result, callable) and
|
||||
this = TDelegateDataFlowType(callable)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2430,7 +2566,12 @@ class DataFlowType extends TDataFlowType {
|
||||
DataFlowType getNodeType(Node n) {
|
||||
result = n.(NodeImpl).getDataFlowType() and
|
||||
not lambdaCreation(n, _, _) and
|
||||
not isLocalFunctionCallReceiver(_, n.asExpr(), _)
|
||||
not delegateCreationStep(_, n)
|
||||
or
|
||||
exists(Node arg |
|
||||
delegateCreationStep(arg, n) and
|
||||
result = getNodeType(arg)
|
||||
)
|
||||
or
|
||||
[
|
||||
n.asExpr().(ControlFlowElement),
|
||||
@@ -2599,7 +2740,7 @@ module PostUpdateNodes {
|
||||
result = getEnclosingStaticFieldOrProperty(oc)
|
||||
}
|
||||
|
||||
override Type getTypeImpl() { result = oc.getType() }
|
||||
override DotNet::Type getTypeImpl() { result = oc.getType() }
|
||||
|
||||
override ControlFlow::Nodes::ElementNode getControlFlowNodeImpl() { result = cfn }
|
||||
|
||||
@@ -2712,7 +2853,7 @@ class CastNode extends Node {
|
||||
}
|
||||
}
|
||||
|
||||
class DataFlowExpr = Expr;
|
||||
class DataFlowExpr = DotNet::Expr;
|
||||
|
||||
/** Holds if `e` is an expression that always has the same Boolean value `val`. */
|
||||
private predicate constantBooleanExpr(Expr e, boolean val) {
|
||||
@@ -2755,7 +2896,7 @@ private predicate lambdaCreationExpr(ControlFlowElement creation, Callable c) {
|
||||
c =
|
||||
[
|
||||
creation.(AnonymousFunctionExpr),
|
||||
creation.(DelegateCreation).getArgument().(CallableAccess).getTarget().getUnboundDeclaration(),
|
||||
creation.(CallableAccess).getTarget().getUnboundDeclaration(),
|
||||
creation.(AddressOfExpr).getOperand().(CallableAccess).getTarget().getUnboundDeclaration(),
|
||||
creation.(LocalFunctionStmt).getLocalFunction()
|
||||
]
|
||||
@@ -2769,13 +2910,6 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
|
||||
exists(kind)
|
||||
}
|
||||
|
||||
private predicate isLocalFunctionCallReceiver(
|
||||
LocalFunctionCall call, LocalFunctionAccess receiver, LocalFunction f
|
||||
) {
|
||||
receiver.getParent() = call and
|
||||
f = receiver.getTarget().getUnboundDeclaration()
|
||||
}
|
||||
|
||||
private class LambdaConfiguration extends ControlFlowReachabilityConfiguration {
|
||||
LambdaConfiguration() { this = "LambdaConfiguration" }
|
||||
|
||||
@@ -2792,7 +2926,7 @@ private class LambdaConfiguration extends ControlFlowReachabilityConfiguration {
|
||||
scope = e2 and
|
||||
isSuccessor = true
|
||||
or
|
||||
isLocalFunctionCallReceiver(e2, e1, _) and
|
||||
e1.(LocalFunctionAccess).getParent() = e2.(LocalFunctionCall) and
|
||||
exactScope = false and
|
||||
scope = e2 and
|
||||
isSuccessor = true
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
private import csharp
|
||||
private import cil
|
||||
private import dotnet
|
||||
private import DataFlowDispatch
|
||||
private import DataFlowPrivate
|
||||
private import semmle.code.csharp.controlflow.Guards
|
||||
@@ -10,7 +12,7 @@ private import semmle.code.csharp.Unification
|
||||
*/
|
||||
class Node extends TNode {
|
||||
/** Gets the expression corresponding to this node, if any. */
|
||||
Expr asExpr() { result = this.(ExprNode).getExpr() }
|
||||
DotNet::Expr asExpr() { result = this.(ExprNode).getExpr() }
|
||||
|
||||
/**
|
||||
* Gets the expression corresponding to this node, at control flow node `cfn`,
|
||||
@@ -21,7 +23,7 @@ class Node extends TNode {
|
||||
}
|
||||
|
||||
/** Gets the parameter corresponding to this node, if any. */
|
||||
Parameter asParameter() { result = this.(ParameterNode).getParameter() }
|
||||
DotNet::Parameter asParameter() { result = this.(ParameterNode).getParameter() }
|
||||
|
||||
/** Gets the definition corresponding to this node, if any. */
|
||||
AssignableDefinition asDefinition() { result = this.asDefinitionAtNode(_) }
|
||||
@@ -35,7 +37,7 @@ class Node extends TNode {
|
||||
}
|
||||
|
||||
/** Gets the type of this node. */
|
||||
final Type getType() { result = this.(NodeImpl).getTypeImpl() }
|
||||
final DotNet::Type getType() { result = this.(NodeImpl).getTypeImpl() }
|
||||
|
||||
/** Gets the enclosing callable of this node. */
|
||||
final Callable getEnclosingCallable() {
|
||||
@@ -65,6 +67,8 @@ class Node extends TNode {
|
||||
}
|
||||
}
|
||||
|
||||
private class TExprNode_ = TExprNode or TCilExprNode;
|
||||
|
||||
/**
|
||||
* An expression, viewed as a node in a data flow graph.
|
||||
*
|
||||
@@ -72,9 +76,13 @@ class Node extends TNode {
|
||||
* to multiple `ExprNode`s, just like it may correspond to multiple
|
||||
* `ControlFlow::Node`s.
|
||||
*/
|
||||
class ExprNode extends Node, TExprNode {
|
||||
class ExprNode extends Node, TExprNode_ {
|
||||
/** Gets the expression corresponding to this node. */
|
||||
Expr getExpr() { result = this.getExprAtNode(_) }
|
||||
DotNet::Expr getExpr() {
|
||||
result = this.getExprAtNode(_)
|
||||
or
|
||||
this = TCilExprNode(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the expression corresponding to this node, at control flow node `cfn`,
|
||||
@@ -86,22 +94,16 @@ class ExprNode extends Node, TExprNode {
|
||||
}
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate isParameterOf0(DataFlowCallable c, ParameterPosition ppos, Parameter p) {
|
||||
p.getCallable() = c.asCallable() and
|
||||
p.getPosition() = ppos.getPosition()
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of a parameter at function entry, viewed as a node in a data
|
||||
* flow graph.
|
||||
*/
|
||||
class ParameterNode extends Node instanceof ParameterNodeImpl {
|
||||
/** Gets the parameter corresponding to this node, if any. */
|
||||
Parameter getParameter() {
|
||||
DotNet::Parameter getParameter() {
|
||||
exists(DataFlowCallable c, ParameterPosition ppos |
|
||||
super.isParameterOf(c, ppos) and
|
||||
isParameterOf0(c, ppos, result)
|
||||
result = c.asCallable().getParameter(ppos.getPosition())
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -118,12 +120,12 @@ class AssignableDefinitionNode extends Node instanceof AssignableDefinitionNodeI
|
||||
}
|
||||
|
||||
/** Gets a node corresponding to expression `e`. */
|
||||
ExprNode exprNode(Expr e) { result.getExpr() = e }
|
||||
ExprNode exprNode(DotNet::Expr e) { result.getExpr() = e }
|
||||
|
||||
/**
|
||||
* Gets the node corresponding to the value of parameter `p` at function entry.
|
||||
*/
|
||||
ParameterNode parameterNode(Parameter p) { result.getParameter() = p }
|
||||
ParameterNode parameterNode(DotNet::Parameter p) { result.getParameter() = p }
|
||||
|
||||
/** Gets a node corresponding to the definition `def`. */
|
||||
AssignableDefinitionNode assignableDefinitionNode(AssignableDefinition def) {
|
||||
@@ -144,7 +146,7 @@ predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
|
||||
* local (intra-procedural) steps.
|
||||
*/
|
||||
pragma[inline]
|
||||
predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)) }
|
||||
predicate localExprFlow(DotNet::Expr e1, DotNet::Expr e2) { localFlow(exprNode(e1), exprNode(e2)) }
|
||||
|
||||
/**
|
||||
* A data flow node that jumps between callables. This can be extended in
|
||||
|
||||
@@ -7,6 +7,8 @@ private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
|
||||
private import semmle.code.csharp.dataflow.internal.ControlFlowReachability
|
||||
private import semmle.code.csharp.dispatch.Dispatch
|
||||
private import semmle.code.csharp.commons.ComparisonTest
|
||||
private import cil
|
||||
private import dotnet
|
||||
// import `TaintedMember` definitions from other files to avoid potential reevaluation
|
||||
private import semmle.code.csharp.frameworks.JsonNET
|
||||
private import semmle.code.csharp.frameworks.WCF
|
||||
@@ -31,6 +33,16 @@ predicate defaultTaintSanitizer(DataFlow::Node node) {
|
||||
bindingset[node]
|
||||
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) { none() }
|
||||
|
||||
private predicate localCilTaintStep(CIL::DataFlowNode src, CIL::DataFlowNode sink) {
|
||||
src = sink.(CIL::BinaryArithmeticExpr).getAnOperand() or
|
||||
src = sink.(CIL::Opcodes::Neg).getOperand() or
|
||||
src = sink.(CIL::UnaryBitwiseOperation).getOperand()
|
||||
}
|
||||
|
||||
private predicate localTaintStepCil(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
localCilTaintStep(asCilDataFlowNode(nodeFrom), asCilDataFlowNode(nodeTo))
|
||||
}
|
||||
|
||||
private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityConfiguration {
|
||||
LocalTaintExprStepConfiguration() { this = "LocalTaintExprStepConfiguration" }
|
||||
|
||||
@@ -94,6 +106,8 @@ private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityCon
|
||||
|
||||
private predicate localTaintStepCommon(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
hasNodePath(any(LocalTaintExprStepConfiguration x), nodeFrom, nodeTo)
|
||||
or
|
||||
localTaintStepCil(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
cached
|
||||
|
||||
@@ -5,12 +5,14 @@
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import cil
|
||||
private import dotnet
|
||||
|
||||
/**
|
||||
* A run-time callable. That is, a callable that is neither abstract
|
||||
* nor defined in an interface.
|
||||
*/
|
||||
class RuntimeCallable extends Callable {
|
||||
class RuntimeCallable extends DotNet::Callable {
|
||||
RuntimeCallable() {
|
||||
not this.(Modifiable).isAbstract() and
|
||||
(
|
||||
@@ -21,7 +23,15 @@ class RuntimeCallable extends Callable {
|
||||
}
|
||||
|
||||
/** A run-time method. */
|
||||
class RuntimeMethod extends RuntimeCallable, Method { }
|
||||
class RuntimeMethod extends RuntimeCallable {
|
||||
RuntimeMethod() {
|
||||
this instanceof Method or
|
||||
this instanceof CIL::Method
|
||||
}
|
||||
|
||||
/** Holds if the method is `static`. */
|
||||
predicate isStatic() { this.(Method).isStatic() or this.(CIL::Method).isStatic() }
|
||||
}
|
||||
|
||||
/** A run-time instance method. */
|
||||
class RuntimeInstanceMethod extends RuntimeMethod {
|
||||
|
||||
@@ -8,6 +8,7 @@ import Expr
|
||||
private import semmle.code.csharp.dataflow.internal.DataFlowDispatch
|
||||
private import semmle.code.csharp.dataflow.internal.DataFlowImplCommon
|
||||
private import semmle.code.csharp.dispatch.Dispatch
|
||||
private import dotnet
|
||||
|
||||
/**
|
||||
* A call. Either a method call (`MethodCall`), a constructor initializer call
|
||||
@@ -15,7 +16,7 @@ private import semmle.code.csharp.dispatch.Dispatch
|
||||
* a delegate call (`DelegateCall`), an accessor call (`AccessorCall`), a
|
||||
* constructor call (`ObjectCreation`), or a local function call (`LocalFunctionCall`).
|
||||
*/
|
||||
class Call extends Expr, @call {
|
||||
class Call extends DotNet::Call, Expr, @call {
|
||||
/**
|
||||
* Gets the static (compile-time) target of this call. For example, the
|
||||
* static target of `x.M()` on line 9 is `A.M` in
|
||||
@@ -37,19 +38,13 @@ class Call extends Expr, @call {
|
||||
* Use `getARuntimeTarget()` instead to get a potential run-time target (will
|
||||
* include `B.M` in the example above).
|
||||
*/
|
||||
Callable getTarget() { none() }
|
||||
override Callable getTarget() { none() }
|
||||
|
||||
/** Gets the `i`th argument to this call, if any. */
|
||||
Expr getArgument(int i) { result = this.getChild(i) and i >= 0 }
|
||||
override Expr getArgument(int i) { result = this.getChild(i) and i >= 0 }
|
||||
|
||||
/**
|
||||
* Gets the `i`th "raw" argument to this call, if any.
|
||||
* For instance methods, argument 0 is the qualifier.
|
||||
*/
|
||||
Expr getRawArgument(int i) { result = this.getArgument(i) }
|
||||
override Expr getRawArgument(int i) { result = this.getArgument(i) }
|
||||
|
||||
/** Gets an argument to this call. */
|
||||
Expr getAnArgument() { result = this.getArgument(_) }
|
||||
override Expr getAnArgument() { result = this.getArgument(_) }
|
||||
|
||||
/** Gets the number of arguments of this call. */
|
||||
int getNumberOfArguments() { result = count(this.getAnArgument()) }
|
||||
@@ -64,7 +59,7 @@ class Call extends Expr, @call {
|
||||
* consider default arguments.
|
||||
*/
|
||||
cached
|
||||
Expr getArgumentForParameter(Parameter p) {
|
||||
override Expr getArgumentForParameter(DotNet::Parameter p) {
|
||||
// Appears in the positional part of the call
|
||||
result = this.getImplicitArgument(p)
|
||||
or
|
||||
@@ -74,7 +69,7 @@ class Call extends Expr, @call {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Expr getImplicitArgument(Parameter p) {
|
||||
private Expr getImplicitArgument(DotNet::Parameter p) {
|
||||
this.getTarget().getAParameter() = p and
|
||||
not exists(result.getExplicitArgumentName()) and
|
||||
(
|
||||
@@ -149,7 +144,7 @@ class Call extends Expr, @call {
|
||||
* - Line 16: There is no static target (delegate call) but the delegate `i => { }`
|
||||
* (line 20) is a run-time target.
|
||||
*/
|
||||
Callable getARuntimeTarget() {
|
||||
override Callable getARuntimeTarget() {
|
||||
exists(DispatchCall dc | dc.getCall() = this | result = dc.getADynamicTarget())
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import semmle.code.csharp.controlflow.ControlFlowElement
|
||||
import semmle.code.csharp.Location
|
||||
import semmle.code.csharp.Stmt
|
||||
import semmle.code.csharp.Type
|
||||
private import dotnet
|
||||
private import semmle.code.csharp.ExprOrStmtParent
|
||||
private import semmle.code.csharp.frameworks.System
|
||||
private import semmle.code.csharp.TypeRef
|
||||
@@ -37,11 +38,11 @@ private import semmle.code.csharp.TypeRef
|
||||
* interpolated string (`InterpolatedStringExpr`), a qualifiable expression
|
||||
* (`QualifiableExpr`), or a literal (`Literal`).
|
||||
*/
|
||||
class Expr extends ControlFlowElement, @expr {
|
||||
class Expr extends DotNet::Expr, ControlFlowElement, @expr {
|
||||
override Location getALocation() { expr_location(this, result) }
|
||||
|
||||
/** Gets the type of this expression. */
|
||||
Type getType() {
|
||||
override Type getType() {
|
||||
expressions(this, _, result)
|
||||
or
|
||||
not expressions(this, _, any(Type t)) and
|
||||
@@ -52,10 +53,7 @@ class Expr extends ControlFlowElement, @expr {
|
||||
final AnnotatedType getAnnotatedType() { result.appliesTo(this) }
|
||||
|
||||
/** Gets the value of this expression, if any */
|
||||
string getValue() { expr_value(this, result) }
|
||||
|
||||
/** Holds if this expression has a value. */
|
||||
final predicate hasValue() { exists(this.getValue()) }
|
||||
override string getValue() { expr_value(this, result) }
|
||||
|
||||
/** Gets the enclosing statement of this expression, if any. */
|
||||
final Stmt getEnclosingStmt() { enclosingStmt(this, result) }
|
||||
@@ -90,10 +88,6 @@ class Expr extends ControlFlowElement, @expr {
|
||||
*/
|
||||
string getExplicitArgumentName() { expr_argument_name(this, result) }
|
||||
|
||||
/**
|
||||
* Gets the parent of this expression. This is for example the element
|
||||
* that uses the result of this expression.
|
||||
*/
|
||||
override Element getParent() { result = ControlFlowElement.super.getParent() }
|
||||
|
||||
/** Holds if the nullable flow state of this expression is not null. */
|
||||
@@ -949,13 +943,13 @@ class InterpolatedStringExpr extends Expr, @interpolated_string_expr {
|
||||
* A `throw` element. Either a `throw` expression (`ThrowExpr`)
|
||||
* or a `throw` statement (`ThrowStmt`).
|
||||
*/
|
||||
class ThrowElement extends ControlFlowElement, @throw_element {
|
||||
class ThrowElement extends ControlFlowElement, DotNet::Throw, @throw_element {
|
||||
/**
|
||||
* Gets the expression of the exception being thrown, if any.
|
||||
*
|
||||
* For example, `new Exception("Syntax error")` in `throw new Exception("Syntax error");`.
|
||||
*/
|
||||
Expr getExpr() { result = this.getChild(0) }
|
||||
override Expr getExpr() { result = this.getChild(0) }
|
||||
|
||||
/** Gets the type of exception being thrown. */
|
||||
Class getThrownExceptionType() {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user