Compare commits

..

1 Commits

Author SHA1 Message Date
Esben Sparre Andreasen
5f41b3afb6 make boosted version of js/code-injection
Changes generated with:

```
tb boost src/Security/CWE-094/CodeInjection.ql CodeInjectionSink
```
2022-01-31 10:57:18 +01:00
290 changed files with 7587 additions and 25526 deletions

View File

@@ -6,7 +6,6 @@
"*/ql/examples/qlpack.yml",
"cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml",
"javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml",
"javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml",
"javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml",
"csharp/ql/campaigns/Solorigate/lib/qlpack.yml",
"csharp/ql/campaigns/Solorigate/src/qlpack.yml",

View File

@@ -1,103 +0,0 @@
name: Models as Data - Diff
on:
workflow_dispatch:
inputs:
projects:
description: "The projects to generate models for"
required: true
default: '["netty/netty"]'
pull_request:
branches:
- main
paths:
- "java/ql/src/utils/model-generator/**/*.*"
- ".github/workflows/mad_modelDiff.yml"
permissions:
contents: read
jobs:
model-diff:
name: Model Difference
runs-on: ubuntu-latest
if: github.repository == 'github/codeql'
strategy:
matrix:
slug: ${{fromJson(github.event.inputs.projects || '["apache/commons-codec", "apache/commons-io", "apache/commons-beanutils", "apache/commons-logging", "apache/commons-fileupload", "apache/commons-lang", "apache/commons-validator", "apache/commons-csv", "apache/dubbo"]' )}}
steps:
- name: Clone github/codeql from PR
uses: actions/checkout@v2
if: github.event.pull_request
with:
path: codeql-pr
- name: Clone github/codeql from main
uses: actions/checkout@v2
with:
path: codeql-main
ref: main
- uses: ./codeql-main/.github/actions/fetch-codeql
- name: Download database
env:
SLUG: ${{ matrix.slug }}
run: |
set -x
mkdir lib-dbs
SHORTNAME=${SLUG//[^a-zA-Z0-9_]/}
projectId=`curl -s https://lgtm.com/api/v1.0/projects/g/${SLUG} | jq .id`
curl -L "https://lgtm.com/api/v1.0/snapshots/$projectId/java" -o "$SHORTNAME.zip"
unzip -q -d "${SHORTNAME}-db" "${SHORTNAME}.zip"
mkdir "lib-dbs/$SHORTNAME/"
mv "${SHORTNAME}-db/"$(ls -1 "${SHORTNAME}"-db)/* "lib-dbs/${SHORTNAME}/"
- name: Generate Models (PR and main)
run: |
set -x
mkdir tmp-models
MODELS=`pwd`/tmp-models
DATABASES=`pwd`/lib-dbs
analyzeDatabaseWithCheckout() {
QL_VARIANT=$1
DATABASE=$2
cd codeql-$QL_VARIANT
SHORTNAME=`basename $DATABASE`
python java/ql/src/utils/model-generator/GenerateFlowModel.py $DATABASE $MODELS/${SHORTNAME}.qll
mv $MODELS/${SHORTNAME}.qll $MODELS/${SHORTNAME}Generated_${QL_VARIANT}.qll
cd ..
}
for d in $DATABASES/*/ ; do
ls -1 "$d"
analyzeDatabaseWithCheckout "main" $d
if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]
then
analyzeDatabaseWithCheckout "pr" $d
fi
done
- name: Install diff2html
if: github.event.pull_request
run: |
npm install -g diff2html-cli
- name: Generate Model Diff
if: github.event.pull_request
run: |
set -x
MODELS=`pwd`/tmp-models
ls -1 tmp-models/
for m in $MODELS/*_main.qll ; do
t="${m/main/"pr"}"
basename=`basename $m`
name="diff_${basename/_main.qll/""}"
(diff -w -u $m $t | diff2html -i stdin -F $MODELS/$name.html) || true
done
- uses: actions/upload-artifact@v2
with:
name: models
path: tmp-models/*.qll
retention-days: 20
- uses: actions/upload-artifact@v2
with:
name: diffs
path: tmp-models/*.html
retention-days: 20

View File

@@ -17,7 +17,7 @@ jobs:
CODEQL_THREADS: 4 # TODO: remove this once it's set by the CLI
strategy:
matrix:
repo:
repo:
- github/codeql
- github/codeql-go
runs-on: ubuntu-latest
@@ -35,7 +35,7 @@ jobs:
~/.cargo/registry
~/.cargo/git
ql/target
key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('ql/**/Cargo.lock') }}
key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Build Extractor
run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./create-extractor-pack.sh
env:

View File

@@ -29,24 +29,24 @@ jobs:
~/.cargo/registry
~/.cargo/git
ql/target
key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('ql/**/Cargo.lock') }}
key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Build extractor
run: |
cd ql;
codeqlpath=$(dirname ${{ steps.find-codeql.outputs.codeql-path }});
env "PATH=$PATH:$codeqlpath" ./create-extractor-pack.sh
- name: Run QL tests
run: |
run: |
"${CODEQL}" test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}/ql/extractor-pack" --consistency-queries ql/ql/consistency-queries ql/ql/test
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Check QL formatting
run: |
run: |
find ql/ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 "${CODEQL}" query format --check-only
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Check QL compilation
run: |
run: |
"${CODEQL}" query compile --check-only --threads=4 --warnings=error --search-path "${{ github.workspace }}/ql/extractor-pack" "ql/ql/src" "ql/ql/examples"
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}

View File

@@ -50,7 +50,7 @@ jobs:
~/.cargo/registry
~/.cargo/git
ruby/target
key: ${{ runner.os }}-ruby-rust-cargo-${{ hashFiles('ruby/**/Cargo.lock') }}
key: ${{ runner.os }}-rust-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Check formatting
run: cargo fmt --all -- --check
- name: Build

View File

@@ -24,45 +24,27 @@ defaults:
working-directory: ruby
jobs:
qlformat:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/fetch-codeql
- name: Check QL formatting
run: find ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only
qlcompile:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/fetch-codeql
- name: Check QL compilation
run: |
codeql query compile --check-only --threads=0 --ram 5000 --warnings=error "ql/src" "ql/examples"
env:
GITHUB_TOKEN: ${{ github.token }}
qlupgrade:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/fetch-codeql
- name: Check DB upgrade scripts
run: |
echo >empty.trap
codeql dataset import -S ql/lib/upgrades/initial/ruby.dbscheme testdb empty.trap
codeql dataset upgrade testdb --additional-packs ql/lib
diff -q testdb/ruby.dbscheme ql/lib/ruby.dbscheme
qltest:
runs-on: ubuntu-latest
strategy:
matrix:
slice: ["1/2", "2/2"]
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/fetch-codeql
- uses: ./ruby/actions/create-extractor-pack
- name: Run QL tests
run: |
codeql test run --threads=0 --ram 5000 --slice ${{ matrix.slice }} --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test
codeql test run --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Check QL formatting
run: find ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only
- name: Check QL compilation
run: |
codeql query compile --check-only --threads=4 --warnings=error "ql/src" "ql/examples"
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Check DB upgrade scripts
run: |
echo >empty.trap
codeql dataset import -S ql/lib/upgrades/initial/ruby.dbscheme testdb empty.trap
codeql dataset upgrade testdb --additional-packs ql/lib
diff -q testdb/ruby.dbscheme ql/lib/ruby.dbscheme

View File

@@ -1,6 +1,4 @@
name: codeql/cpp-examples
groups:
- cpp
- examples
version: 0.0.2
dependencies:
codeql/cpp-all: "*"

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The `Class::hasImplicitCopyConstructor` and `Class::hasImplicitCopyAssignmentOperator` methods now handle template instantiations more accurately. This should improve results for the `cpp/rule-of-two` query.

View File

@@ -285,17 +285,7 @@ class Class extends UserType {
predicate hasImplicitCopyConstructor() {
not this.implicitCopyConstructorDeleted() and
forall(CopyConstructor cc | cc = this.getAMemberFunction() |
cc.isCompilerGenerated() and not cc.isDeleted() and not cc.isDefaulted()
) and
(
not this instanceof ClassTemplateInstantiation
or
this.(ClassTemplateInstantiation).getTemplate().hasImplicitCopyConstructor()
) and
(
not this instanceof PartialClassTemplateSpecialization
or
this.(PartialClassTemplateSpecialization).getPrimaryTemplate().hasImplicitCopyConstructor()
cc.isCompilerGenerated() and not cc.isDeleted()
)
}
@@ -310,19 +300,7 @@ class Class extends UserType {
predicate hasImplicitCopyAssignmentOperator() {
not this.implicitCopyAssignmentOperatorDeleted() and
forall(CopyAssignmentOperator ca | ca = this.getAMemberFunction() |
ca.isCompilerGenerated() and not ca.isDeleted() and not ca.isDefaulted()
) and
(
not this instanceof ClassTemplateInstantiation
or
this.(ClassTemplateInstantiation).getTemplate().hasImplicitCopyAssignmentOperator()
) and
(
not this instanceof PartialClassTemplateSpecialization
or
this.(PartialClassTemplateSpecialization)
.getPrimaryTemplate()
.hasImplicitCopyAssignmentOperator()
ca.isCompilerGenerated() and not ca.isDeleted()
)
}
@@ -333,12 +311,6 @@ class Class extends UserType {
* http://en.cppreference.com/w/cpp/language/copy_constructor#Deleted_implicitly-declared_copy_constructor
*/
predicate implicitCopyConstructorDeleted() {
forex(CopyConstructor cc | cc = this.getAConstructor() |
cc.isDeleted()
or
not cc.isCompilerGenerated()
)
or
// - T has non-static data members that cannot be copied (have deleted,
// inaccessible, or ambiguous copy constructors);
exists(Type t | t = this.getAFieldSubobjectType().getUnspecifiedType() |
@@ -346,6 +318,34 @@ class Class extends UserType {
// constructors are considered equal.
this.cannotAccessCopyConstructorOnAny(t)
)
or
// - T has direct or virtual base class that cannot be copied (has deleted,
// inaccessible, or ambiguous copy constructors);
exists(Class c | c = this.getADirectOrVirtualBase() |
// Note: Overload resolution is not implemented -- all copy
// constructors are considered equal.
this.cannotAccessCopyConstructorOnThis(c)
)
or
// - T has direct or virtual base class with a deleted or inaccessible
// destructor;
exists(Class base | base = this.getADirectOrVirtualBase() |
this.cannotAccessDestructor(base, this)
)
or
// - T has a user-defined move constructor or move assignment operator;
exists(MoveConstructor mc | mc = this.getAMemberFunction() | not mc.isCompilerGenerated())
or
exists(MoveAssignmentOperator ma | ma = this.getAMemberFunction() |
not ma.isCompilerGenerated()
)
or
// - T is a union and has a variant member with non-trivial copy
// constructor (since C++11)
none() // Not implemented
or
// - T has a data member of rvalue reference type.
exists(Type t | t = this.getAFieldSubobjectType() | t instanceof RValueReferenceType)
}
/**
@@ -355,12 +355,34 @@ class Class extends UserType {
* http://en.cppreference.com/w/cpp/language/copy_assignment#Deleted_implicitly-declared_copy_assignment_operator
*/
predicate implicitCopyAssignmentOperatorDeleted() {
forex(CopyAssignmentOperator ca | ca = this.getAMemberFunction() |
ca.isDeleted()
or
not ca.isCompilerGenerated()
// - T has a user-declared move constructor;
exists(MoveConstructor mc | mc = this.getAMemberFunction() | not mc.isCompilerGenerated())
or
// - T has a user-declared move assignment operator.
exists(MoveAssignmentOperator ma | ma = this.getAMemberFunction() |
not ma.isCompilerGenerated()
)
or
// - T has a non-static data member of non-class type (or array thereof)
// that is const;
exists(Type t | t = this.getAFieldSubobjectType() |
// The rule for this case refers only to non-class types only, but our
// implementation extends it to cover class types too. Class types are
// supposed to be covered by the rule below on data members that
// cannot be copy-assigned. Copy-assigning a const class-typed member
// would call an overload of type
// `const C& operator=(const C&) const;`. Such an overload is unlikely
// to exist because it contradicts the intention of "const": it allows
// assigning to a const object. But since we have not implemented the
// ability to distinguish between overloads, we cannot distinguish that
// overload from the ordinary `C& operator=(const C&);`. Instead, we
// require class types to be non-const in this clause.
/* not t instanceof Class and */ t.isConst()
)
or
// - T has a non-static data member of a reference type;
exists(Type t | t = this.getAFieldSubobjectType() | t instanceof ReferenceType)
or
// - T has a non-static data member or a direct or virtual base class that
// cannot be copy-assigned (overload resolution for the copy assignment
// fails, or selects a deleted or inaccessible function);
@@ -369,6 +391,15 @@ class Class extends UserType {
// operators are considered equal.
this.cannotAccessCopyAssignmentOperatorOnAny(t)
)
or
exists(Class c | c = this.getADirectOrVirtualBase() |
// Note: Overload resolution is not implemented -- all copy assignment
// operators are considered equal.
this.cannotAccessCopyAssignmentOperatorOnThis(c)
)
// - T is a union-like class, and has a variant member whose corresponding
// assignment operator is non-trivial.
// Not implemented
}
/** Gets the destructor of this class, struct or union, if any. */

View File

@@ -1290,7 +1290,7 @@ class DataFlowCallOption extends TDataFlowCallOption {
}
}
/** A `Content` tagged with the type of a containing object. */
/** Content tagged with the type of a containing object. */
class TypedContent extends MkTypedContent {
private Content c;
private DataFlowType t;

View File

@@ -1,8 +1,3 @@
/**
* An IR taint tracking library that uses an IR DataFlow configuration to track
* taint from user inputs as defined by `semmle.code.cpp.security.Security`.
*/
import cpp
import semmle.code.cpp.security.Security
private import semmle.code.cpp.ir.dataflow.DataFlow

View File

@@ -1290,7 +1290,7 @@ class DataFlowCallOption extends TDataFlowCallOption {
}
}
/** A `Content` tagged with the type of a containing object. */
/** Content tagged with the type of a containing object. */
class TypedContent extends MkTypedContent {
private Content c;
private DataFlowType t;

View File

@@ -111,45 +111,6 @@ private predicate hasDefaultSideEffect(Call call, ParameterIndex i, boolean buff
)
}
/**
* A `Call` or `NewOrNewArrayExpr`.
*
* Both kinds of expression invoke a function as part of their evaluation. This class provides a
* way to treat both kinds of function similarly, and to get the invoked `Function`.
*/
class CallOrAllocationExpr extends Expr {
CallOrAllocationExpr() {
this instanceof Call
or
this instanceof NewOrNewArrayExpr
}
/** Gets the `Function` invoked by this expression, if known. */
final Function getTarget() {
result = this.(Call).getTarget()
or
result = this.(NewOrNewArrayExpr).getAllocator()
}
}
/**
* Returns the side effect opcode, if any, that represents any side effects not specifically modeled
* by an argument side effect.
*/
Opcode getCallSideEffectOpcode(CallOrAllocationExpr expr) {
not exists(expr.getTarget().(SideEffectFunction)) and result instanceof Opcode::CallSideEffect
or
exists(SideEffectFunction sideEffectFunction |
sideEffectFunction = expr.getTarget() and
if not sideEffectFunction.hasOnlySpecificWriteSideEffects()
then result instanceof Opcode::CallSideEffect
else (
not sideEffectFunction.hasOnlySpecificReadSideEffects() and
result instanceof Opcode::CallReadSideEffect
)
)
}
/**
* Returns a side effect opcode for parameter index `i` of the specified call.
*

View File

@@ -49,6 +49,19 @@ abstract class TranslatedCall extends TranslatedExpr {
tag = CallTag() and
opcode instanceof Opcode::Call and
resultType = getTypeForPRValue(getCallResultType())
or
hasSideEffect() and
tag = CallSideEffectTag() and
(
if hasWriteSideEffect()
then (
opcode instanceof Opcode::CallSideEffect and
resultType = getUnknownType()
) else (
opcode instanceof Opcode::CallReadSideEffect and
resultType = getVoidType()
)
)
}
override Instruction getChildSuccessor(TranslatedElement child) {
@@ -71,8 +84,25 @@ abstract class TranslatedCall extends TranslatedExpr {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
tag = CallTag() and
result = getSideEffects().getFirstInstruction()
(
(
tag = CallTag() and
if hasSideEffect()
then result = getInstruction(CallSideEffectTag())
else
if hasPreciseSideEffect()
then result = getSideEffects().getFirstInstruction()
else result = getParent().getChildSuccessor(this)
)
or
(
hasSideEffect() and
tag = CallSideEffectTag() and
if hasPreciseSideEffect()
then result = getSideEffects().getFirstInstruction()
else result = getParent().getChildSuccessor(this)
)
)
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
@@ -91,6 +121,15 @@ abstract class TranslatedCall extends TranslatedExpr {
)
}
final override CppType getInstructionMemoryOperandType(
InstructionTag tag, TypedOperandTag operandTag
) {
tag = CallSideEffectTag() and
hasSideEffect() and
operandTag instanceof SideEffectOperandTag and
result = getUnknownType()
}
final override Instruction getResult() { result = getInstruction(CallTag()) }
/**
@@ -161,31 +200,40 @@ abstract class TranslatedCall extends TranslatedExpr {
*/
abstract predicate hasArguments();
predicate hasReadSideEffect() { any() }
predicate hasWriteSideEffect() { any() }
private predicate hasSideEffect() { hasReadSideEffect() or hasWriteSideEffect() }
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
hasSideEffect() and
tag = CallSideEffectTag() and
result = getResult()
}
predicate hasPreciseSideEffect() { exists(getSideEffects()) }
final TranslatedSideEffects getSideEffects() { result.getExpr() = expr }
}
/**
* The IR translation of the side effects of the parent `TranslatedElement`.
*
* This object does not itself generate the side effect instructions. Instead, its children provide
* the actual side effects, with this object acting as a placeholder so the parent only needs to
* insert this one element at the point where all the side effects are supposed to occur.
*/
abstract class TranslatedSideEffects extends TranslatedElement {
/** Gets the expression whose side effects are being modeled. */
abstract Expr getExpr();
final override Locatable getAST() { result = getExpr() }
final override Function getFunction() { result = getExpr().getEnclosingFunction() }
final override TranslatedElement getChild(int i) {
override TranslatedElement getChild(int i) {
result =
rank[i + 1](TranslatedSideEffect tse, int group, int indexInGroup |
tse.getPrimaryExpr() = getExpr() and
tse.sortOrder(group, indexInGroup)
rank[i + 1](TranslatedSideEffect tse, int isWrite, int index |
(
tse.getCall() = getExpr() and
tse.getArgumentIndex() = index and
if tse.isWrite() then isWrite = 1 else isWrite = 0
)
|
tse order by group, indexInGroup
tse order by isWrite, index
)
}
@@ -198,21 +246,12 @@ abstract class TranslatedSideEffects extends TranslatedElement {
)
}
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
none()
/**
* Gets the `TranslatedFunction` containing this expression.
*/
final TranslatedFunction getEnclosingFunction() {
result = getTranslatedFunction(getExpr().getEnclosingFunction())
}
final override Instruction getFirstInstruction() {
result = getChild(0).getFirstInstruction()
or
// Some functions, like `std::move()`, have no side effects whatsoever.
not exists(getChild(0)) and result = getParent().getChildSuccessor(this)
}
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
/** Gets the primary instruction to be associated with each side effect instruction. */
abstract Instruction getPrimaryInstruction();
}
/**
@@ -286,6 +325,14 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall {
tag = CallTargetTag() and result = expr.getTarget()
}
override predicate hasReadSideEffect() {
not expr.getTarget().(SideEffectFunction).hasOnlySpecificReadSideEffects()
}
override predicate hasWriteSideEffect() {
not expr.getTarget().(SideEffectFunction).hasOnlySpecificWriteSideEffects()
}
override Instruction getQualifierResult() {
hasQualifier() and
result = getQualifier().getResult()
@@ -316,116 +363,209 @@ class TranslatedStructorCall extends TranslatedFunctionCall {
override predicate hasQualifier() { any() }
}
/**
* The IR translation of the side effects of a function call, including the implicit allocator
* call in a `new` or `new[]` expression.
*/
class TranslatedAllocationSideEffects extends TranslatedSideEffects,
TTranslatedAllocationSideEffects {
AllocationExpr expr;
TranslatedAllocationSideEffects() { this = TTranslatedAllocationSideEffects(expr) }
final override AllocationExpr getExpr() { result = expr }
override string toString() { result = "(allocation side effects for " + expr.toString() + ")" }
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
opcode instanceof Opcode::InitializeDynamicAllocation and
tag = OnlyInstructionTag() and
type = getUnknownType()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
kind = EdgeKind::gotoEdge() and
if exists(getChild(0))
then result = getChild(0).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag = addressOperand() and
result = getPrimaryInstructionForSideEffect(OnlyInstructionTag())
}
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
tag = OnlyInstructionTag() and
if expr instanceof NewOrNewArrayExpr
then result = getTranslatedAllocatorCall(expr).getInstruction(CallTag())
else result = getTranslatedCallInstruction(expr)
}
}
class TranslatedCallSideEffects extends TranslatedSideEffects, TTranslatedCallSideEffects {
Expr expr;
Call expr;
TranslatedCallSideEffects() { this = TTranslatedCallSideEffects(expr) }
final override string toString() { result = "(side effects for " + expr.toString() + ")" }
override string toString() { result = "(side effects for " + expr.toString() + ")" }
final override Expr getExpr() { result = expr }
override Call getExpr() { result = expr }
final override Instruction getPrimaryInstruction() {
expr instanceof Call and result = getTranslatedCallInstruction(expr)
or
expr instanceof NewOrNewArrayExpr and
result = getTranslatedAllocatorCall(expr).getInstruction(CallTag())
}
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) { none() }
/** Returns the sort group index for argument read side effects. */
private int argumentReadGroup() { result = 1 }
override Instruction getFirstInstruction() { result = getChild(0).getFirstInstruction() }
/** Returns the sort group index for conservative call side effects. */
private int callSideEffectGroup() {
result = 0 // Make this group first for now to preserve the existing ordering
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
/** Returns the sort group index for argument write side effects. */
private int argumentWriteGroup() { result = 2 }
/** Returns the sort group index for dynamic allocation side effects. */
private int initializeAllocationGroup() { result = 3 }
/**
* The IR translation of a single side effect of a call.
*/
abstract class TranslatedSideEffect extends TranslatedElement {
final override TranslatedElement getChild(int n) { none() }
final override Instruction getChildSuccessor(TranslatedElement child) { none() }
final override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
tag = OnlyInstructionTag() and
sideEffectInstruction(opcode, type)
result = getTranslatedCallInstruction(expr)
}
}
class TranslatedStructorCallSideEffects extends TranslatedCallSideEffects {
TranslatedStructorCallSideEffects() {
getParent().(TranslatedStructorCall).hasQualifier() and
getASideEffectOpcode(expr, -1) instanceof WriteSideEffectOpcode
}
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType t) {
tag instanceof OnlyInstructionTag and
t = getTypeForPRValue(expr.getTarget().getDeclaringType()) and
opcode = getASideEffectOpcode(expr, -1).(WriteSideEffectOpcode)
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
(
if exists(getChild(0))
then result = getChild(0).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
) and
tag = OnlyInstructionTag() and
kind instanceof GotoEdge
}
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag instanceof OnlyInstructionTag and
operandTag instanceof AddressOperandTag and
result = getParent().(TranslatedStructorCall).getQualifierResult()
}
final override int getInstructionIndex(InstructionTag tag) {
tag = OnlyInstructionTag() and
result = -1
}
}
class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEffect {
Call call;
Expr arg;
int index;
SideEffectOpcode sideEffectOpcode;
TranslatedSideEffect() {
this = TTranslatedArgumentSideEffect(call, arg, index, sideEffectOpcode)
}
override Locatable getAST() { result = arg }
Expr getExpr() { result = arg }
Call getCall() { result = call }
int getArgumentIndex() { result = index }
predicate isWrite() { sideEffectOpcode instanceof WriteSideEffectOpcode }
override string toString() {
isWrite() and
result = "(write side effect for " + arg.toString() + ")"
or
not isWrite() and
result = "(read side effect for " + arg.toString() + ")"
}
override TranslatedElement getChild(int n) { none() }
override Instruction getChildSuccessor(TranslatedElement child) { none() }
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
tag = OnlyInstructionTag() and
opcode = sideEffectOpcode and
(
isWrite() and
(
opcode instanceof BufferAccessOpcode and
type = getUnknownType()
or
not opcode instanceof BufferAccessOpcode and
exists(Type baseType | baseType = arg.getUnspecifiedType().(DerivedType).getBaseType() |
if baseType instanceof VoidType
then type = getUnknownType()
else type = getTypeForPRValueOrUnknown(baseType)
)
or
index = -1 and
not arg.getUnspecifiedType() instanceof DerivedType and
type = getTypeForPRValueOrUnknown(arg.getUnspecifiedType())
)
or
not isWrite() and
type = getVoidType()
)
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
result = getParent().getChildSuccessor(this) and
tag = OnlyInstructionTag() and
kind instanceof GotoEdge
}
final override Function getFunction() { result = getParent().getFunction() }
final override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
tag = OnlyInstructionTag() and
result = getParent().(TranslatedSideEffects).getPrimaryInstruction()
}
/**
* Gets the expression that caused this side effect.
*
* All side effects with the same `getPrimaryExpr()` will appear in the same contiguous sequence
* in the IR.
*/
abstract Expr getPrimaryExpr();
/**
* Gets the order in which this side effect should be sorted with respect to other side effects
* for the same expression.
*
* Side effects are sorted first by `group`, and then by `indexInGroup`.
*/
abstract predicate sortOrder(int group, int indexInGroup);
/**
* Gets the opcode and result type for the side effect instruction.
*/
abstract predicate sideEffectInstruction(Opcode opcode, CppType type);
}
/**
* The IR translation of a single argument side effect for a call.
*/
abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
Call call;
int index;
SideEffectOpcode sideEffectOpcode;
// All subclass charpreds must bind the `index` field.
bindingset[index]
TranslatedArgumentSideEffect() { any() }
override string toString() {
isWrite() and
result = "(write side effect for " + getArgString() + ")"
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag instanceof OnlyInstructionTag and
operandTag instanceof AddressOperandTag and
result = getTranslatedExpr(arg).getResult()
or
not isWrite() and
result = "(read side effect for " + getArgString() + ")"
tag instanceof OnlyInstructionTag and
operandTag instanceof BufferSizeOperandTag and
result =
getTranslatedExpr(call.getArgument(call.getTarget()
.(SideEffectFunction)
.getParameterSizeIndex(index)).getFullyConverted()).getResult()
}
override Call getPrimaryExpr() { result = call }
override CppType getInstructionMemoryOperandType(InstructionTag tag, TypedOperandTag operandTag) {
not isWrite() and
if sideEffectOpcode instanceof BufferAccessOpcode
then
result = getUnknownType() and
tag instanceof OnlyInstructionTag and
operandTag instanceof SideEffectOperandTag
else
exists(Type operandType |
tag instanceof OnlyInstructionTag and
operandType = arg.getType().getUnspecifiedType().(DerivedType).getBaseType() and
operandTag instanceof SideEffectOperandTag
or
tag instanceof OnlyInstructionTag and
operandType = arg.getType().getUnspecifiedType() and
not operandType instanceof DerivedType and
operandTag instanceof SideEffectOperandTag
|
// If the type we select is an incomplete type (e.g. a forward-declared `struct`), there will
// not be a `CppType` that represents that type. In that case, fall back to `UnknownCppType`.
result = getTypeForPRValueOrUnknown(operandType)
)
}
override predicate sortOrder(int group, int indexInGroup) {
indexInGroup = index and
if isWrite() then group = argumentWriteGroup() else group = argumentReadGroup()
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
tag = OnlyInstructionTag() and
result = getTranslatedCallInstruction(call)
}
final override int getInstructionIndex(InstructionTag tag) {
@@ -437,199 +577,11 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
* Gets the `TranslatedFunction` containing this expression.
*/
final TranslatedFunction getEnclosingFunction() {
result = getTranslatedFunction(call.getEnclosingFunction())
result = getTranslatedFunction(arg.getEnclosingFunction())
}
final override predicate sideEffectInstruction(Opcode opcode, CppType type) {
opcode = sideEffectOpcode and
(
isWrite() and
(
opcode instanceof BufferAccessOpcode and
type = getUnknownType()
or
not opcode instanceof BufferAccessOpcode and
exists(Type indirectionType | indirectionType = getIndirectionType() |
if indirectionType instanceof VoidType
then type = getUnknownType()
else type = getTypeForPRValueOrUnknown(indirectionType)
)
)
or
not isWrite() and
type = getVoidType()
)
}
final override CppType getInstructionMemoryOperandType(
InstructionTag tag, TypedOperandTag operandTag
) {
not isWrite() and
if sideEffectOpcode instanceof BufferAccessOpcode
then
result = getUnknownType() and
tag instanceof OnlyInstructionTag and
operandTag instanceof SideEffectOperandTag
else
exists(Type operandType |
tag instanceof OnlyInstructionTag and
operandType = getIndirectionType() and
operandTag instanceof SideEffectOperandTag
|
// If the type we select is an incomplete type (e.g. a forward-declared `struct`), there will
// not be a `CppType` that represents that type. In that case, fall back to `UnknownCppType`.
result = getTypeForPRValueOrUnknown(operandType)
)
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag instanceof OnlyInstructionTag and
operandTag instanceof AddressOperandTag and
result = getArgInstruction()
or
tag instanceof OnlyInstructionTag and
operandTag instanceof BufferSizeOperandTag and
result =
getTranslatedExpr(call.getArgument(call.getTarget()
.(SideEffectFunction)
.getParameterSizeIndex(index)).getFullyConverted()).getResult()
}
/** Holds if this side effect is a write side effect, rather than a read side effect. */
final predicate isWrite() { sideEffectOpcode instanceof WriteSideEffectOpcode }
/** Gets a text representation of the argument. */
abstract string getArgString();
/** Gets the `Instruction` whose result is the value of the argument. */
abstract Instruction getArgInstruction();
/** Gets the type pointed to by the argument. */
abstract Type getIndirectionType();
}
/**
* The IR translation of an argument side effect where the argument has an `Expr` object in the AST.
*
* This generally applies to all positional arguments, as well as qualifier (`this`) arguments for
* calls other than constructor calls.
*/
class TranslatedArgumentExprSideEffect extends TranslatedArgumentSideEffect,
TTranslatedArgumentExprSideEffect {
Expr arg;
TranslatedArgumentExprSideEffect() {
this = TTranslatedArgumentExprSideEffect(call, arg, index, sideEffectOpcode)
}
final override Locatable getAST() { result = arg }
final override Type getIndirectionType() {
result = arg.getUnspecifiedType().(DerivedType).getBaseType()
or
// Sometimes the qualifier type gets the type of the class itself, rather than a pointer to the
// class.
index = -1 and
not arg.getUnspecifiedType() instanceof DerivedType and
result = arg.getUnspecifiedType()
}
final override string getArgString() { result = arg.toString() }
final override Instruction getArgInstruction() { result = getTranslatedExpr(arg).getResult() }
}
/**
* The IR translation of an argument side effect for `*this` on a call, where there is no `Expr`
* object that represents the `this` argument.
*
* The applies only to constructor calls, as the AST has explioit qualifier `Expr`s for all other
* calls to non-static member functions.
*/
class TranslatedStructorQualifierSideEffect extends TranslatedArgumentSideEffect,
TTranslatedStructorQualifierSideEffect {
TranslatedStructorQualifierSideEffect() {
this = TTranslatedStructorQualifierSideEffect(call, sideEffectOpcode) and
index = -1
}
final override Locatable getAST() { result = call }
final override Type getIndirectionType() { result = call.getTarget().getDeclaringType() }
final override string getArgString() { result = "this" }
final override Instruction getArgInstruction() {
exists(TranslatedStructorCall structorCall |
structorCall.getExpr() = call and
result = structorCall.getQualifierResult()
)
}
}
/** The IR translation of the non-argument-specific side effect of a call. */
class TranslatedCallSideEffect extends TranslatedSideEffect, TTranslatedCallSideEffect {
Expr expr;
SideEffectOpcode sideEffectOpcode;
TranslatedCallSideEffect() { this = TTranslatedCallSideEffect(expr, sideEffectOpcode) }
override Locatable getAST() { result = expr }
override Expr getPrimaryExpr() { result = expr }
override predicate sortOrder(int group, int indexInGroup) {
group = callSideEffectGroup() and indexInGroup = 0
}
override string toString() { result = "(call side effect for '" + expr.toString() + "')" }
override predicate sideEffectInstruction(Opcode opcode, CppType type) {
opcode = sideEffectOpcode and
(
opcode instanceof Opcode::CallSideEffect and
type = getUnknownType()
or
opcode instanceof Opcode::CallReadSideEffect and
type = getVoidType()
)
}
override CppType getInstructionMemoryOperandType(InstructionTag tag, TypedOperandTag operandTag) {
tag instanceof OnlyInstructionTag and
operandTag instanceof SideEffectOperandTag and
result = getUnknownType()
}
}
/**
* The IR translation of the allocation side effect of a call to a memory allocation function.
*
* This side effect provides a definition for the newly-allocated memory.
*/
class TranslatedAllocationSideEffect extends TranslatedSideEffect, TTranslatedAllocationSideEffect {
AllocationExpr expr;
TranslatedAllocationSideEffect() { this = TTranslatedAllocationSideEffect(expr) }
override Locatable getAST() { result = expr }
override Expr getPrimaryExpr() { result = expr }
override predicate sortOrder(int group, int indexInGroup) {
group = initializeAllocationGroup() and indexInGroup = 0
}
override string toString() { result = "(allocation side effect for '" + expr.toString() + "')" }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag = addressOperand() and
result = getPrimaryInstructionForSideEffect(OnlyInstructionTag())
}
override predicate sideEffectInstruction(Opcode opcode, CppType type) {
opcode instanceof Opcode::InitializeDynamicAllocation and
type = getUnknownType()
}
/**
* Gets the `Function` containing this expression.
*/
override Function getFunction() { result = arg.getEnclosingFunction() }
}

View File

@@ -135,20 +135,6 @@ private predicate ignoreExpr(Expr expr) {
ignoreExprAndDescendants(expr)
}
/**
* Holds if the side effects of `expr` should be ignoredf for the purposes of IR generation.
*
* In cases involving `constexpr`, a call can wind up as a constant expression. `ignoreExpr()` will
* not hold for such a call, since we do need to translate the call (as a constant), but we need to
* ignore all of the side effects of that call, since we will not actually be generating a `Call`
* instruction.
*/
private predicate ignoreSideEffects(Expr expr) {
ignoreExpr(expr)
or
isIRConstant(expr)
}
/**
* Holds if `func` contains an AST that cannot be translated into IR. This is mostly used to work
* around extractor bugs. Once the relevant extractor bugs are fixed, this predicate can be removed.
@@ -635,34 +621,32 @@ 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 ignoreSideEffects(expr) } or
// The non-argument-specific side effect of a `Call`
TTranslatedCallSideEffect(Expr expr, SideEffectOpcode opcode) {
not ignoreSideEffects(expr) and
opcode = getCallSideEffectOpcode(expr)
TTranslatedCallSideEffects(Call expr) {
// Exclude allocations such as `malloc` (which happen to also be function calls).
// Both `TranslatedCallSideEffects` and `TranslatedAllocationSideEffects` generate
// the same side effects for its children as they both extend the `TranslatedSideEffects`
// class.
// Note: We can separate allocation side effects and call side effects into two
// translated elements as no call can be both a `ConstructorCall` and an `AllocationExpr`.
not expr instanceof AllocationExpr and
(
exists(TTranslatedArgumentSideEffect(expr, _, _, _)) or
expr instanceof ConstructorCall
)
} or
// The side effects of an allocation, i.e. `new`, `new[]` or `malloc`
TTranslatedAllocationSideEffects(AllocationExpr expr) { not ignoreExpr(expr) } or
// A precise side effect of an argument to a `Call`
TTranslatedArgumentExprSideEffect(Call call, Expr expr, int n, SideEffectOpcode opcode) {
TTranslatedArgumentSideEffect(Call call, Expr expr, int n, SideEffectOpcode opcode) {
not ignoreExpr(expr) and
not ignoreSideEffects(call) and
not ignoreExpr(call) and
(
n >= 0 and expr = call.getArgument(n).getFullyConverted()
or
n = -1 and expr = call.getQualifier().getFullyConverted()
) and
opcode = getASideEffectOpcode(call, n)
} or
// 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 ignoreSideEffects(call) and
// Don't bother with destructor calls for now, since we won't see very many of them in the IR
// until we start injecting implicit destructor calls.
call instanceof ConstructorCall and
opcode = getASideEffectOpcode(call, -1)
} or
// The side effect that initializes newly-allocated memory.
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) }
}
/**
* Gets the index of the first explicitly initialized element in `initList`

View File

@@ -11,14 +11,15 @@ import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.FlowSource
/**
* The standard functions `fgets` and `fgetws`.
* The standard functions `gets` and `fgets`.
*/
private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFunction, AliasFunction,
private class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunction, AliasFunction,
SideEffectFunction, RemoteFlowSourceFunction {
FgetsFunction() {
GetsFunction() {
// gets(str)
// fgets(str, num, stream)
// fgetws(wstr, num, stream)
this.hasGlobalOrStdOrBslName(["fgets", "fgetws"])
this.hasGlobalOrStdOrBslName(["gets", "fgets", "fgetws"])
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
@@ -50,61 +51,20 @@ private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFuncti
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(0) and
description = "String read by " + this.getName()
or
output.isReturnValue() and
description = "String read by " + this.getName()
}
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
not this.hasName("gets") and
bufParam = 0 and
countParam = 1
}
override predicate hasArrayWithUnknownSize(int bufParam) {
this.hasName("gets") and
bufParam = 0
}
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
override predicate hasSocketInput(FunctionInput input) { input.isParameterDeref(2) }
}
/**
* The standard functions `gets`.
*/
private class GetsFunction extends DataFlowFunction, ArrayFunction, AliasFunction,
SideEffectFunction, LocalFlowSourceFunction {
GetsFunction() {
// gets(str)
this.hasGlobalOrStdOrBslName("gets")
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and
output.isReturnValue()
}
override predicate parameterNeverEscapes(int index) { none() }
override predicate parameterEscapesOnlyViaReturn(int index) { index = 0 }
override predicate parameterIsAlwaysReturned(int index) { index = 0 }
override predicate hasOnlySpecificReadSideEffects() { any() }
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
i = 0 and
buffer = true and
mustWrite = true
}
override predicate hasLocalFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(0) and
description = "String read by " + this.getName()
or
output.isReturnValue() and
description = "String read by " + this.getName()
}
override predicate hasArrayWithUnknownSize(int bufParam) { bufParam = 0 }
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
override predicate hasSocketInput(FunctionInput input) { input.isParameter(2) }
}

View File

@@ -1,10 +1,7 @@
/*
* Support for tracking tainted data through the program. This is an alias for
* `semmle.code.cpp.ir.dataflow.DefaultTaintTracking` provided for backwards
* compatibility.
* Support for tracking tainted data through the program.
*
* Prefer to use `semmle.code.cpp.dataflow.TaintTracking` or
* `semmle.code.cpp.ir.dataflow.TaintTracking` when designing new queries.
* Prefer to use `semmle.code.cpp.dataflow.TaintTracking` when designing new queries.
*/
import semmle.code.cpp.ir.dataflow.DefaultTaintTracking

View File

@@ -6,22 +6,122 @@
*/
class Person extends string {
Person() {
this =
[
"Ronil", "Dina", "Ravi", "Bruce", "Jo", "Aida", "Esme", "Charlie", "Fred", "Meera", "Maya",
"Chad", "Tiana", "Laura", "George", "Will", "Mary", "Almira", "Susannah", "Rhoda",
"Cynthia", "Eunice", "Olive", "Virginia", "Angeline", "Helen", "Cornelia", "Harriet",
"Mahala", "Abby", "Margaret", "Deb", "Minerva", "Severus", "Lavina", "Adeline", "Cath",
"Elisa", "Lucretia", "Anne", "Eleanor", "Joanna", "Adam", "Agnes", "Rosanna", "Clara",
"Melissa", "Amy", "Isabel", "Jemima", "Cordelia", "Melinda", "Delila", "Jeremiah", "Elijah",
"Hester", "Walter", "Oliver", "Hugh", "Aaron", "Reuben", "Eli", "Amos", "Augustus",
"Theodore", "Ira", "Timothy", "Cyrus", "Horace", "Simon", "Asa", "Frank", "Nelson",
"Leonard", "Harrison", "Anthony", "Louis", "Milton", "Noah", "Cornelius", "Abdul", "Warren",
"Harvey", "Dennis", "Wesley", "Sylvester", "Gilbert", "Sullivan", "Edmund", "Wilson",
"Perry", "Matthew", "Simba", "Nala", "Rafiki", "Shenzi", "Ernest", "Gertrude", "Oscar",
"Lilian", "Raymond", "Elgar", "Elmer", "Herbert", "Maude", "Mae", "Otto", "Edwin",
"Ophelia", "Parsley", "Sage", "Rosemary", "Thyme", "Garfunkel", "King Basil", "Stephen"
]
this = "Ronil" or
this = "Dina" or
this = "Ravi" or
this = "Bruce" or
this = "Jo" or
this = "Aida" or
this = "Esme" or
this = "Charlie" or
this = "Fred" or
this = "Meera" or
this = "Maya" or
this = "Chad" or
this = "Tiana" or
this = "Laura" or
this = "George" or
this = "Will" or
this = "Mary" or
this = "Almira" or
this = "Susannah" or
this = "Rhoda" or
this = "Cynthia" or
this = "Eunice" or
this = "Olive" or
this = "Virginia" or
this = "Angeline" or
this = "Helen" or
this = "Cornelia" or
this = "Harriet" or
this = "Mahala" or
this = "Abby" or
this = "Margaret" or
this = "Deb" or
this = "Minerva" or
this = "Severus" or
this = "Lavina" or
this = "Adeline" or
this = "Cath" or
this = "Elisa" or
this = "Lucretia" or
this = "Anne" or
this = "Eleanor" or
this = "Joanna" or
this = "Adam" or
this = "Agnes" or
this = "Rosanna" or
this = "Clara" or
this = "Melissa" or
this = "Amy" or
this = "Isabel" or
this = "Jemima" or
this = "Cordelia" or
this = "Melinda" or
this = "Delila" or
this = "Jeremiah" or
this = "Elijah" or
this = "Hester" or
this = "Walter" or
this = "Oliver" or
this = "Hugh" or
this = "Aaron" or
this = "Reuben" or
this = "Eli" or
this = "Amos" or
this = "Augustus" or
this = "Theodore" or
this = "Ira" or
this = "Timothy" or
this = "Cyrus" or
this = "Horace" or
this = "Simon" or
this = "Asa" or
this = "Frank" or
this = "Nelson" or
this = "Leonard" or
this = "Harrison" or
this = "Anthony" or
this = "Louis" or
this = "Milton" or
this = "Noah" or
this = "Cornelius" or
this = "Abdul" or
this = "Warren" or
this = "Harvey" or
this = "Dennis" or
this = "Wesley" or
this = "Sylvester" or
this = "Gilbert" or
this = "Sullivan" or
this = "Edmund" or
this = "Wilson" or
this = "Perry" or
this = "Matthew" or
this = "Simba" or
this = "Nala" or
this = "Rafiki" or
this = "Shenzi" or
this = "Ernest" or
this = "Gertrude" or
this = "Oscar" or
this = "Lilian" or
this = "Raymond" or
this = "Elgar" or
this = "Elmer" or
this = "Herbert" or
this = "Maude" or
this = "Mae" or
this = "Otto" or
this = "Edwin" or
this = "Ophelia" or
this = "Parsley" or
this = "Sage" or
this = "Rosemary" or
this = "Thyme" or
this = "Garfunkel" or
this = "King Basil" or
this = "Stephen"
}
/** Gets the hair color of the person. If the person is bald, there is no result. */
@@ -836,12 +936,25 @@ class Person extends string {
/** Holds if the person is deceased. */
predicate isDeceased() {
this =
[
"Ernest", "Gertrude", "Oscar", "Lilian", "Edwin", "Raymond", "Elgar", "Elmer", "Herbert",
"Maude", "Mae", "Otto", "Ophelia", "Parsley", "Sage", "Rosemary", "Thyme", "Garfunkel",
"King Basil"
]
this = "Ernest" or
this = "Gertrude" or
this = "Oscar" or
this = "Lilian" or
this = "Edwin" or
this = "Raymond" or
this = "Elgar" or
this = "Elmer" or
this = "Herbert" or
this = "Maude" or
this = "Mae" or
this = "Otto" or
this = "Ophelia" or
this = "Parsley" or
this = "Sage" or
this = "Rosemary" or
this = "Thyme" or
this = "Garfunkel" or
this = "King Basil"
}
/** Gets a parent of the person (alive or deceased). */
@@ -1082,7 +1195,12 @@ class Person extends string {
}
/** Holds if the person is allowed in the region. Initially, all villagers are allowed in every region. */
predicate isAllowedIn(string region) { region = ["north", "south", "east", "west"] }
predicate isAllowedIn(string region) {
region = "north" or
region = "south" or
region = "east" or
region = "west"
}
}
/** Returns a parent of the person. */

View File

@@ -18,7 +18,6 @@ where
not lv1.isCompilerGenerated() and
not lv2.isCompilerGenerated() and
not lv1.getParentScope().(BlockStmt).isInMacroExpansion() and
not lv2.getParentScope().(BlockStmt).isInMacroExpansion() and
not lv1.getName() = "(unnamed local variable)"
not lv2.getParentScope().(BlockStmt).isInMacroExpansion()
select lv1, "Variable " + lv1.getName() + " hides another variable of the same name (on $@).", lv2,
"line " + lv2.getLocation().getStartLine().toString()

View File

@@ -12,33 +12,23 @@
*/
import cpp
import semmle.code.cpp.security.BufferWrite as BufferWrite
import semmle.code.cpp.security.BufferWrite
import semmle.code.cpp.security.TaintTracking
import semmle.code.cpp.security.SensitiveExprs
import semmle.code.cpp.security.FlowSources
import semmle.code.cpp.ir.dataflow.TaintTracking
import DataFlow::PathGraph
import TaintedWithPath
/**
* Taint flow from user input to a buffer write.
*/
class ToBufferConfiguration extends TaintTracking::Configuration {
ToBufferConfiguration() { this = "ToBufferConfiguration" }
override predicate isSource(DataFlow::Node source) { source instanceof FlowSource }
override predicate isSink(DataFlow::Node sink) {
exists(BufferWrite::BufferWrite w | w.getASource() = sink.asExpr())
}
class Configuration extends TaintTrackingConfiguration {
override predicate isSink(Element tainted) { exists(BufferWrite w | w.getASource() = tainted) }
}
from
ToBufferConfiguration config, BufferWrite::BufferWrite w, DataFlow::PathNode sourceNode,
DataFlow::PathNode sinkNode, FlowSource source, SensitiveExpr dest
BufferWrite w, Expr taintedArg, Expr taintSource, PathNode sourceNode, PathNode sinkNode,
string taintCause, SensitiveExpr dest
where
config.hasFlowPath(sourceNode, sinkNode) and
sourceNode.getNode() = source and
w.getASource() = sinkNode.getNode().asExpr() and
taintedWithPath(taintSource, taintedArg, sourceNode, sinkNode) and
isUserInput(taintSource, taintCause) and
w.getASource() = taintedArg and
dest = w.getDest()
select w, sourceNode, sinkNode,
"This write into buffer '" + dest.toString() + "' may contain unencrypted data from $@", source,
"user input (" + source.getSourceType() + ")"
"This write into buffer '" + dest.toString() + "' may contain unencrypted data from $@",
taintSource, "user input (" + taintCause + ")"

View File

@@ -65,7 +65,6 @@ where
midNode.getNode().asExpr() = mid and
mid = w.getASource() and
dest = w.getDest() and
not dest.(VariableAccess).getTarget().getName() = ["stdin", "stdout", "stderr"] and // exclude calls with standard streams
not isFileName(globalValueNumber(source)) and // file names are not passwords
not exists(string convChar | convChar = w.getSourceConvChar(mid) | not convChar = ["s", "S"]) // ignore things written with other conversion characters
select w, sourceNode, midNode,

View File

@@ -27,7 +27,6 @@ class SensitiveNode extends DataFlow::Node {
this.asExpr() = any(SensitiveVariable sv).getInitializer().getExpr() or
this.asExpr().(VariableAccess).getTarget() =
any(SensitiveVariable sv).(GlobalOrNamespaceVariable) or
this.asExpr().(VariableAccess).getTarget() = any(SensitiveVariable v | v instanceof Field) or
this.asUninitialized() instanceof SensitiveVariable or
this.asParameter() instanceof SensitiveVariable or
this.asExpr().(FunctionCall).getTarget() instanceof SensitiveFunction
@@ -59,10 +58,7 @@ class Send extends SendRecv instanceof RemoteFlowSinkFunction {
call.getTarget() = this and
exists(FunctionInput input, int arg |
super.hasSocketInput(input) and
(
input.isParameter(arg) or
input.isParameterDeref(arg)
) and
input.isParameter(arg) and
result = call.getArgument(arg)
)
}
@@ -85,10 +81,7 @@ class Recv extends SendRecv instanceof RemoteFlowSourceFunction {
call.getTarget() = this and
exists(FunctionInput input, int arg |
super.hasSocketInput(input) and
(
input.isParameter(arg) or
input.isParameterDeref(arg)
) and
input.isParameter(arg) and
result = call.getArgument(arg)
)
}

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The "Cleartext transmission of sensitive information" (`cpp/cleartext-transmission`) query now finds more results, where a password is stored in a struct field or class member variable.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The `cpp/cleartext-storage-buffer` query has been updated to use the `semmle.code.cpp.dataflow.TaintTracking` library.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Fix an issue with the `cpp/declaration-hides-variable` query where it would report variables that are unnamed in a database.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The `cpp/cleartext-storage-file` query has been improved, removing false positives where data is written to a standard output stream.

View File

@@ -1,9 +0,0 @@
void test(){
int a = 8;
int b = 9;
//Useless NonEquals
if(a==8 && a != 7) {}
while(a==8 && a!=7){}
}

View File

@@ -1,18 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Comparison operations like <code>a==8 &amp;&amp; a!=7</code> contain a useless part : the non-equal part. This rule finds tests of this kind within an <code>if</code> or a <code>while</code> statement</p>
</overview>
<recommendation>
<p>Remove the useless comparisons</p>
</recommendation>
<example>
<sample src="UselessTest.cpp" />
</example>
</qhelp>

View File

@@ -1,43 +0,0 @@
/**
* @name Useless Test
* @description A boolean condition that is guaranteed to never be evaluated should be deleted.
* @kind problem
* @problem.severity warning
* @id cpp/uselesstest
* @tags reliability
* readability
*/
import cpp
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
predicate sameExpr(Expr e1, Expr e2) { globalValueNumber(e1).getAnExpr() = e2 }
Element nearestParent(Expr e) {
if
e.getParent().(Expr).getConversion*() instanceof ParenthesisExpr or
e.getParent() instanceof IfStmt or
e.getParent() instanceof WhileStmt
then result = e.getParent()
else result = nearestParent(e.getParent())
}
from LogicalAndExpr b, EQExpr eq, NEExpr ne
where
(
b.getAChild*() = eq and
b.getAChild*() = ne and
eq.getParent() instanceof LogicalAndExpr and
ne.getParent() instanceof LogicalAndExpr
) and
(
eq.getLeftOperand() instanceof VariableAccess and ne.getLeftOperand() instanceof VariableAccess
or
eq.getLeftOperand() instanceof PointerDereferenceExpr and
ne.getLeftOperand() instanceof PointerDereferenceExpr
) and
eq.getRightOperand() instanceof Literal and
ne.getRightOperand() instanceof Literal and
nearestParent(eq) = nearestParent(ne) and
sameExpr(eq.getLeftOperand(), ne.getLeftOperand())
select ne, "Useless Test"

View File

@@ -1,8 +1,6 @@
name: codeql/cpp-queries
version: 0.0.8-dev
groups:
- cpp
- queries
groups: cpp
dependencies:
codeql/cpp-all: "*"
codeql/suite-helpers: "*"

View File

@@ -93,7 +93,7 @@
private import InlineExpectationsTestPrivate
/**
* The base class for tests with inline expectations. The test extends this class to provide the actual
* Base class for tests with inline expectations. The test extends this class to provide the actual
* results of the query, which are then compared with the expected results in comments to produce a
* list of failure messages that point out where the actual results differ from the expected
* results.

View File

@@ -2665,7 +2665,7 @@
| ir.cpp:617:15:617:21 | Unary | r617_4 |
| ir.cpp:617:15:617:22 | CallTarget | func:r617_3 |
| ir.cpp:617:15:617:22 | ChiPartial | partial:m617_7 |
| ir.cpp:617:15:617:22 | ChiPartial | partial:m617_10 |
| ir.cpp:617:15:617:22 | ChiPartial | partial:m617_9 |
| ir.cpp:617:15:617:22 | ChiTotal | total:m616_6 |
| ir.cpp:617:15:617:22 | ChiTotal | total:m617_2 |
| ir.cpp:617:15:617:22 | SideEffect | ~m616_6 |
@@ -2680,7 +2680,7 @@
| ir.cpp:619:12:619:13 | Arg(this) | this:r619_1 |
| ir.cpp:619:16:619:30 | CallTarget | func:r619_3 |
| ir.cpp:619:16:619:30 | ChiPartial | partial:m619_7 |
| ir.cpp:619:16:619:30 | ChiPartial | partial:m619_10 |
| ir.cpp:619:16:619:30 | ChiPartial | partial:m619_9 |
| ir.cpp:619:16:619:30 | ChiTotal | total:m618_5 |
| ir.cpp:619:16:619:30 | ChiTotal | total:m619_2 |
| ir.cpp:619:16:619:30 | SideEffect | ~m618_5 |
@@ -2906,7 +2906,7 @@
| ir.cpp:658:5:658:5 | ChiPartial | partial:m658_3 |
| ir.cpp:658:5:658:5 | ChiTotal | total:m658_2 |
| ir.cpp:658:5:658:5 | Load | m658_6 |
| ir.cpp:658:5:658:5 | SideEffect | m662_10 |
| ir.cpp:658:5:658:5 | SideEffect | m662_9 |
| ir.cpp:658:5:658:5 | SideEffect | ~m662_7 |
| ir.cpp:658:5:658:5 | Unary | m658_6 |
| ir.cpp:658:5:658:5 | Unary | m658_6 |
@@ -2929,7 +2929,7 @@
| ir.cpp:662:9:662:19 | Arg(this) | this:r662_1 |
| ir.cpp:662:9:662:19 | CallTarget | func:r662_2 |
| ir.cpp:662:9:662:19 | ChiPartial | partial:m662_6 |
| ir.cpp:662:9:662:19 | ChiPartial | partial:m662_9 |
| ir.cpp:662:9:662:19 | ChiPartial | partial:m662_8 |
| ir.cpp:662:9:662:19 | ChiTotal | total:m661_4 |
| ir.cpp:662:9:662:19 | ChiTotal | total:m663_5 |
| ir.cpp:662:9:662:19 | SideEffect | ~m663_5 |
@@ -3147,10 +3147,10 @@
| ir.cpp:736:5:736:19 | Arg(this) | this:r736_1 |
| ir.cpp:736:5:736:19 | CallTarget | func:r736_3 |
| ir.cpp:736:5:736:19 | ChiPartial | partial:m736_7 |
| ir.cpp:736:5:736:19 | ChiPartial | partial:m736_10 |
| ir.cpp:736:5:736:19 | ChiPartial | partial:m736_9 |
| ir.cpp:736:5:736:19 | ChiTotal | total:m724_4 |
| ir.cpp:736:5:736:19 | ChiTotal | total:m736_2 |
| ir.cpp:736:5:736:19 | Load | m736_11 |
| ir.cpp:736:5:736:19 | Load | m736_10 |
| ir.cpp:736:5:736:19 | SideEffect | ~m724_4 |
| ir.cpp:736:18:736:18 | Address | &:r736_4 |
| ir.cpp:736:18:736:18 | Address | &:r736_5 |
@@ -3673,11 +3673,11 @@
| ir.cpp:809:7:809:13 | Arg(this) | this:r809_3 |
| ir.cpp:809:7:809:13 | CallTarget | func:r809_5 |
| ir.cpp:809:7:809:13 | ChiPartial | partial:m809_10 |
| ir.cpp:809:7:809:13 | ChiPartial | partial:m809_13 |
| ir.cpp:809:7:809:13 | ChiPartial | partial:m809_12 |
| ir.cpp:809:7:809:13 | ChiTotal | total:m808_8 |
| ir.cpp:809:7:809:13 | ChiTotal | total:m809_4 |
| ir.cpp:809:7:809:13 | SideEffect | ~m808_8 |
| ir.cpp:809:7:809:13 | SideEffect | ~m809_14 |
| ir.cpp:809:7:809:13 | SideEffect | ~m809_13 |
| ir.cpp:809:7:809:13 | Unary | r809_3 |
| ir.cpp:809:7:809:13 | Unary | r809_15 |
| ir.cpp:809:13:809:13 | Address | &:r809_8 |
@@ -3703,11 +3703,11 @@
| ir.cpp:810:7:810:26 | Arg(this) | this:r810_3 |
| ir.cpp:810:7:810:26 | CallTarget | func:r810_5 |
| ir.cpp:810:7:810:26 | ChiPartial | partial:m810_10 |
| ir.cpp:810:7:810:26 | ChiPartial | partial:m810_13 |
| ir.cpp:810:7:810:26 | ChiPartial | partial:m810_12 |
| ir.cpp:810:7:810:26 | ChiTotal | total:m809_19 |
| ir.cpp:810:7:810:26 | ChiTotal | total:m810_4 |
| ir.cpp:810:7:810:26 | SideEffect | ~m809_19 |
| ir.cpp:810:7:810:26 | SideEffect | ~m810_14 |
| ir.cpp:810:7:810:26 | SideEffect | ~m810_13 |
| ir.cpp:810:7:810:26 | Unary | r810_3 |
| ir.cpp:810:7:810:26 | Unary | r810_15 |
| ir.cpp:810:25:810:25 | Address | &:r810_8 |
@@ -3819,11 +3819,11 @@
| ir.cpp:823:7:823:13 | Arg(this) | this:r823_3 |
| ir.cpp:823:7:823:13 | CallTarget | func:r823_5 |
| ir.cpp:823:7:823:13 | ChiPartial | partial:m823_11 |
| ir.cpp:823:7:823:13 | ChiPartial | partial:m823_14 |
| ir.cpp:823:7:823:13 | ChiPartial | partial:m823_13 |
| ir.cpp:823:7:823:13 | ChiTotal | total:m822_9 |
| ir.cpp:823:7:823:13 | ChiTotal | total:m823_4 |
| ir.cpp:823:7:823:13 | SideEffect | ~m822_9 |
| ir.cpp:823:7:823:13 | SideEffect | ~m823_15 |
| ir.cpp:823:7:823:13 | SideEffect | ~m823_14 |
| ir.cpp:823:7:823:13 | Unary | r823_3 |
| ir.cpp:823:7:823:13 | Unary | r823_16 |
| ir.cpp:823:13:823:13 | Address | &:r823_9 |
@@ -3850,11 +3850,11 @@
| ir.cpp:824:7:824:26 | Arg(this) | this:r824_3 |
| ir.cpp:824:7:824:26 | CallTarget | func:r824_5 |
| ir.cpp:824:7:824:26 | ChiPartial | partial:m824_11 |
| ir.cpp:824:7:824:26 | ChiPartial | partial:m824_14 |
| ir.cpp:824:7:824:26 | ChiPartial | partial:m824_13 |
| ir.cpp:824:7:824:26 | ChiTotal | total:m823_20 |
| ir.cpp:824:7:824:26 | ChiTotal | total:m824_4 |
| ir.cpp:824:7:824:26 | SideEffect | ~m823_20 |
| ir.cpp:824:7:824:26 | SideEffect | ~m824_15 |
| ir.cpp:824:7:824:26 | SideEffect | ~m824_14 |
| ir.cpp:824:7:824:26 | Unary | r824_3 |
| ir.cpp:824:7:824:26 | Unary | r824_16 |
| ir.cpp:824:25:824:25 | Address | &:r824_9 |
@@ -4059,11 +4059,11 @@
| ir.cpp:867:1:867:14 | ChiPartial | partial:m867_3 |
| ir.cpp:867:1:867:14 | ChiTotal | total:m867_2 |
| ir.cpp:867:1:867:14 | Load | m867_6 |
| ir.cpp:867:1:867:14 | SideEffect | m868_9 |
| ir.cpp:867:1:867:14 | SideEffect | m868_8 |
| ir.cpp:867:1:867:14 | SideEffect | ~m868_6 |
| ir.cpp:868:3:868:12 | CallTarget | func:r868_1 |
| ir.cpp:868:3:868:12 | ChiPartial | partial:m868_5 |
| ir.cpp:868:3:868:12 | ChiPartial | partial:m868_8 |
| ir.cpp:868:3:868:12 | ChiPartial | partial:m868_7 |
| ir.cpp:868:3:868:12 | ChiTotal | total:m867_4 |
| ir.cpp:868:3:868:12 | ChiTotal | total:m867_8 |
| ir.cpp:868:3:868:12 | SideEffect | ~m867_4 |
@@ -4310,7 +4310,7 @@
| ir.cpp:954:3:954:27 | CallTarget | func:r954_9 |
| ir.cpp:954:3:954:27 | ChiPartial | partial:m954_5 |
| ir.cpp:954:3:954:27 | ChiPartial | partial:m954_13 |
| ir.cpp:954:3:954:27 | ChiPartial | partial:m954_16 |
| ir.cpp:954:3:954:27 | ChiPartial | partial:m954_15 |
| ir.cpp:954:3:954:27 | ChiTotal | total:m953_11 |
| ir.cpp:954:3:954:27 | ChiTotal | total:m954_6 |
| ir.cpp:954:3:954:27 | ChiTotal | total:m954_7 |
@@ -5386,10 +5386,10 @@
| ir.cpp:1154:5:1154:19 | Arg(this) | this:r1154_1 |
| ir.cpp:1154:5:1154:19 | CallTarget | func:r1154_3 |
| ir.cpp:1154:5:1154:19 | ChiPartial | partial:m1154_7 |
| ir.cpp:1154:5:1154:19 | ChiPartial | partial:m1154_10 |
| ir.cpp:1154:5:1154:19 | ChiPartial | partial:m1154_9 |
| ir.cpp:1154:5:1154:19 | ChiTotal | total:m1142_4 |
| ir.cpp:1154:5:1154:19 | ChiTotal | total:m1154_2 |
| ir.cpp:1154:5:1154:19 | Load | m1154_11 |
| ir.cpp:1154:5:1154:19 | Load | m1154_10 |
| ir.cpp:1154:5:1154:19 | SideEffect | ~m1142_4 |
| ir.cpp:1154:18:1154:18 | Address | &:r1154_4 |
| ir.cpp:1154:18:1154:18 | Address | &:r1154_5 |
@@ -5496,14 +5496,14 @@
| ir.cpp:1178:8:1178:23 | Address | &:r1178_5 |
| ir.cpp:1178:8:1178:23 | ChiPartial | partial:m1178_3 |
| ir.cpp:1178:8:1178:23 | ChiTotal | total:m1178_2 |
| ir.cpp:1178:8:1178:23 | Load | m1179_11 |
| ir.cpp:1178:8:1178:23 | Load | m1179_10 |
| ir.cpp:1178:8:1178:23 | SideEffect | ~m1179_8 |
| ir.cpp:1179:3:1179:23 | Address | &:r1179_1 |
| ir.cpp:1179:3:1179:23 | Address | &:r1179_1 |
| ir.cpp:1179:3:1179:23 | Arg(this) | this:r1179_1 |
| ir.cpp:1179:3:1179:23 | CallTarget | func:r1179_3 |
| ir.cpp:1179:3:1179:23 | ChiPartial | partial:m1179_7 |
| ir.cpp:1179:3:1179:23 | ChiPartial | partial:m1179_10 |
| ir.cpp:1179:3:1179:23 | ChiPartial | partial:m1179_9 |
| ir.cpp:1179:3:1179:23 | ChiTotal | total:m1178_4 |
| ir.cpp:1179:3:1179:23 | ChiTotal | total:m1179_2 |
| ir.cpp:1179:3:1179:23 | SideEffect | ~m1178_4 |
@@ -5651,7 +5651,7 @@
| ir.cpp:1242:19:1242:19 | Address | &:r1242_5 |
| ir.cpp:1242:19:1242:19 | Arg(this) | this:r1242_5 |
| ir.cpp:1242:19:1242:19 | ChiPartial | partial:m1242_16 |
| ir.cpp:1242:19:1242:19 | ChiTotal | total:m1242_14 |
| ir.cpp:1242:19:1242:19 | ChiTotal | total:m1242_13 |
| ir.cpp:1242:19:1242:19 | Condition | r1242_3 |
| ir.cpp:1242:19:1242:19 | Load | ~m1242_1 |
| ir.cpp:1242:19:1242:19 | Phi | from 0:~m1240_4 |
@@ -5659,7 +5659,7 @@
| ir.cpp:1242:19:1242:19 | StoreValue | r1242_15 |
| ir.cpp:1242:20:1242:29 | CallTarget | func:r1242_6 |
| ir.cpp:1242:20:1242:29 | ChiPartial | partial:m1242_10 |
| ir.cpp:1242:20:1242:29 | ChiPartial | partial:m1242_13 |
| ir.cpp:1242:20:1242:29 | ChiPartial | partial:m1242_12 |
| ir.cpp:1242:20:1242:29 | ChiTotal | total:m1242_1 |
| ir.cpp:1242:20:1242:29 | ChiTotal | total:m1242_11 |
| ir.cpp:1242:20:1242:29 | SideEffect | ~m1242_1 |
@@ -5672,7 +5672,7 @@
| ir.cpp:1243:19:1243:19 | Address | &:r1243_5 |
| ir.cpp:1243:19:1243:19 | Arg(this) | this:r1243_5 |
| ir.cpp:1243:19:1243:19 | ChiPartial | partial:m1243_16 |
| ir.cpp:1243:19:1243:19 | ChiTotal | total:m1243_14 |
| ir.cpp:1243:19:1243:19 | ChiTotal | total:m1243_13 |
| ir.cpp:1243:19:1243:19 | Condition | r1243_3 |
| ir.cpp:1243:19:1243:19 | Load | ~m1243_1 |
| ir.cpp:1243:19:1243:19 | Phi | from 2:~m1242_1 |
@@ -5680,7 +5680,7 @@
| ir.cpp:1243:19:1243:19 | StoreValue | r1243_15 |
| ir.cpp:1243:20:1243:28 | CallTarget | func:r1243_6 |
| ir.cpp:1243:20:1243:28 | ChiPartial | partial:m1243_10 |
| ir.cpp:1243:20:1243:28 | ChiPartial | partial:m1243_13 |
| ir.cpp:1243:20:1243:28 | ChiPartial | partial:m1243_12 |
| ir.cpp:1243:20:1243:28 | ChiTotal | total:m1243_1 |
| ir.cpp:1243:20:1243:28 | ChiTotal | total:m1243_11 |
| ir.cpp:1243:20:1243:28 | SideEffect | ~m1243_1 |
@@ -6200,12 +6200,12 @@
| ir.cpp:1370:23:1370:27 | Arg(this) | this:r1370_2 |
| ir.cpp:1370:23:1370:27 | CallTarget | func:r1370_4 |
| ir.cpp:1370:23:1370:27 | ChiPartial | partial:m1370_8 |
| ir.cpp:1370:23:1370:27 | ChiPartial | partial:m1370_11 |
| ir.cpp:1370:23:1370:27 | ChiPartial | partial:m1370_10 |
| ir.cpp:1370:23:1370:27 | ChiTotal | total:m1369_7 |
| ir.cpp:1370:23:1370:27 | ChiTotal | total:m1370_3 |
| ir.cpp:1370:23:1370:27 | SideEffect | ~m1365_3 |
| ir.cpp:1370:23:1370:27 | SideEffect | ~m1369_7 |
| ir.cpp:1370:23:1370:27 | SideEffect | ~m1370_12 |
| ir.cpp:1370:23:1370:27 | SideEffect | ~m1370_11 |
| ir.cpp:1370:23:1370:27 | Unary | r1370_2 |
| ir.cpp:1370:23:1370:27 | Unary | r1370_5 |
| ir.cpp:1371:5:1371:15 | CallTarget | func:r1371_1 |
@@ -6221,10 +6221,10 @@
| ir.cpp:1371:17:1371:17 | Arg(this) | this:r1371_2 |
| ir.cpp:1371:17:1371:17 | CallTarget | func:r1371_4 |
| ir.cpp:1371:17:1371:17 | ChiPartial | partial:m1371_9 |
| ir.cpp:1371:17:1371:17 | ChiPartial | partial:m1371_12 |
| ir.cpp:1371:17:1371:17 | ChiPartial | partial:m1371_11 |
| ir.cpp:1371:17:1371:17 | ChiTotal | total:m1370_16 |
| ir.cpp:1371:17:1371:17 | ChiTotal | total:m1371_3 |
| ir.cpp:1371:17:1371:17 | Load | m1371_13 |
| ir.cpp:1371:17:1371:17 | Load | m1371_12 |
| ir.cpp:1371:17:1371:17 | SideEffect | ~m1366_6 |
| ir.cpp:1371:17:1371:17 | SideEffect | ~m1370_16 |
| ir.cpp:1371:17:1371:17 | Unary | r1371_5 |
@@ -6242,10 +6242,10 @@
| ir.cpp:1372:25:1372:29 | Arg(this) | this:r1372_2 |
| ir.cpp:1372:25:1372:29 | CallTarget | func:r1372_4 |
| ir.cpp:1372:25:1372:29 | ChiPartial | partial:m1372_8 |
| ir.cpp:1372:25:1372:29 | ChiPartial | partial:m1372_11 |
| ir.cpp:1372:25:1372:29 | ChiPartial | partial:m1372_10 |
| ir.cpp:1372:25:1372:29 | ChiTotal | total:m1371_17 |
| ir.cpp:1372:25:1372:29 | ChiTotal | total:m1372_3 |
| ir.cpp:1372:25:1372:29 | Load | m1372_12 |
| ir.cpp:1372:25:1372:29 | Load | m1372_11 |
| ir.cpp:1372:25:1372:29 | SideEffect | ~m1365_3 |
| ir.cpp:1372:25:1372:29 | SideEffect | ~m1371_17 |
| ir.cpp:1372:25:1372:29 | Unary | r1372_5 |
@@ -6414,10 +6414,10 @@
| ir.cpp:1396:17:1396:17 | Arg(this) | this:r1396_2 |
| ir.cpp:1396:17:1396:17 | CallTarget | func:r1396_4 |
| ir.cpp:1396:17:1396:17 | ChiPartial | partial:m1396_9 |
| ir.cpp:1396:17:1396:17 | ChiPartial | partial:m1396_12 |
| ir.cpp:1396:17:1396:17 | ChiPartial | partial:m1396_11 |
| ir.cpp:1396:17:1396:17 | ChiTotal | total:m1395_7 |
| ir.cpp:1396:17:1396:17 | ChiTotal | total:m1396_3 |
| ir.cpp:1396:17:1396:17 | Load | m1396_13 |
| ir.cpp:1396:17:1396:17 | Load | m1396_12 |
| ir.cpp:1396:17:1396:17 | SideEffect | ~m1392_6 |
| ir.cpp:1396:17:1396:17 | SideEffect | ~m1395_7 |
| ir.cpp:1396:17:1396:17 | Unary | r1396_5 |
@@ -6741,7 +6741,7 @@
| smart_ptr.cpp:19:20:19:21 | ChiPartial | partial:m19_18 |
| smart_ptr.cpp:19:20:19:21 | ChiTotal | total:m17_8 |
| smart_ptr.cpp:19:20:19:21 | ChiTotal | total:m18_8 |
| smart_ptr.cpp:19:20:19:21 | Load | m19_12 |
| smart_ptr.cpp:19:20:19:21 | Load | m19_11 |
| smart_ptr.cpp:19:20:19:21 | SideEffect | m18_9 |
| smart_ptr.cpp:19:20:19:21 | SideEffect | ~m17_8 |
| smart_ptr.cpp:19:20:19:21 | SideEffect | ~m18_8 |
@@ -6766,7 +6766,7 @@
| smart_ptr.cpp:31:26:31:37 | CallTarget | func:r31_4 |
| smart_ptr.cpp:31:26:31:37 | ChiPartial | partial:m31_9 |
| smart_ptr.cpp:31:26:31:37 | ChiTotal | total:m28_4 |
| smart_ptr.cpp:31:26:31:37 | Load | m31_12 |
| smart_ptr.cpp:31:26:31:37 | Load | m31_11 |
| smart_ptr.cpp:31:26:31:37 | SideEffect | m29_2 |
| smart_ptr.cpp:31:26:31:37 | SideEffect | ~m28_4 |
| smart_ptr.cpp:31:26:31:37 | SideEffect | ~m31_16 |
@@ -6791,7 +6791,7 @@
| smart_ptr.cpp:35:30:35:49 | ChiPartial | partial:m35_18 |
| smart_ptr.cpp:35:30:35:49 | ChiTotal | total:m31_16 |
| smart_ptr.cpp:35:30:35:49 | ChiTotal | total:m35_16 |
| smart_ptr.cpp:35:30:35:49 | Load | m35_12 |
| smart_ptr.cpp:35:30:35:49 | Load | m35_11 |
| smart_ptr.cpp:35:30:35:49 | SideEffect | m33_2 |
| smart_ptr.cpp:35:30:35:49 | SideEffect | ~m31_16 |
| smart_ptr.cpp:35:30:35:49 | SideEffect | ~m35_16 |
@@ -6816,7 +6816,7 @@
| smart_ptr.cpp:39:37:39:51 | ChiPartial | partial:m39_18 |
| smart_ptr.cpp:39:37:39:51 | ChiTotal | total:m35_19 |
| smart_ptr.cpp:39:37:39:51 | ChiTotal | total:m39_16 |
| smart_ptr.cpp:39:37:39:51 | Load | m39_12 |
| smart_ptr.cpp:39:37:39:51 | Load | m39_11 |
| smart_ptr.cpp:39:37:39:51 | SideEffect | m37_2 |
| smart_ptr.cpp:39:37:39:51 | SideEffect | ~m35_19 |
| smart_ptr.cpp:39:37:39:51 | SideEffect | ~m39_16 |
@@ -6841,7 +6841,7 @@
| smart_ptr.cpp:43:37:43:51 | ChiPartial | partial:m43_18 |
| smart_ptr.cpp:43:37:43:51 | ChiTotal | total:m39_19 |
| smart_ptr.cpp:43:37:43:51 | ChiTotal | total:m43_16 |
| smart_ptr.cpp:43:37:43:51 | Load | m43_12 |
| smart_ptr.cpp:43:37:43:51 | Load | m43_11 |
| smart_ptr.cpp:43:37:43:51 | SideEffect | m41_2 |
| smart_ptr.cpp:43:37:43:51 | SideEffect | ~m39_19 |
| smart_ptr.cpp:43:37:43:51 | SideEffect | ~m43_16 |
@@ -6863,7 +6863,7 @@
| smart_ptr.cpp:47:43:47:63 | CallTarget | func:r47_4 |
| smart_ptr.cpp:47:43:47:63 | ChiPartial | partial:m47_9 |
| smart_ptr.cpp:47:43:47:63 | ChiTotal | total:m43_19 |
| smart_ptr.cpp:47:43:47:63 | Load | m47_12 |
| smart_ptr.cpp:47:43:47:63 | Load | m47_11 |
| smart_ptr.cpp:47:43:47:63 | SideEffect | m45_2 |
| smart_ptr.cpp:47:43:47:63 | SideEffect | ~m43_19 |
| smart_ptr.cpp:47:43:47:63 | SideEffect | ~m47_16 |

View File

@@ -3362,8 +3362,8 @@ ir.cpp:
# 617| r617_5(char *) = Convert : r617_4
# 617| v617_6(void) = Call[String] : func:r617_3, this:r617_1, 0:r617_5
# 617| mu617_7(unknown) = ^CallSideEffect : ~m?
# 617| v617_8(void) = ^BufferReadSideEffect[0] : &:r617_5, ~m?
# 617| mu617_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r617_1
# 617| mu617_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r617_1
# 617| v617_9(void) = ^BufferReadSideEffect[0] : &:r617_5, ~m?
# 618| r618_1(glval<String>) = VariableAddress[s3] :
# 618| r618_2(glval<unknown>) = FunctionAddress[ReturnObject] :
# 618| r618_3(String) = Call[ReturnObject] : func:r618_2
@@ -3376,8 +3376,8 @@ ir.cpp:
# 619| r619_5(char *) = Convert : r619_4
# 619| v619_6(void) = Call[String] : func:r619_3, this:r619_1, 0:r619_5
# 619| mu619_7(unknown) = ^CallSideEffect : ~m?
# 619| v619_8(void) = ^BufferReadSideEffect[0] : &:r619_5, ~m?
# 619| mu619_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r619_1
# 619| mu619_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r619_1
# 619| v619_9(void) = ^BufferReadSideEffect[0] : &:r619_5, ~m?
# 620| v620_1(void) = NoOp :
# 615| v615_4(void) = ReturnVoid :
# 615| v615_5(void) = AliasedUse : ~m?
@@ -3628,8 +3628,8 @@ ir.cpp:
# 662| r662_4(char *) = Convert : r662_3
# 662| v662_5(void) = Call[String] : func:r662_2, this:r662_1, 0:r662_4
# 662| mu662_6(unknown) = ^CallSideEffect : ~m?
# 662| v662_7(void) = ^BufferReadSideEffect[0] : &:r662_4, ~m?
# 662| mu662_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r662_1
# 662| mu662_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r662_1
# 662| v662_8(void) = ^BufferReadSideEffect[0] : &:r662_4, ~m?
# 664| v664_1(void) = NoOp :
# 658| v658_8(void) = ReturnIndirection[#this] : &:r658_6, ~m?
# 658| v658_9(void) = ReturnVoid :
@@ -3924,8 +3924,8 @@ ir.cpp:
# 731| r731_15(char *) = Convert : r731_14
# 731| v731_16(void) = Call[String] : func:r731_13, this:r731_11, 0:r731_15
# 731| mu731_17(unknown) = ^CallSideEffect : ~m?
# 731| v731_18(void) = ^BufferReadSideEffect[0] : &:r731_15, ~m?
# 731| mu731_19(String) = ^IndirectMayWriteSideEffect[-1] : &:r731_11
# 731| mu731_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r731_11
# 731| v731_19(void) = ^BufferReadSideEffect[0] : &:r731_15, ~m?
# 731| v731_20(void) = ThrowValue : &:r731_11, ~m?
#-----| Exception -> Block 9
@@ -3952,8 +3952,8 @@ ir.cpp:
# 736| r736_5(char *) = Load[s] : &:r736_4, ~m?
# 736| v736_6(void) = Call[String] : func:r736_3, this:r736_1, 0:r736_5
# 736| mu736_7(unknown) = ^CallSideEffect : ~m?
# 736| v736_8(void) = ^BufferReadSideEffect[0] : &:r736_5, ~m?
# 736| mu736_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r736_1
# 736| mu736_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r736_1
# 736| v736_9(void) = ^BufferReadSideEffect[0] : &:r736_5, ~m?
# 736| v736_10(void) = ThrowValue : &:r736_1, ~m?
#-----| Exception -> Block 2
@@ -4518,8 +4518,8 @@ ir.cpp:
# 809| r809_8(Base &) = CopyValue : r809_7
# 809| v809_9(void) = Call[Base] : func:r809_5, this:r809_3, 0:r809_8
# 809| mu809_10(unknown) = ^CallSideEffect : ~m?
# 809| v809_11(void) = ^BufferReadSideEffect[0] : &:r809_8, ~m?
# 809| mu809_12(Base) = ^IndirectMayWriteSideEffect[-1] : &:r809_3
# 809| mu809_11(Base) = ^IndirectMayWriteSideEffect[-1] : &:r809_3
# 809| v809_12(void) = ^BufferReadSideEffect[0] : &:r809_8, ~m?
# 809| r809_13(glval<Base>) = Convert : r809_3
# 809| r809_14(Base &) = CopyValue : r809_13
# 809| r809_15(Base &) = Call[operator=] : func:r809_2, this:r809_1, 0:r809_14
@@ -4538,8 +4538,8 @@ ir.cpp:
# 810| r810_8(Base &) = CopyValue : r810_7
# 810| v810_9(void) = Call[Base] : func:r810_5, this:r810_3, 0:r810_8
# 810| mu810_10(unknown) = ^CallSideEffect : ~m?
# 810| v810_11(void) = ^BufferReadSideEffect[0] : &:r810_8, ~m?
# 810| mu810_12(Base) = ^IndirectMayWriteSideEffect[-1] : &:r810_3
# 810| mu810_11(Base) = ^IndirectMayWriteSideEffect[-1] : &:r810_3
# 810| v810_12(void) = ^BufferReadSideEffect[0] : &:r810_8, ~m?
# 810| r810_13(glval<Base>) = Convert : r810_3
# 810| r810_14(Base &) = CopyValue : r810_13
# 810| r810_15(Base &) = Call[operator=] : func:r810_2, this:r810_1, 0:r810_14
@@ -4630,8 +4630,8 @@ ir.cpp:
# 823| r823_9(Base &) = CopyValue : r823_8
# 823| v823_10(void) = Call[Base] : func:r823_5, this:r823_3, 0:r823_9
# 823| mu823_11(unknown) = ^CallSideEffect : ~m?
# 823| v823_12(void) = ^BufferReadSideEffect[0] : &:r823_9, ~m?
# 823| mu823_13(Base) = ^IndirectMayWriteSideEffect[-1] : &:r823_3
# 823| mu823_12(Base) = ^IndirectMayWriteSideEffect[-1] : &:r823_3
# 823| v823_13(void) = ^BufferReadSideEffect[0] : &:r823_9, ~m?
# 823| r823_14(glval<Base>) = Convert : r823_3
# 823| r823_15(Base &) = CopyValue : r823_14
# 823| r823_16(Base &) = Call[operator=] : func:r823_2, this:r823_1, 0:r823_15
@@ -4651,8 +4651,8 @@ ir.cpp:
# 824| r824_9(Base &) = CopyValue : r824_8
# 824| v824_10(void) = Call[Base] : func:r824_5, this:r824_3, 0:r824_9
# 824| mu824_11(unknown) = ^CallSideEffect : ~m?
# 824| v824_12(void) = ^BufferReadSideEffect[0] : &:r824_9, ~m?
# 824| mu824_13(Base) = ^IndirectMayWriteSideEffect[-1] : &:r824_3
# 824| mu824_12(Base) = ^IndirectMayWriteSideEffect[-1] : &:r824_3
# 824| v824_13(void) = ^BufferReadSideEffect[0] : &:r824_9, ~m?
# 824| r824_14(glval<Base>) = Convert : r824_3
# 824| r824_15(Base &) = CopyValue : r824_14
# 824| r824_16(Base &) = Call[operator=] : func:r824_2, this:r824_1, 0:r824_15
@@ -4876,8 +4876,8 @@ ir.cpp:
# 868| r868_3(char *) = Convert : r868_2
# 868| v868_4(void) = Call[String] : func:r868_1, this:mu867_5, 0:r868_3
# 868| mu868_5(unknown) = ^CallSideEffect : ~m?
# 868| v868_6(void) = ^BufferReadSideEffect[0] : &:r868_3, ~m?
# 868| mu868_7(String) = ^IndirectMayWriteSideEffect[-1] : &:mu867_5
# 868| mu868_6(String) = ^IndirectMayWriteSideEffect[-1] : &:mu867_5
# 868| v868_7(void) = ^BufferReadSideEffect[0] : &:r868_3, ~m?
# 869| v869_1(void) = NoOp :
# 867| v867_8(void) = ReturnIndirection[#this] : &:r867_6, ~m?
# 867| v867_9(void) = ReturnVoid :
@@ -5177,8 +5177,8 @@ ir.cpp:
# 954| r954_10(char *) = Convert : r954_9
# 954| v954_11(void) = Call[String] : func:r954_8, this:r954_7, 0:r954_10
# 954| mu954_12(unknown) = ^CallSideEffect : ~m?
# 954| v954_13(void) = ^BufferReadSideEffect[0] : &:r954_10, ~m?
# 954| mu954_14(String) = ^IndirectMayWriteSideEffect[-1] : &:r954_7
# 954| mu954_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r954_7
# 954| v954_14(void) = ^BufferReadSideEffect[0] : &:r954_10, ~m?
# 955| r955_1(glval<unknown>) = FunctionAddress[operator new] :
# 955| r955_2(unsigned long) = Constant[256] :
# 955| r955_3(align_val_t) = Constant[128] :
@@ -6423,8 +6423,8 @@ ir.cpp:
# 1149| r1149_15(char *) = Convert : r1149_14
# 1149| v1149_16(void) = Call[String] : func:r1149_13, this:r1149_11, 0:r1149_15
# 1149| mu1149_17(unknown) = ^CallSideEffect : ~m?
# 1149| v1149_18(void) = ^BufferReadSideEffect[0] : &:r1149_15, ~m?
# 1149| mu1149_19(String) = ^IndirectMayWriteSideEffect[-1] : &:r1149_11
# 1149| mu1149_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r1149_11
# 1149| v1149_19(void) = ^BufferReadSideEffect[0] : &:r1149_15, ~m?
# 1149| v1149_20(void) = ThrowValue : &:r1149_11, ~m?
#-----| Exception -> Block 9
@@ -6451,8 +6451,8 @@ ir.cpp:
# 1154| r1154_5(char *) = Load[s] : &:r1154_4, ~m?
# 1154| v1154_6(void) = Call[String] : func:r1154_3, this:r1154_1, 0:r1154_5
# 1154| mu1154_7(unknown) = ^CallSideEffect : ~m?
# 1154| v1154_8(void) = ^BufferReadSideEffect[0] : &:r1154_5, ~m?
# 1154| mu1154_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r1154_1
# 1154| mu1154_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r1154_1
# 1154| v1154_9(void) = ^BufferReadSideEffect[0] : &:r1154_5, ~m?
# 1154| v1154_10(void) = ThrowValue : &:r1154_1, ~m?
#-----| Exception -> Block 2
@@ -6577,8 +6577,8 @@ ir.cpp:
# 1179| r1179_5(char *) = Convert : r1179_4
# 1179| v1179_6(void) = Call[String] : func:r1179_3, this:r1179_1, 0:r1179_5
# 1179| mu1179_7(unknown) = ^CallSideEffect : ~m?
# 1179| v1179_8(void) = ^BufferReadSideEffect[0] : &:r1179_5, ~m?
# 1179| mu1179_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r1179_1
# 1179| mu1179_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r1179_1
# 1179| v1179_9(void) = ^BufferReadSideEffect[0] : &:r1179_5, ~m?
# 1178| r1178_4(glval<String>) = VariableAddress[#return] :
# 1178| v1178_5(void) = ReturnValue : &:r1178_4, ~m?
# 1178| v1178_6(void) = AliasedUse : ~m?
@@ -6832,8 +6832,8 @@ ir.cpp:
# 1242| r1242_7(char *) = Convert : r1242_6
# 1242| v1242_8(void) = Call[String] : func:r1242_5, this:r1242_4, 0:r1242_7
# 1242| mu1242_9(unknown) = ^CallSideEffect : ~m?
# 1242| v1242_10(void) = ^BufferReadSideEffect[0] : &:r1242_7, ~m?
# 1242| mu1242_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r1242_4
# 1242| mu1242_10(String) = ^IndirectMayWriteSideEffect[-1] : &:r1242_4
# 1242| v1242_11(void) = ^BufferReadSideEffect[0] : &:r1242_7, ~m?
# 1242| r1242_12(bool) = Constant[1] :
# 1242| mu1242_13(bool) = Store[b#init] : &:r1242_1, r1242_12
#-----| Goto -> Block 4
@@ -6852,8 +6852,8 @@ ir.cpp:
# 1243| r1243_7(char *) = Load[dynamic] : &:r1243_6, ~m?
# 1243| v1243_8(void) = Call[String] : func:r1243_5, this:r1243_4, 0:r1243_7
# 1243| mu1243_9(unknown) = ^CallSideEffect : ~m?
# 1243| v1243_10(void) = ^BufferReadSideEffect[0] : &:r1243_7, ~m?
# 1243| mu1243_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r1243_4
# 1243| mu1243_10(String) = ^IndirectMayWriteSideEffect[-1] : &:r1243_4
# 1243| v1243_11(void) = ^BufferReadSideEffect[0] : &:r1243_7, ~m?
# 1243| r1243_12(bool) = Constant[1] :
# 1243| mu1243_13(bool) = Store[c#init] : &:r1243_1, r1243_12
#-----| Goto -> Block 6
@@ -7481,8 +7481,8 @@ ir.cpp:
# 1370| r1370_6(char *) = Convert : r1370_5
# 1370| v1370_7(void) = Call[String] : func:r1370_4, this:r1370_2, 0:r1370_6
# 1370| mu1370_8(unknown) = ^CallSideEffect : ~m?
# 1370| v1370_9(void) = ^BufferReadSideEffect[0] : &:r1370_6, ~m?
# 1370| mu1370_10(String) = ^IndirectMayWriteSideEffect[-1] : &:r1370_2
# 1370| mu1370_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r1370_2
# 1370| v1370_10(void) = ^BufferReadSideEffect[0] : &:r1370_6, ~m?
# 1370| r1370_11(String &) = CopyValue : r1370_2
# 1370| v1370_12(void) = Call[acceptRef] : func:r1370_1, 0:r1370_11
# 1370| mu1370_13(unknown) = ^CallSideEffect : ~m?
@@ -7496,8 +7496,8 @@ ir.cpp:
# 1371| r1371_7(String &) = CopyValue : r1371_6
# 1371| v1371_8(void) = Call[String] : func:r1371_4, this:r1371_2, 0:r1371_7
# 1371| mu1371_9(unknown) = ^CallSideEffect : ~m?
# 1371| v1371_10(void) = ^BufferReadSideEffect[0] : &:r1371_7, ~m?
# 1371| mu1371_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r1371_2
# 1371| mu1371_10(String) = ^IndirectMayWriteSideEffect[-1] : &:r1371_2
# 1371| v1371_11(void) = ^BufferReadSideEffect[0] : &:r1371_7, ~m?
# 1371| r1371_12(String) = Load[#temp1371:17] : &:r1371_2, ~m?
# 1371| v1371_13(void) = Call[acceptValue] : func:r1371_1, 0:r1371_12
# 1371| mu1371_14(unknown) = ^CallSideEffect : ~m?
@@ -7509,8 +7509,8 @@ ir.cpp:
# 1372| r1372_6(char *) = Convert : r1372_5
# 1372| v1372_7(void) = Call[String] : func:r1372_4, this:r1372_2, 0:r1372_6
# 1372| mu1372_8(unknown) = ^CallSideEffect : ~m?
# 1372| v1372_9(void) = ^BufferReadSideEffect[0] : &:r1372_6, ~m?
# 1372| mu1372_10(String) = ^IndirectMayWriteSideEffect[-1] : &:r1372_2
# 1372| mu1372_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r1372_2
# 1372| v1372_10(void) = ^BufferReadSideEffect[0] : &:r1372_6, ~m?
# 1372| r1372_11(String) = Load[#temp1372:25] : &:r1372_2, ~m?
# 1372| v1372_12(void) = Call[acceptValue] : func:r1372_1, 0:r1372_11
# 1372| mu1372_13(unknown) = ^CallSideEffect : ~m?
@@ -7652,8 +7652,8 @@ ir.cpp:
# 1396| r1396_7(copy_constructor &) = CopyValue : r1396_6
# 1396| v1396_8(void) = Call[copy_constructor] : func:r1396_4, this:r1396_2, 0:r1396_7
# 1396| mu1396_9(unknown) = ^CallSideEffect : ~m?
# 1396| v1396_10(void) = ^BufferReadSideEffect[0] : &:r1396_7, ~m?
# 1396| mu1396_11(copy_constructor) = ^IndirectMayWriteSideEffect[-1] : &:r1396_2
# 1396| mu1396_10(copy_constructor) = ^IndirectMayWriteSideEffect[-1] : &:r1396_2
# 1396| v1396_11(void) = ^BufferReadSideEffect[0] : &:r1396_7, ~m?
# 1396| r1396_12(copy_constructor) = Load[#temp1396:17] : &:r1396_2, ~m?
# 1396| v1396_13(void) = Call[acceptValue] : func:r1396_1, 0:r1396_12
# 1396| mu1396_14(unknown) = ^CallSideEffect : ~m?
@@ -7967,8 +7967,8 @@ smart_ptr.cpp:
# 19| r19_7(shared_ptr<float> &) = CopyValue : r19_6
# 19| v19_8(void) = Call[shared_ptr] : func:r19_4, this:r19_2, 0:r19_7
# 19| mu19_9(unknown) = ^CallSideEffect : ~m?
# 19| v19_10(void) = ^IndirectReadSideEffect[0] : &:r19_7, ~m?
# 19| mu19_11(shared_ptr<float>) = ^IndirectMustWriteSideEffect[-1] : &:r19_2
# 19| mu19_10(shared_ptr<float>) = ^IndirectMustWriteSideEffect[-1] : &:r19_2
# 19| v19_11(void) = ^IndirectReadSideEffect[0] : &:r19_7, ~m?
# 19| r19_12(shared_ptr<float>) = Load[#temp19:20] : &:r19_2, ~m?
# 19| v19_13(void) = Call[shared_ptr_arg] : func:r19_1, 0:r19_12
# 19| mu19_14(unknown) = ^CallSideEffect : ~m?
@@ -7996,8 +7996,8 @@ smart_ptr.cpp:
# 31| r31_7(shared_ptr<const int> &) = CopyValue : r31_6
# 31| v31_8(void) = Call[shared_ptr] : func:r31_4, this:r31_2, 0:r31_7
# 31| mu31_9(unknown) = ^CallSideEffect : ~m?
# 31| v31_10(void) = ^IndirectReadSideEffect[0] : &:r31_7, ~m?
# 31| mu31_11(shared_ptr<const int>) = ^IndirectMustWriteSideEffect[-1] : &:r31_2
# 31| mu31_10(shared_ptr<const int>) = ^IndirectMustWriteSideEffect[-1] : &:r31_2
# 31| v31_11(void) = ^IndirectReadSideEffect[0] : &:r31_7, ~m?
# 31| r31_12(shared_ptr<const int>) = Load[#temp31:26] : &:r31_2, ~m?
# 31| v31_13(void) = Call[shared_ptr_const_int] : func:r31_1, 0:r31_12
# 31| mu31_14(unknown) = ^CallSideEffect : ~m?
@@ -8013,8 +8013,8 @@ smart_ptr.cpp:
# 35| r35_7(shared_ptr<int *const> &) = CopyValue : r35_6
# 35| v35_8(void) = Call[shared_ptr] : func:r35_4, this:r35_2, 0:r35_7
# 35| mu35_9(unknown) = ^CallSideEffect : ~m?
# 35| v35_10(void) = ^IndirectReadSideEffect[0] : &:r35_7, ~m?
# 35| mu35_11(shared_ptr<int *const>) = ^IndirectMustWriteSideEffect[-1] : &:r35_2
# 35| mu35_10(shared_ptr<int *const>) = ^IndirectMustWriteSideEffect[-1] : &:r35_2
# 35| v35_11(void) = ^IndirectReadSideEffect[0] : &:r35_7, ~m?
# 35| r35_12(shared_ptr<int *const>) = Load[#temp35:30] : &:r35_2, ~m?
# 35| v35_13(void) = Call[shared_ptr_const_int_ptr] : func:r35_1, 0:r35_12
# 35| mu35_14(unknown) = ^CallSideEffect : ~m?
@@ -8031,8 +8031,8 @@ smart_ptr.cpp:
# 39| r39_7(shared_ptr<shared_ptr<const int>> &) = CopyValue : r39_6
# 39| v39_8(void) = Call[shared_ptr] : func:r39_4, this:r39_2, 0:r39_7
# 39| mu39_9(unknown) = ^CallSideEffect : ~m?
# 39| v39_10(void) = ^IndirectReadSideEffect[0] : &:r39_7, ~m?
# 39| mu39_11(shared_ptr<shared_ptr<const int>>) = ^IndirectMustWriteSideEffect[-1] : &:r39_2
# 39| mu39_10(shared_ptr<shared_ptr<const int>>) = ^IndirectMustWriteSideEffect[-1] : &:r39_2
# 39| v39_11(void) = ^IndirectReadSideEffect[0] : &:r39_7, ~m?
# 39| r39_12(shared_ptr<shared_ptr<const int>>) = Load[#temp39:37] : &:r39_2, ~m?
# 39| v39_13(void) = Call[shared_ptr_shared_ptr_const_int] : func:r39_1, 0:r39_12
# 39| mu39_14(unknown) = ^CallSideEffect : ~m?
@@ -8049,8 +8049,8 @@ smart_ptr.cpp:
# 43| r43_7(shared_ptr<const shared_ptr<int>> &) = CopyValue : r43_6
# 43| v43_8(void) = Call[shared_ptr] : func:r43_4, this:r43_2, 0:r43_7
# 43| mu43_9(unknown) = ^CallSideEffect : ~m?
# 43| v43_10(void) = ^IndirectReadSideEffect[0] : &:r43_7, ~m?
# 43| mu43_11(shared_ptr<const shared_ptr<int>>) = ^IndirectMustWriteSideEffect[-1] : &:r43_2
# 43| mu43_10(shared_ptr<const shared_ptr<int>>) = ^IndirectMustWriteSideEffect[-1] : &:r43_2
# 43| v43_11(void) = ^IndirectReadSideEffect[0] : &:r43_7, ~m?
# 43| r43_12(shared_ptr<const shared_ptr<int>>) = Load[#temp43:37] : &:r43_2, ~m?
# 43| v43_13(void) = Call[shared_ptr_const_shared_ptr_int] : func:r43_1, 0:r43_12
# 43| mu43_14(unknown) = ^CallSideEffect : ~m?
@@ -8067,8 +8067,8 @@ smart_ptr.cpp:
# 47| r47_7(shared_ptr<const shared_ptr<const int>> &) = CopyValue : r47_6
# 47| v47_8(void) = Call[shared_ptr] : func:r47_4, this:r47_2, 0:r47_7
# 47| mu47_9(unknown) = ^CallSideEffect : ~m?
# 47| v47_10(void) = ^IndirectReadSideEffect[0] : &:r47_7, ~m?
# 47| mu47_11(shared_ptr<const shared_ptr<const int>>) = ^IndirectMustWriteSideEffect[-1] : &:r47_2
# 47| mu47_10(shared_ptr<const shared_ptr<const int>>) = ^IndirectMustWriteSideEffect[-1] : &:r47_2
# 47| v47_11(void) = ^IndirectReadSideEffect[0] : &:r47_7, ~m?
# 47| r47_12(shared_ptr<const shared_ptr<const int>>) = Load[#temp47:43] : &:r47_2, ~m?
# 47| v47_13(void) = Call[shared_ptr_const_shared_ptr_const_int] : func:r47_1, 0:r47_12
# 47| mu47_14(unknown) = ^CallSideEffect : ~m?

View File

@@ -1398,13 +1398,13 @@ ssa.cpp:
# 294| v294_25(void) = Call[A] : func:r294_9, this:r294_8, 0:r294_16
# 294| m294_26(unknown) = ^CallSideEffect : ~m294_22
# 294| m294_27(unknown) = Chi : total:m294_22, partial:m294_26
# 294| v294_28(void) = ^BufferReadSideEffect[0] : &:r294_16, ~m294_24
# 294| m294_29(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
# 294| m294_30(unknown) = Chi : total:m294_7, partial:m294_29
# 294| m294_28(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
# 294| m294_29(unknown) = Chi : total:m294_7, partial:m294_28
# 294| v294_30(void) = ^BufferReadSideEffect[0] : &:r294_16, ~m294_24
# 294| m294_31(unknown) = ^BufferMayWriteSideEffect[0] : &:r294_16
# 294| m294_32(unknown) = Chi : total:m294_24, partial:m294_31
# 294| r294_33(glval<int>) = FieldAddress[i] : r294_8
# 294| r294_34(int) = Load[?] : &:r294_33, ~m294_30
# 294| r294_34(int) = Load[?] : &:r294_33, ~m294_29
# 294| m294_35(int) = Store[j] : &:r294_1, r294_34
# 295| r295_1(glval<A *>) = VariableAddress[a] :
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :

View File

@@ -1392,13 +1392,13 @@ ssa.cpp:
# 294| v294_25(void) = Call[A] : func:r294_9, this:r294_8, 0:r294_16
# 294| m294_26(unknown) = ^CallSideEffect : ~m294_22
# 294| m294_27(unknown) = Chi : total:m294_22, partial:m294_26
# 294| v294_28(void) = ^BufferReadSideEffect[0] : &:r294_16, ~m294_24
# 294| m294_29(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
# 294| m294_30(unknown) = Chi : total:m294_7, partial:m294_29
# 294| m294_28(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
# 294| m294_29(unknown) = Chi : total:m294_7, partial:m294_28
# 294| v294_30(void) = ^BufferReadSideEffect[0] : &:r294_16, ~m294_24
# 294| m294_31(unknown) = ^BufferMayWriteSideEffect[0] : &:r294_16
# 294| m294_32(unknown) = Chi : total:m294_24, partial:m294_31
# 294| r294_33(glval<int>) = FieldAddress[i] : r294_8
# 294| r294_34(int) = Load[?] : &:r294_33, ~m294_30
# 294| r294_34(int) = Load[?] : &:r294_33, ~m294_29
# 294| m294_35(int) = Store[j] : &:r294_1, r294_34
# 295| r295_1(glval<A *>) = VariableAddress[a] :
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :

View File

@@ -1285,8 +1285,8 @@ ssa.cpp:
# 294| mu294_20(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_14
# 294| v294_21(void) = Call[A] : func:r294_8, this:r294_7, 0:r294_14
# 294| mu294_22(unknown) = ^CallSideEffect : ~m?
# 294| v294_23(void) = ^BufferReadSideEffect[0] : &:r294_14, ~m?
# 294| mu294_24(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_7
# 294| mu294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_7
# 294| v294_24(void) = ^BufferReadSideEffect[0] : &:r294_14, ~m?
# 294| mu294_25(unknown) = ^BufferMayWriteSideEffect[0] : &:r294_14
# 294| r294_26(glval<int>) = FieldAddress[i] : r294_7
# 294| r294_27(int) = Load[?] : &:r294_26, ~m?

View File

@@ -1285,8 +1285,8 @@ ssa.cpp:
# 294| mu294_20(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_14
# 294| v294_21(void) = Call[A] : func:r294_8, this:r294_7, 0:r294_14
# 294| mu294_22(unknown) = ^CallSideEffect : ~m?
# 294| v294_23(void) = ^BufferReadSideEffect[0] : &:r294_14, ~m?
# 294| mu294_24(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_7
# 294| mu294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_7
# 294| v294_24(void) = ^BufferReadSideEffect[0] : &:r294_14, ~m?
# 294| mu294_25(unknown) = ^BufferMayWriteSideEffect[0] : &:r294_14
# 294| r294_26(glval<int>) = FieldAddress[i] : r294_7
# 294| r294_27(int) = Load[?] : &:r294_26, ~m?

View File

@@ -11,7 +11,6 @@
| difference::Base | can | does NOT | have implicit copy assignment |
| difference::OnlyAssign | can | does | have implicit copy assignment |
| difference::OnlyCtor | can NOT | does NOT | have implicit copy assignment |
| instantiated_explicit_ctor::Wrapper<int> | can | does | have implicit copy assignment |
| moves::MoveAssign | can NOT | does NOT | have implicit copy assignment |
| moves::MoveCtor | can NOT | does NOT | have implicit copy assignment |
| private_cc::C | can | does NOT | have implicit copy assignment |

View File

@@ -131,21 +131,3 @@ namespace difference {
class OnlyAssign : Base {
};
}
namespace instantiated_explicit_ctor {
template<class T>
class Wrapper {
public:
Wrapper(Wrapper<T> &other) {
m_t = other.m_t;
}
Wrapper() {
m_t = 0;
}
private:
T m_t;
};
Wrapper<int> wrapped_int;
}

View File

@@ -11,7 +11,6 @@
| difference::Base | can | does NOT | have implicit copy constructor |
| difference::OnlyAssign | can NOT | does NOT | have implicit copy constructor |
| difference::OnlyCtor | can | does | have implicit copy constructor |
| instantiated_explicit_ctor::Wrapper<int> | can | does NOT | have implicit copy constructor |
| moves::MoveAssign | can NOT | does NOT | have implicit copy constructor |
| moves::MoveCtor | can NOT | does NOT | have implicit copy constructor |
| private_cc::C | can | does NOT | have implicit copy constructor |

View File

@@ -86,9 +86,5 @@
| copy.cpp:131:9:131:9 | OnlyAssign | deleted | |
| copy.cpp:131:9:131:9 | operator= | | |
| copy.cpp:131:9:131:9 | operator= | | |
| copy.cpp:137:9:137:9 | operator= | | |
| copy.cpp:139:5:139:11 | Wrapper | | |
| copy.cpp:143:5:143:5 | Wrapper | | |
| copy.cpp:143:5:143:11 | Wrapper | | |
| file://:0:0:0:0 | operator= | | |
| file://:0:0:0:0 | operator= | | |

View File

@@ -1,4 +1,4 @@
// semmle-extractor-options: -std=c++17
void f(void) {
if (1) {
int i;
@@ -30,12 +30,3 @@ void nestedRangeBasedFor() {
for (auto y : ys) // GOOD
x = y = 0;
}
void structuredBinding() {
int xs[1] = {1};
auto [x] = xs;
{
auto [x] = xs; // BAD [NOT DETECTED]
auto [y] = xs; // GOOD
}
}

View File

@@ -117,8 +117,12 @@ struct HasVPV {
}
};
// NOT OK: the relevant copy constructor of ProtectedVolatile is
// accessible, so our class will get a generated copy constructor.
// FALSE NEGATIVE: the relevant copy constructor of ProtectedVolatile is
// accessible, so our class will get a generated copy constructor. Our query
// thinks the copy constructor is inaccessible because it picks up the other
// copy constructor. To fix this, our library should be changed to distinguish
// between copy constructors and resolve overloading properly instead of
// assuming that there is at most one.
struct HasPV {
ProtectedVolatile pv;
HasPV& operator=(const HasPV& that) {

View File

@@ -1,6 +1,6 @@
| RuleOfTwo.cpp:4:3:4:17 | CopyButNoAssign | No matching copy assignment operator in class CopyButNoAssign. It is good practice to match a copy constructor with a copy assignment operator. |
| RuleOfTwo.cpp:10:20:10:28 | operator= | No matching copy constructor in class AssignButNoCopy. It is good practice to match a copy assignment operator with a copy constructor. |
| RuleOfTwo.cpp:81:18:81:26 | operator= | No matching copy constructor in class MyClassFriend. It is good practice to match a copy assignment operator with a copy constructor. |
| RuleOfTwo.cpp:140:3:140:20 | IsAProtectedAssign | No matching copy assignment operator in class IsAProtectedAssign. It is good practice to match a copy constructor with a copy assignment operator. |
| RuleOfTwo.cpp:163:19:163:27 | operator= | No matching copy constructor in class IsAProtectedCC. It is good practice to match a copy assignment operator with a copy constructor. |
| RuleOfTwo.cpp:308:5:308:8 | R1_C | No matching copy assignment operator in class R1_C. It is good practice to match a copy constructor with a copy assignment operator. |
| RuleOfTwo.cpp:144:3:144:20 | IsAProtectedAssign | No matching copy assignment operator in class IsAProtectedAssign. It is good practice to match a copy constructor with a copy assignment operator. |
| RuleOfTwo.cpp:167:19:167:27 | operator= | No matching copy constructor in class IsAProtectedCC. It is good practice to match a copy assignment operator with a copy constructor. |
| RuleOfTwo.cpp:312:5:312:8 | R1_C | No matching copy assignment operator in class R1_C. It is good practice to match a copy constructor with a copy assignment operator. |

View File

@@ -1,10 +1,18 @@
edges
| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input |
| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input |
| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input |
| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input |
| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input indirection |
| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input indirection |
subpaths
nodes
| test2.cpp:110:3:110:6 | call to gets | semmle.label | call to gets |
| test.cpp:54:17:54:20 | argv | semmle.label | argv |
| test.cpp:54:17:54:20 | argv | semmle.label | argv |
| test.cpp:58:25:58:29 | input | semmle.label | input |
subpaths
| test.cpp:58:25:58:29 | input | semmle.label | input |
| test.cpp:58:25:58:29 | input | semmle.label | input |
| test.cpp:58:25:58:29 | input indirection | semmle.label | input indirection |
| test.cpp:58:25:58:29 | input indirection | semmle.label | input indirection |
#select
| test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets | This write into buffer 'password' may contain unencrypted data from $@ | test2.cpp:110:3:110:6 | call to gets | user input (String read by gets) |
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input | This write into buffer 'passwd' may contain unencrypted data from $@ | test.cpp:54:17:54:20 | argv | user input (a command-line argument) |
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input | This write into buffer 'passwd' may contain unencrypted data from $@ | test.cpp:54:17:54:20 | argv | user input (argv) |

View File

@@ -1,5 +1,4 @@
edges
| test2.cpp:63:24:63:31 | password | test2.cpp:63:16:63:20 | call to crypt |
| test3.cpp:17:28:17:36 | password1 | test3.cpp:22:15:22:23 | password1 |
| test3.cpp:17:51:17:59 | password2 | test3.cpp:26:15:26:23 | password2 |
| test3.cpp:45:8:45:15 | password | test3.cpp:47:15:47:22 | password |
@@ -90,15 +89,11 @@ edges
| test3.cpp:398:18:398:25 | password | test3.cpp:400:15:400:23 | & ... |
| test3.cpp:398:18:398:25 | password | test3.cpp:400:16:400:23 | password |
| test3.cpp:398:18:398:25 | password | test3.cpp:400:33:400:40 | password |
| test3.cpp:421:21:421:28 | password | test3.cpp:421:3:421:17 | call to decrypt_inplace |
| test.cpp:41:23:41:43 | cleartext password! | test.cpp:48:21:48:27 | call to encrypt |
| test.cpp:41:23:41:43 | cleartext password! | test.cpp:48:29:48:39 | thePassword |
| test.cpp:66:23:66:43 | cleartext password! | test.cpp:76:21:76:27 | call to encrypt |
| test.cpp:66:23:66:43 | cleartext password! | test.cpp:76:29:76:39 | thePassword |
nodes
| test2.cpp:63:16:63:20 | call to crypt | semmle.label | call to crypt |
| test2.cpp:63:24:63:31 | password | semmle.label | password |
| test2.cpp:63:24:63:31 | password | semmle.label | password |
| test3.cpp:17:28:17:36 | password1 | semmle.label | password1 |
| test3.cpp:17:51:17:59 | password2 | semmle.label | password2 |
| test3.cpp:22:15:22:23 | password1 | semmle.label | password1 |
@@ -213,11 +208,6 @@ nodes
| test3.cpp:400:15:400:23 | & ... | semmle.label | & ... |
| test3.cpp:400:16:400:23 | password | semmle.label | password |
| test3.cpp:400:33:400:40 | password | semmle.label | password |
| test3.cpp:414:17:414:24 | password | semmle.label | password |
| test3.cpp:420:17:420:24 | password | semmle.label | password |
| test3.cpp:421:3:421:17 | call to decrypt_inplace | semmle.label | call to decrypt_inplace |
| test3.cpp:421:21:421:28 | password | semmle.label | password |
| test3.cpp:421:21:421:28 | password | semmle.label | password |
| test.cpp:41:23:41:43 | cleartext password! | semmle.label | cleartext password! |
| test.cpp:48:21:48:27 | call to encrypt | semmle.label | call to encrypt |
| test.cpp:48:29:48:39 | thePassword | semmle.label | thePassword |
@@ -248,5 +238,3 @@ subpaths
| test3.cpp:300:2:300:5 | call to send | test3.cpp:308:58:308:66 | password2 | test3.cpp:300:14:300:17 | data | This operation transmits 'data', which may contain unencrypted sensitive data from $@ | test3.cpp:308:58:308:66 | password2 | password2 |
| test3.cpp:341:4:341:7 | call to recv | test3.cpp:339:9:339:16 | password | test3.cpp:341:16:341:23 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:339:9:339:16 | password | password |
| test3.cpp:388:3:388:6 | call to recv | test3.cpp:386:8:386:15 | password | test3.cpp:388:15:388:22 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:386:8:386:15 | password | password |
| test3.cpp:414:3:414:6 | call to recv | test3.cpp:414:17:414:24 | password | test3.cpp:414:17:414:24 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:414:17:414:24 | password | password |
| test3.cpp:420:3:420:6 | call to recv | test3.cpp:420:17:420:24 | password | test3.cpp:420:17:420:24 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:420:17:420:24 | password | password |

View File

@@ -99,14 +99,3 @@ void tests(FILE *log, myStruct &s)
fprintf(log, "log: %s", buffer); // BAD
}
}
char *gets(char *s);
void test_gets()
{
{
char password[1024];
gets(password); // BAD
}
}

View File

@@ -411,13 +411,13 @@ void test_member_password()
{
packet p;
recv(val(), p.password, 256, val()); // BAD: not encrypted
recv(val(), p.password, 256, val()); // BAD: not encrypted [NOT DETECTED]
}
{
packet p;
recv(val(), p.password, 256, val()); // GOOD: password is encrypted [FALSE POSITIVE]
recv(val(), p.password, 256, val()); // GOOD: password is encrypted
decrypt_inplace(p.password); // proof that `password` was in fact encrypted
}
}

View File

@@ -1,2 +0,0 @@
description: Support for compiler-generated event accessors.
compatibility: backwards

File diff suppressed because it is too large Load Diff

View File

@@ -6,15 +6,11 @@ namespace Semmle.Extraction.CSharp.Entities
{
internal class Accessor : Method
{
private readonly IPropertySymbol property;
protected Accessor(Context cx, IMethodSymbol init, IPropertySymbol property)
: base(cx, init)
{
this.property = property;
}
protected Accessor(Context cx, IMethodSymbol init)
: base(cx, init) { }
/// <summary>
/// Gets the property symbol associated with accessor `symbol`, or `null`
/// Gets the property symbol associated accessor `symbol`, or `null`
/// if there is no associated symbol.
/// </summary>
public static IPropertySymbol? GetPropertySymbol(IMethodSymbol symbol)
@@ -30,30 +26,42 @@ namespace Semmle.Extraction.CSharp.Entities
return props.SingleOrDefault();
}
/// <summary>
/// Gets the property symbol associated with this accessor.
/// </summary>
private IPropertySymbol? PropertySymbol => GetPropertySymbol(Symbol);
public new Accessor OriginalDefinition => Create(Context, Symbol.OriginalDefinition);
public override void Populate(TextWriter trapFile)
{
PopulateMethod(trapFile);
PopulateModifiers(trapFile);
ContainingType!.PopulateGenerics();
var parent = Property.Create(Context, property);
var prop = PropertySymbol;
if (prop is null)
{
Context.ModelError(Symbol, "Unhandled accessor associated symbol");
return;
}
var parent = Property.Create(Context, prop);
int kind;
Accessor unboundAccessor;
if (SymbolEqualityComparer.Default.Equals(Symbol, property.GetMethod))
if (SymbolEqualityComparer.Default.Equals(Symbol, prop.GetMethod))
{
kind = 1;
var orig = property.OriginalDefinition;
unboundAccessor = Create(Context, orig.GetMethod!, orig);
unboundAccessor = Create(Context, prop.OriginalDefinition.GetMethod!);
}
else if (SymbolEqualityComparer.Default.Equals(Symbol, property.SetMethod))
else if (SymbolEqualityComparer.Default.Equals(Symbol, prop.SetMethod))
{
kind = 2;
var orig = property.OriginalDefinition;
unboundAccessor = Create(Context, orig.SetMethod!, orig);
unboundAccessor = Create(Context, prop.OriginalDefinition.SetMethod!);
}
else
{
Context.ModelError(Symbol, $"Unhandled accessor method {Symbol.ToDisplayString()}");
Context.ModelError(Symbol, "Unhandled accessor kind");
return;
}
@@ -75,14 +83,14 @@ namespace Semmle.Extraction.CSharp.Entities
}
}
public static Accessor Create(Context cx, IMethodSymbol symbol, IPropertySymbol prop) =>
AccessorFactory.Instance.CreateEntity(cx, symbol, (symbol, prop));
public static new Accessor Create(Context cx, IMethodSymbol symbol) =>
AccessorFactory.Instance.CreateEntityFromSymbol(cx, symbol);
private class AccessorFactory : CachedEntityFactory<(IMethodSymbol, IPropertySymbol), Accessor>
private class AccessorFactory : CachedEntityFactory<IMethodSymbol, Accessor>
{
public static AccessorFactory Instance { get; } = new AccessorFactory();
public override Accessor Create(Context cx, (IMethodSymbol, IPropertySymbol) init) => new(cx, init.Item1, init.Item2);
public override Accessor Create(Context cx, IMethodSymbol init) => new Accessor(cx, init);
}
}
}

View File

@@ -3,46 +3,44 @@ using System.IO;
namespace Semmle.Extraction.CSharp.Entities
{
internal class EventAccessor : Method
internal class EventAccessor : Accessor
{
private readonly IEventSymbol @event;
private EventAccessor(Context cx, IMethodSymbol init, IEventSymbol @event)
: base(cx, init)
{
this.@event = @event;
}
private EventAccessor(Context cx, IMethodSymbol init)
: base(cx, init) { }
/// <summary>
/// Gets the event symbol associated with accessor `symbol`, or `null`
/// if there is no associated symbol.
/// Gets the event symbol associated with this accessor.
/// </summary>
public static IEventSymbol? GetEventSymbol(IMethodSymbol symbol) =>
symbol.AssociatedSymbol as IEventSymbol;
private IEventSymbol? EventSymbol => Symbol.AssociatedSymbol as IEventSymbol;
public override void Populate(TextWriter trapFile)
{
PopulateMethod(trapFile);
ContainingType!.PopulateGenerics();
var @event = EventSymbol;
if (@event is null)
{
Context.ModelError(Symbol, "Unhandled event accessor associated symbol");
return;
}
var parent = Event.Create(Context, @event);
int kind;
EventAccessor unboundAccessor;
if (SymbolEqualityComparer.Default.Equals(Symbol, @event.AddMethod))
{
kind = 1;
var orig = @event.OriginalDefinition;
unboundAccessor = Create(Context, orig.AddMethod!, orig);
unboundAccessor = Create(Context, @event.OriginalDefinition.AddMethod!);
}
else if (SymbolEqualityComparer.Default.Equals(Symbol, @event.RemoveMethod))
{
kind = 2;
var orig = @event.OriginalDefinition;
unboundAccessor = Create(Context, orig.RemoveMethod!, orig);
unboundAccessor = Create(Context, @event.OriginalDefinition.RemoveMethod!);
}
else
{
Context.ModelError(Symbol, $"Undhandled event accessor kind {Symbol.ToDisplayString()}");
Context.ModelError(Symbol, "Undhandled event accessor kind");
return;
}
@@ -52,21 +50,16 @@ namespace Semmle.Extraction.CSharp.Entities
trapFile.event_accessor_location(this, l);
Overrides(trapFile);
if (Symbol.FromSource() && Block is null)
{
trapFile.compiler_generated(this);
}
}
public static EventAccessor Create(Context cx, IMethodSymbol symbol, IEventSymbol @event) =>
EventAccessorFactory.Instance.CreateEntity(cx, symbol, (symbol, @event));
public static new EventAccessor Create(Context cx, IMethodSymbol symbol) =>
EventAccessorFactory.Instance.CreateEntityFromSymbol(cx, symbol);
private class EventAccessorFactory : CachedEntityFactory<(IMethodSymbol, IEventSymbol), EventAccessor>
private class EventAccessorFactory : CachedEntityFactory<IMethodSymbol, EventAccessor>
{
public static EventAccessorFactory Instance { get; } = new EventAccessorFactory();
public override EventAccessor Create(Context cx, (IMethodSymbol, IEventSymbol) init) => new EventAccessor(cx, init.Item1, init.Item2);
public override EventAccessor Create(Context cx, IMethodSymbol init) => new EventAccessor(cx, init);
}
}
}

View File

@@ -45,7 +45,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
else if (body is BlockSyntax blockBody)
Statements.Block.Create(Context, blockBody, this, 0);
else
Context.ModelError(body, $"Unhandled lambda body of type {body.GetType()}");
Context.ModelError(body, "Unhandled lambda body");
});
}

View File

@@ -96,7 +96,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
kind = ExprKind.NAMESPACE_ACCESS;
break;
default:
info.Context.ModelError(info.Node, $"Unhandled symbol for member access of kind {symbol.Kind}");
info.Context.ModelError(info.Node, "Unhandled symbol for member access");
kind = ExprKind.UNKNOWN;
break;
}

View File

@@ -43,8 +43,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
if (Syntax.Initializer is not null)
{
var kind = Syntax.Initializer.Kind();
switch (kind)
switch (Syntax.Initializer.Kind())
{
case SyntaxKind.CollectionInitializerExpression:
CollectionInitializer.Create(new ExpressionNodeInfo(Context, Syntax.Initializer, this, -1).SetType(Type));
@@ -53,7 +52,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
ObjectInitializer.Create(new ExpressionNodeInfo(Context, Syntax.Initializer, this, -1).SetType(Type));
break;
default:
Context.ModelError(Syntax.Initializer, $"Unhandled initializer in object creation of kind {kind}");
Context.ModelError(Syntax.Initializer, "Unhandled initializer in object creation");
break;
}
}

View File

@@ -68,7 +68,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
case DiscardDesignationSyntax discard:
return new Expressions.Discard(cx, discard, parent, child);
default:
throw new InternalError($"var pattern designation of type {varPattern.Designation.GetType()} is unhandled");
throw new InternalError("var pattern designation is unhandled");
}
case DiscardPatternSyntax dp:

View File

@@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Semmle.Extraction.Kinds;
using Semmle.Extraction.Entities;
@@ -12,69 +10,17 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
base(new ExpressionInfo(cx, null, cx.CreateLocation(pp.GetLocation()), ExprKind.PROPERTY_PATTERN, parent, child, false, null))
{
child = 0;
var trapFile = cx.TrapWriter.Writer;
foreach (var sub in pp.Subpatterns)
{
if (sub.ExpressionColon is null)
var p = Expressions.Pattern.Create(cx, sub.Pattern, this, child++);
if (sub.NameColon is null)
{
Context.ModelError(sub, "Expected to find 'Expression:' in pattern.");
Context.ModelError(sub, "Expected to find 'Name:' in pattern.");
continue;
}
MakeExpressions(cx, this, sub, child++);
trapFile.exprorstmt_name(p, sub.NameColon.Name.ToString());
}
}
private record AccessStep(string Identifier, Microsoft.CodeAnalysis.Location Location);
private class AccessStepPack
{
public readonly List<AccessStep> Prefix = new List<AccessStep>();
public AccessStep Last { get; private set; }
public AccessStepPack Add(string identifier, Microsoft.CodeAnalysis.Location location)
{
Prefix.Add(Last);
Last = new AccessStep(identifier, location);
return this;
}
public AccessStepPack(string identifier, Microsoft.CodeAnalysis.Location location) =>
Last = new AccessStep(identifier, location);
}
private static AccessStepPack GetAccessStepPack(ExpressionSyntax syntax) =>
syntax switch
{
MemberAccessExpressionSyntax memberAccess => GetAccessStepPack(memberAccess.Expression).Add(memberAccess.Name.Identifier.ValueText, memberAccess.Name.Identifier.GetLocation()),
IdentifierNameSyntax identifier => new AccessStepPack(identifier.Identifier.Text, identifier.GetLocation()),
_ => throw new InternalError(syntax, "Unexpected expression syntax in property patterns."),
};
private static AccessStepPack GetAccessStepPack(BaseExpressionColonSyntax syntax) =>
syntax switch
{
NameColonSyntax ncs => new AccessStepPack(ncs.Name.ToString(), ncs.Name.GetLocation()),
ExpressionColonSyntax ecs => GetAccessStepPack(ecs.Expression),
_ => throw new InternalError(syntax, "Unsupported expression colon in property pattern."),
};
private static Expression CreateSyntheticExp(Context cx, Microsoft.CodeAnalysis.Location location, IExpressionParentEntity parent, int child) =>
new Expression(new ExpressionInfo(cx, null, cx.CreateLocation(location), ExprKind.PROPERTY_PATTERN, parent, child, false, null));
private static void MakeExpressions(Context cx, IExpressionParentEntity parent, SubpatternSyntax syntax, int child)
{
var trapFile = cx.TrapWriter.Writer;
var pack = GetAccessStepPack(syntax.ExpressionColon!);
foreach (var step in pack.Prefix)
{
var exp = CreateSyntheticExp(cx, step.Location, parent, child);
trapFile.exprorstmt_name(exp, step.Identifier);
parent = exp;
child = 0;
}
var p = Expressions.Pattern.Create(cx, syntax.Pattern, parent, child);
trapFile.exprorstmt_name(p, pack.Last.Identifier);
}
}
}

View File

@@ -105,8 +105,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
}
break;
default:
var type = variable.GetType().ToString() ?? "null";
throw new InternalError(variable, $"Unhandled designation type {type}");
throw new InternalError(variable, "Unhandled designation type");
}
elementTypes.Add(sub.Type.HasValue && sub.Type.Value.Symbol?.Kind != SymbolKind.ErrorType

View File

@@ -262,10 +262,10 @@ namespace Semmle.Extraction.CSharp.Entities
return Destructor.Create(cx, methodDecl);
case MethodKind.PropertyGet:
case MethodKind.PropertySet:
return Accessor.GetPropertySymbol(methodDecl) is IPropertySymbol prop ? Accessor.Create(cx, methodDecl, prop) : OrdinaryMethod.Create(cx, methodDecl);
return Accessor.GetPropertySymbol(methodDecl) is null ? OrdinaryMethod.Create(cx, methodDecl) : (Method)Accessor.Create(cx, methodDecl);
case MethodKind.EventAdd:
case MethodKind.EventRemove:
return EventAccessor.GetEventSymbol(methodDecl) is IEventSymbol @event ? EventAccessor.Create(cx, methodDecl, @event) : OrdinaryMethod.Create(cx, methodDecl);
return EventAccessor.Create(cx, methodDecl);
case MethodKind.UserDefinedOperator:
case MethodKind.BuiltinOperator:
return UserOperator.Create(cx, methodDecl);

View File

@@ -13,7 +13,7 @@ namespace Semmle.Extraction.CSharp.Entities
SyntaxKind.DefaultKeyword => LineDirectiveKind.Default,
SyntaxKind.HiddenKeyword => LineDirectiveKind.Hidden,
SyntaxKind.NumericLiteralToken => LineDirectiveKind.Numeric,
_ => throw new InternalError(trivia, $"Unhandled line token kind {trivia.Line.Kind()}")
_ => throw new InternalError(trivia, "Unhandled line token kind")
})
{
}

View File

@@ -18,7 +18,7 @@ namespace Semmle.Extraction.CSharp.Entities
SyntaxKind.DisableKeyword => 0,
SyntaxKind.EnableKeyword => 1,
SyntaxKind.RestoreKeyword => 2,
_ => throw new InternalError(Symbol, $"Unhandled setting token kind {Symbol.SettingToken.Kind()}")
_ => throw new InternalError(Symbol, "Unhandled setting token kind")
};
var target = Symbol.TargetToken.Kind() switch
@@ -26,7 +26,7 @@ namespace Semmle.Extraction.CSharp.Entities
SyntaxKind.None => 0,
SyntaxKind.AnnotationsKeyword => 1,
SyntaxKind.WarningsKeyword => 2,
_ => throw new InternalError(Symbol, $"Unhandled target token kind {Symbol.TargetToken.Kind()}")
_ => throw new InternalError(Symbol, "Unhandled target token kind")
};
trapFile.directive_nullables(this, setting, target);

View File

@@ -23,7 +23,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
case SyntaxKind.CasePatternSwitchLabel:
return CasePattern.Create(cx, (CasePatternSwitchLabelSyntax)node, parent, child);
default:
throw new InternalError(node, $"Unhandled case label of kind {node.Kind()}");
throw new InternalError(node, "Unhandled case label");
}
}
}

View File

@@ -1,5 +1,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Semmle.Extraction.Entities;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -19,9 +21,33 @@ namespace Semmle.Extraction.CSharp.Entities
public override void Populate(TextWriter trapFile)
{
trapFile.types(this, Kinds.TypeKind.TYPE_PARAMETER, Symbol.Name);
var constraints = new TypeParameterConstraints(Context);
trapFile.type_parameter_constraints(constraints, this);
TypeParameterConstraints.Create(Context, this);
if (Symbol.HasReferenceTypeConstraint)
trapFile.general_type_parameter_constraints(constraints, 1);
if (Symbol.HasValueTypeConstraint)
trapFile.general_type_parameter_constraints(constraints, 2);
if (Symbol.HasConstructorConstraint)
trapFile.general_type_parameter_constraints(constraints, 3);
if (Symbol.HasUnmanagedTypeConstraint)
trapFile.general_type_parameter_constraints(constraints, 4);
if (Symbol.ReferenceTypeConstraintNullableAnnotation == NullableAnnotation.Annotated)
trapFile.general_type_parameter_constraints(constraints, 5);
foreach (var abase in Symbol.GetAnnotatedTypeConstraints())
{
var t = Create(Context, abase.Symbol);
trapFile.specific_type_parameter_constraints(constraints, t.TypeRef);
if (!abase.HasObliviousNullability())
trapFile.specific_type_parameter_nullability(constraints, t.TypeRef, NullabilityEntity.Create(Context, Nullability.Create(abase)));
}
trapFile.types(this, Kinds.TypeKind.TYPE_PARAMETER, Symbol.Name);
var parentNs = Namespace.Create(Context, Symbol.TypeParameterKind == TypeParameterKind.Method ? Context.Compilation.GlobalNamespace : Symbol.ContainingNamespace);
trapFile.parent_namespace(this, parentNs);

View File

@@ -1,65 +1,14 @@
using Microsoft.CodeAnalysis;
using System.IO;
namespace Semmle.Extraction.CSharp.Entities
{
internal class TypeParameterConstraints : CachedEntity<ITypeParameterSymbol>
internal class TypeParameterConstraints : FreshEntity
{
private readonly TypeParameter parent;
public TypeParameterConstraints(Context cx)
: base(cx) { }
public TypeParameterConstraints(Context cx, TypeParameter parent)
: base(cx, parent.Symbol)
protected override void Populate(TextWriter trapFile)
{
this.parent = parent;
}
public override void WriteId(EscapingTextWriter trapFile)
{
trapFile.WriteSubId(parent);
trapFile.Write(";typeparameterconstraints");
}
public override bool NeedsPopulation => true;
public override void Populate(TextWriter trapFile)
{
trapFile.type_parameter_constraints(this, parent);
if (Symbol.HasReferenceTypeConstraint)
trapFile.general_type_parameter_constraints(this, 1);
if (Symbol.HasValueTypeConstraint)
trapFile.general_type_parameter_constraints(this, 2);
if (Symbol.HasConstructorConstraint)
trapFile.general_type_parameter_constraints(this, 3);
if (Symbol.HasUnmanagedTypeConstraint)
trapFile.general_type_parameter_constraints(this, 4);
if (Symbol.ReferenceTypeConstraintNullableAnnotation == NullableAnnotation.Annotated)
trapFile.general_type_parameter_constraints(this, 5);
foreach (var abase in Symbol.GetAnnotatedTypeConstraints())
{
var t = Type.Create(Context, abase.Symbol);
trapFile.specific_type_parameter_constraints(this, t.TypeRef);
if (!abase.HasObliviousNullability())
trapFile.specific_type_parameter_nullability(this, t.TypeRef, NullabilityEntity.Create(Context, Nullability.Create(abase)));
}
}
public override Location? ReportingLocation => null;
public static TypeParameterConstraints Create(Context cx, TypeParameter p) =>
TypeParameterConstraintsFactory.Instance.CreateEntity(cx, (typeof(TypeParameterConstraints), p), p);
private class TypeParameterConstraintsFactory : CachedEntityFactory<TypeParameter, TypeParameterConstraints>
{
public static TypeParameterConstraintsFactory Instance { get; } = new TypeParameterConstraintsFactory();
public override TypeParameterConstraints Create(Context cx, TypeParameter init) => new(cx, init);
}
}
}

View File

@@ -36,7 +36,7 @@ namespace Semmle.Extraction.CSharp.Populators
public override void DefaultVisit(SyntaxNode node)
{
throw new InternalError(node, $"Unhandled top-level syntax node of type {node.GetType()}");
throw new InternalError(node, "Unhandled top-level syntax node");
}
public override void VisitGlobalStatement(GlobalStatementSyntax node)

View File

@@ -1,6 +1,4 @@
name: codeql/csharp-examples
groups:
- csharp
- examples
version: 0.0.2
dependencies:
codeql/csharp-all: "*"

View File

@@ -1,4 +0,0 @@
---
category: majorAnalysis
---
* Added support for C# 10 [Extended property patterns](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10#extended-property-patterns).

View File

@@ -182,14 +182,6 @@ class Folder extends Container, @folder {
override string getURL() { result = "folder://" + this.getAbsolutePath() }
}
bindingset[flag]
private predicate fileHasExtractionFlag(File f, int flag) {
exists(int i |
file_extraction_mode(f, i) and
i.bitAnd(flag) = flag
)
}
/** A file. */
class File extends Container, @file {
override string getAbsolutePath() { files(this, result) }
@@ -207,10 +199,7 @@ class File extends Container, @file {
/** Holds if this file is a QL test stub file. */
pragma[noinline]
private predicate isStub() {
this.extractedQlTest() and
this.getAbsolutePath().matches("%resources/stubs/%")
}
private predicate isStub() { this.getAbsolutePath().matches("%resources/stubs/%") }
/** Holds if this file contains source code. */
final predicate fromSource() {
@@ -229,12 +218,12 @@ class File extends Container, @file {
* A source file can come from a PDB and from regular extraction
* in the same snapshot.
*/
predicate isPdbSourceFile() { fileHasExtractionFlag(this, 2) }
/**
* Holds if this file was extracted using `codeql test run`.
*/
predicate extractedQlTest() { fileHasExtractionFlag(this, 4) }
predicate isPdbSourceFile() {
exists(int i |
file_extraction_mode(this, i) and
i.bitAnd(2) = 2
)
}
}
/**
@@ -244,5 +233,10 @@ class SourceFile extends File {
SourceFile() { this.fromSource() }
/** Holds if the file was extracted without building the source code. */
predicate extractedStandalone() { fileHasExtractionFlag(this, 1) }
predicate extractedStandalone() {
exists(int i |
file_extraction_mode(this, i) and
i.bitAnd(1) = 1
)
}
}

View File

@@ -214,7 +214,7 @@ abstract class SplitKind extends SplitKindBase {
abstract string toString();
}
/** An interface for implementing an entity to split on. */
/** Provides the interface for implementing an entity to split on. */
abstract class SplitImpl extends Split {
/** Gets the kind of this split. */
abstract SplitKind getKind();
@@ -894,31 +894,16 @@ module TestOutput {
p
order by
l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(),
l.getStartColumn(), l.getEndLine(), l.getEndColumn(), p.toString()
l.getStartColumn()
)
).toString()
}
query predicate edges(RelevantNode pred, RelevantNode succ, string attr, string val) {
attr = "semmle.label" and
exists(SuccessorType t | succ = getASuccessor(pred, t) |
attr = "semmle.label" and
if successorTypeIsSimple(t) then val = "" else val = t.toString()
)
or
attr = "semmle.order" and
val =
any(int i |
succ =
rank[i](RelevantNode s, SuccessorType t, Location l |
s = getASuccessor(pred, t) and
l = s.getLocation()
|
s
order by
l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(),
l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString()
)
).toString()
}
}

View File

@@ -1290,7 +1290,7 @@ class DataFlowCallOption extends TDataFlowCallOption {
}
}
/** A `Content` tagged with the type of a containing object. */
/** Content tagged with the type of a containing object. */
class TypedContent extends MkTypedContent {
private Content c;
private DataFlowType t;

View File

@@ -90,9 +90,7 @@ module Public {
predicate contains(SummaryComponent c) { c = this.drop(_).head() }
/** Gets the bottom element of this stack. */
SummaryComponent bottom() {
this = TSingletonSummaryComponentStack(result) or result = this.tail().bottom()
}
SummaryComponent bottom() { result = this.drop(this.length() - 1).head() }
/** Gets a textual representation of this stack. */
string toString() {

View File

@@ -648,7 +648,7 @@ has_modifiers(
int id: @modifiable_direct ref,
int mod_id: @modifier ref);
compiler_generated(unique int id: @modifiable ref);
compiler_generated(unique int id: @modifiable_direct ref);
/** MEMBERS **/

View File

@@ -12,6 +12,26 @@
<k>@extractor_message</k>
<v>44691</v>
</e>
<e>
<k>@externalDefect</k>
<v>0</v>
</e>
<e>
<k>@externalMetric</k>
<v>0</v>
</e>
<e>
<k>@externalDataElement</k>
<v>0</v>
</e>
<e>
<k>@duplication</k>
<v>0</v>
</e>
<e>
<k>@similarity</k>
<v>0</v>
</e>
<e>
<k>@assembly</k>
<v>30136</v>

View File

@@ -6,22 +6,122 @@
*/
class Person extends string {
Person() {
this =
[
"Ronil", "Dina", "Ravi", "Bruce", "Jo", "Aida", "Esme", "Charlie", "Fred", "Meera", "Maya",
"Chad", "Tiana", "Laura", "George", "Will", "Mary", "Almira", "Susannah", "Rhoda",
"Cynthia", "Eunice", "Olive", "Virginia", "Angeline", "Helen", "Cornelia", "Harriet",
"Mahala", "Abby", "Margaret", "Deb", "Minerva", "Severus", "Lavina", "Adeline", "Cath",
"Elisa", "Lucretia", "Anne", "Eleanor", "Joanna", "Adam", "Agnes", "Rosanna", "Clara",
"Melissa", "Amy", "Isabel", "Jemima", "Cordelia", "Melinda", "Delila", "Jeremiah", "Elijah",
"Hester", "Walter", "Oliver", "Hugh", "Aaron", "Reuben", "Eli", "Amos", "Augustus",
"Theodore", "Ira", "Timothy", "Cyrus", "Horace", "Simon", "Asa", "Frank", "Nelson",
"Leonard", "Harrison", "Anthony", "Louis", "Milton", "Noah", "Cornelius", "Abdul", "Warren",
"Harvey", "Dennis", "Wesley", "Sylvester", "Gilbert", "Sullivan", "Edmund", "Wilson",
"Perry", "Matthew", "Simba", "Nala", "Rafiki", "Shenzi", "Ernest", "Gertrude", "Oscar",
"Lilian", "Raymond", "Elgar", "Elmer", "Herbert", "Maude", "Mae", "Otto", "Edwin",
"Ophelia", "Parsley", "Sage", "Rosemary", "Thyme", "Garfunkel", "King Basil", "Stephen"
]
this = "Ronil" or
this = "Dina" or
this = "Ravi" or
this = "Bruce" or
this = "Jo" or
this = "Aida" or
this = "Esme" or
this = "Charlie" or
this = "Fred" or
this = "Meera" or
this = "Maya" or
this = "Chad" or
this = "Tiana" or
this = "Laura" or
this = "George" or
this = "Will" or
this = "Mary" or
this = "Almira" or
this = "Susannah" or
this = "Rhoda" or
this = "Cynthia" or
this = "Eunice" or
this = "Olive" or
this = "Virginia" or
this = "Angeline" or
this = "Helen" or
this = "Cornelia" or
this = "Harriet" or
this = "Mahala" or
this = "Abby" or
this = "Margaret" or
this = "Deb" or
this = "Minerva" or
this = "Severus" or
this = "Lavina" or
this = "Adeline" or
this = "Cath" or
this = "Elisa" or
this = "Lucretia" or
this = "Anne" or
this = "Eleanor" or
this = "Joanna" or
this = "Adam" or
this = "Agnes" or
this = "Rosanna" or
this = "Clara" or
this = "Melissa" or
this = "Amy" or
this = "Isabel" or
this = "Jemima" or
this = "Cordelia" or
this = "Melinda" or
this = "Delila" or
this = "Jeremiah" or
this = "Elijah" or
this = "Hester" or
this = "Walter" or
this = "Oliver" or
this = "Hugh" or
this = "Aaron" or
this = "Reuben" or
this = "Eli" or
this = "Amos" or
this = "Augustus" or
this = "Theodore" or
this = "Ira" or
this = "Timothy" or
this = "Cyrus" or
this = "Horace" or
this = "Simon" or
this = "Asa" or
this = "Frank" or
this = "Nelson" or
this = "Leonard" or
this = "Harrison" or
this = "Anthony" or
this = "Louis" or
this = "Milton" or
this = "Noah" or
this = "Cornelius" or
this = "Abdul" or
this = "Warren" or
this = "Harvey" or
this = "Dennis" or
this = "Wesley" or
this = "Sylvester" or
this = "Gilbert" or
this = "Sullivan" or
this = "Edmund" or
this = "Wilson" or
this = "Perry" or
this = "Matthew" or
this = "Simba" or
this = "Nala" or
this = "Rafiki" or
this = "Shenzi" or
this = "Ernest" or
this = "Gertrude" or
this = "Oscar" or
this = "Lilian" or
this = "Raymond" or
this = "Elgar" or
this = "Elmer" or
this = "Herbert" or
this = "Maude" or
this = "Mae" or
this = "Otto" or
this = "Edwin" or
this = "Ophelia" or
this = "Parsley" or
this = "Sage" or
this = "Rosemary" or
this = "Thyme" or
this = "Garfunkel" or
this = "King Basil" or
this = "Stephen"
}
/** Gets the hair color of the person. If the person is bald, there is no result. */
@@ -836,12 +936,25 @@ class Person extends string {
/** Holds if the person is deceased. */
predicate isDeceased() {
this =
[
"Ernest", "Gertrude", "Oscar", "Lilian", "Edwin", "Raymond", "Elgar", "Elmer", "Herbert",
"Maude", "Mae", "Otto", "Ophelia", "Parsley", "Sage", "Rosemary", "Thyme", "Garfunkel",
"King Basil"
]
this = "Ernest" or
this = "Gertrude" or
this = "Oscar" or
this = "Lilian" or
this = "Edwin" or
this = "Raymond" or
this = "Elgar" or
this = "Elmer" or
this = "Herbert" or
this = "Maude" or
this = "Mae" or
this = "Otto" or
this = "Ophelia" or
this = "Parsley" or
this = "Sage" or
this = "Rosemary" or
this = "Thyme" or
this = "Garfunkel" or
this = "King Basil"
}
/** Gets a parent of the person (alive or deceased). */
@@ -1082,7 +1195,12 @@ class Person extends string {
}
/** Holds if the person is allowed in the region. Initially, all villagers are allowed in every region. */
predicate isAllowedIn(string region) { region = ["north", "south", "east", "west"] }
predicate isAllowedIn(string region) {
region = "north" or
region = "south" or
region = "east" or
region = "west"
}
}
/** Returns a parent of the person. */

View File

@@ -1,2 +0,0 @@
description: Support for compiler-generated event accessors.
compatibility: backwards

View File

@@ -1,24 +0,0 @@
/**
* @name Extractor diagnostics
* @description This query is for internal use only and may change without notice.
* @kind table
* @id csharp/extractor-diagnostics
*/
import csharp
bindingset[i]
private float getCompilationTimeSum(int i) {
result = sum(float f | compilation_time(_, _, i, f) | f)
}
select getCompilationTimeSum(0) as sum_frontend_cpu_seconds,
getCompilationTimeSum(1) as sum_frontend_elapsed_seconds,
getCompilationTimeSum(4) as sum_frontend_user_seconds,
getCompilationTimeSum(2) as sum_extractor_cpu_seconds,
getCompilationTimeSum(3) as sum_extractor_elapsed_seconds,
getCompilationTimeSum(5) as sum_extractor_user_seconds,
sum(float f | compilation_finished(_, f, _) | f) as sum_total_cpu_seconds,
sum(float f | compilation_finished(_, _, f) | f) as sum_total_elapsed_seconds,
getCompilationTimeSum(6) as sum_peak_working_set_mb,
max(float f | compilation_time(_, _, 6, f) | f) as max_peak_working_set_mb

View File

@@ -1,8 +1,6 @@
name: codeql/csharp-queries
version: 0.0.8-dev
groups:
- csharp
- queries
groups: csharp
suites: codeql-suites
extractor: csharp
defaultSuiteFile: codeql-suites/csharp-code-scanning.qls

View File

@@ -93,7 +93,7 @@
private import InlineExpectationsTestPrivate
/**
* The base class for tests with inline expectations. The test extends this class to provide the actual
* Base class for tests with inline expectations. The test extends this class to provide the actual
* results of the query, which are then compared with the expected results in comments to produce a
* list of failure messages that point out where the actual results differ from the expected
* results.

View File

@@ -1,56 +0,0 @@
using System;
public record Point(int X, int Y);
public record Line(Point P1, Point P2);
public record Wrap(Line L);
public class PropertyPatterns
{
private static Line l = new Line(new Point(1, 2), new Point(3, 6));
private static Wrap w = new Wrap(l);
public void M1()
{
if (l is { P1: { X: 1 } })
{
}
if (l is { P1.X: 2 })
{
}
}
public void M2()
{
if (w is { L: { P2: { Y: 3 } } })
{
}
if (w is { L.P2.Y: 4 })
{
}
}
public void M3()
{
if (w is { L: { P2.Y: 5 } })
{
}
if (w is { L.P2: { Y: 6 } })
{
}
}
public void M4()
{
if (l is { P1: { X: 7 }, P1: { Y: 8 } })
{
}
if (l is { P1.X: 9, P1.Y: 10 })
{
}
}
}

View File

@@ -1,73 +0,0 @@
propertyPatterns
| PropertyPatterns.cs:14:18:14:33 | { ... } |
| PropertyPatterns.cs:14:24:14:31 | { ... } |
| PropertyPatterns.cs:18:18:18:28 | { ... } |
| PropertyPatterns.cs:18:20:18:21 | { ... } |
| PropertyPatterns.cs:25:18:25:40 | { ... } |
| PropertyPatterns.cs:25:23:25:38 | { ... } |
| PropertyPatterns.cs:25:29:25:36 | { ... } |
| PropertyPatterns.cs:29:18:29:30 | { ... } |
| PropertyPatterns.cs:29:20:29:20 | { ... } |
| PropertyPatterns.cs:29:22:29:23 | { ... } |
| PropertyPatterns.cs:36:18:36:35 | { ... } |
| PropertyPatterns.cs:36:23:36:33 | { ... } |
| PropertyPatterns.cs:36:25:36:26 | { ... } |
| PropertyPatterns.cs:40:18:40:35 | { ... } |
| PropertyPatterns.cs:40:20:40:20 | { ... } |
| PropertyPatterns.cs:40:26:40:33 | { ... } |
| PropertyPatterns.cs:47:18:47:47 | { ... } |
| PropertyPatterns.cs:47:24:47:31 | { ... } |
| PropertyPatterns.cs:47:38:47:45 | { ... } |
| PropertyPatterns.cs:51:18:51:38 | { ... } |
| PropertyPatterns.cs:51:20:51:21 | { ... } |
| PropertyPatterns.cs:51:29:51:30 | { ... } |
propertyPatternChild
| PropertyPatterns.cs:14:18:14:33 | { ... } | 0 | PropertyPatterns.cs:14:24:14:31 | { ... } |
| PropertyPatterns.cs:14:24:14:31 | { ... } | 0 | PropertyPatterns.cs:14:29:14:29 | 1 |
| PropertyPatterns.cs:18:18:18:28 | { ... } | 0 | PropertyPatterns.cs:18:20:18:21 | { ... } |
| PropertyPatterns.cs:18:20:18:21 | { ... } | 0 | PropertyPatterns.cs:18:26:18:26 | 2 |
| PropertyPatterns.cs:25:18:25:40 | { ... } | 0 | PropertyPatterns.cs:25:23:25:38 | { ... } |
| PropertyPatterns.cs:25:23:25:38 | { ... } | 0 | PropertyPatterns.cs:25:29:25:36 | { ... } |
| PropertyPatterns.cs:25:29:25:36 | { ... } | 0 | PropertyPatterns.cs:25:34:25:34 | 3 |
| PropertyPatterns.cs:29:18:29:30 | { ... } | 0 | PropertyPatterns.cs:29:20:29:20 | { ... } |
| PropertyPatterns.cs:29:20:29:20 | { ... } | 0 | PropertyPatterns.cs:29:22:29:23 | { ... } |
| PropertyPatterns.cs:29:22:29:23 | { ... } | 0 | PropertyPatterns.cs:29:28:29:28 | 4 |
| PropertyPatterns.cs:36:18:36:35 | { ... } | 0 | PropertyPatterns.cs:36:23:36:33 | { ... } |
| PropertyPatterns.cs:36:23:36:33 | { ... } | 0 | PropertyPatterns.cs:36:25:36:26 | { ... } |
| PropertyPatterns.cs:36:25:36:26 | { ... } | 0 | PropertyPatterns.cs:36:31:36:31 | 5 |
| PropertyPatterns.cs:40:18:40:35 | { ... } | 0 | PropertyPatterns.cs:40:20:40:20 | { ... } |
| PropertyPatterns.cs:40:20:40:20 | { ... } | 0 | PropertyPatterns.cs:40:26:40:33 | { ... } |
| PropertyPatterns.cs:40:26:40:33 | { ... } | 0 | PropertyPatterns.cs:40:31:40:31 | 6 |
| PropertyPatterns.cs:47:18:47:47 | { ... } | 0 | PropertyPatterns.cs:47:24:47:31 | { ... } |
| PropertyPatterns.cs:47:18:47:47 | { ... } | 1 | PropertyPatterns.cs:47:38:47:45 | { ... } |
| PropertyPatterns.cs:47:24:47:31 | { ... } | 0 | PropertyPatterns.cs:47:29:47:29 | 7 |
| PropertyPatterns.cs:47:38:47:45 | { ... } | 0 | PropertyPatterns.cs:47:43:47:43 | 8 |
| PropertyPatterns.cs:51:18:51:38 | { ... } | 0 | PropertyPatterns.cs:51:20:51:21 | { ... } |
| PropertyPatterns.cs:51:18:51:38 | { ... } | 1 | PropertyPatterns.cs:51:29:51:30 | { ... } |
| PropertyPatterns.cs:51:20:51:21 | { ... } | 0 | PropertyPatterns.cs:51:26:51:26 | 9 |
| PropertyPatterns.cs:51:29:51:30 | { ... } | 0 | PropertyPatterns.cs:51:35:51:36 | 10 |
propertyPatternLabels
| PropertyPatterns.cs:14:24:14:31 | { ... } | P1 |
| PropertyPatterns.cs:14:29:14:29 | 1 | X |
| PropertyPatterns.cs:18:20:18:21 | { ... } | P1 |
| PropertyPatterns.cs:18:26:18:26 | 2 | X |
| PropertyPatterns.cs:25:23:25:38 | { ... } | L |
| PropertyPatterns.cs:25:29:25:36 | { ... } | P2 |
| PropertyPatterns.cs:25:34:25:34 | 3 | Y |
| PropertyPatterns.cs:29:20:29:20 | { ... } | L |
| PropertyPatterns.cs:29:22:29:23 | { ... } | P2 |
| PropertyPatterns.cs:29:28:29:28 | 4 | Y |
| PropertyPatterns.cs:36:23:36:33 | { ... } | L |
| PropertyPatterns.cs:36:25:36:26 | { ... } | P2 |
| PropertyPatterns.cs:36:31:36:31 | 5 | Y |
| PropertyPatterns.cs:40:20:40:20 | { ... } | L |
| PropertyPatterns.cs:40:26:40:33 | { ... } | P2 |
| PropertyPatterns.cs:40:31:40:31 | 6 | Y |
| PropertyPatterns.cs:47:24:47:31 | { ... } | P1 |
| PropertyPatterns.cs:47:29:47:29 | 7 | X |
| PropertyPatterns.cs:47:38:47:45 | { ... } | P1 |
| PropertyPatterns.cs:47:43:47:43 | 8 | Y |
| PropertyPatterns.cs:51:20:51:21 | { ... } | P1 |
| PropertyPatterns.cs:51:26:51:26 | 9 | X |
| PropertyPatterns.cs:51:29:51:30 | { ... } | P1 |
| PropertyPatterns.cs:51:35:51:36 | 10 | Y |

View File

@@ -1,11 +0,0 @@
import csharp
query predicate propertyPatterns(PropertyPatternExpr exp) { any() }
query predicate propertyPatternChild(PropertyPatternExpr pp, int n, PatternExpr child) {
child = pp.getPattern(n)
}
query predicate propertyPatternLabels(LabeledPatternExpr exp, string label) {
label = exp.getLabel()
}

View File

@@ -1,7 +1,4 @@
recordTypes
| PropertyPatterns.cs:3:1:3:34 | Point |
| PropertyPatterns.cs:4:1:4:39 | Line |
| PropertyPatterns.cs:5:1:5:27 | Wrap |
| RecordTypes.cs:3:1:6:2 | MyEntry |
| RecordTypes.cs:8:1:8:53 | MyClassRecord |
| RecordTypes.cs:10:1:10:70 | MyReadonlyRecordStruct |
@@ -12,8 +9,5 @@ recordStructs
| RecordTypes.cs:12:1:12:51 | MyRecordStruct1 |
| WithExpression.cs:9:1:9:47 | MyRecordStruct2 |
recordClass
| PropertyPatterns.cs:3:1:3:34 | Point |
| PropertyPatterns.cs:4:1:4:39 | Line |
| PropertyPatterns.cs:5:1:5:27 | Wrap |
| RecordTypes.cs:3:1:6:2 | MyEntry |
| RecordTypes.cs:8:1:8:53 | MyClassRecord |

View File

@@ -1 +1 @@
| normal.cs:0:0:0:0 | normal.cs | 4 |
| normal.cs:0:0:0:0 | normal.cs | 0 |

View File

@@ -1 +1 @@
| standalone.cs:0:0:0:0 | standalone.cs | 5 |
| standalone.cs:0:0:0:0 | standalone.cs | 1 |

View File

@@ -82,7 +82,7 @@ For example, the following query computes, for each folder, the number of JavaSc
Locations
^^^^^^^^^
Most entities in a CodeQL database have an associated source location. Locations are identified by five pieces of information: a file, a start line, a start column, an end line, and an end column. Line and column counts are 1-based (so the first character of a file is at line 1, column 1), and the end position is inclusive.
Most entities in a CodeQL database have an associated source location. Locations are identified by four pieces of information: a file, a start line, a start column, an end line, and an end column. Line and column counts are 1-based (so the first character of a file is at line 1, column 1), and the end position is inclusive.
All entities associated with a source location belong to the class `Locatable <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Locations.qll/type.Locations$Locatable.html>`__. The location itself is modeled by the class `Location <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Locations.qll/type.Locations$Location.html>`__ and can be accessed through the member predicate ``Locatable.getLocation()``. The `Location <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Locations.qll/type.Locations$Location.html>`__ class provides the following member predicates:

View File

@@ -33,7 +33,7 @@ java.lang,8,,58,,,,,,,,,,8,,,,,,,,,,,,,,,46,12
java.net,10,3,7,,,,,,,,,,,,,10,,,,,,,,,,,3,7,
java.nio,15,,6,,13,,,,,,,,,,,,,,,,,2,,,,,,6,
java.sql,7,,,,,,,,,,,,,,,,,,7,,,,,,,,,,
java.util,34,,438,,,,,,,,,,34,,,,,,,,,,,,,,,24,414
java.util,34,,430,,,,,,,,,,34,,,,,,,,,,,,,,,16,414
javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,2,,7,,
javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,100,23
javax.management.remote,2,,,,,,,,,,2,,,,,,,,,,,,,,,,,,
1 package sink source summary sink:bean-validation sink:create-file sink:groovy sink:header-splitting sink:information-leak sink:intent-start sink:jexl sink:jndi-injection sink:ldap sink:logging sink:mvel sink:ognl-injection sink:open-url sink:pending-intent-sent sink:set-hostname-verifier sink:sql sink:url-open-stream sink:url-redirect sink:write-file sink:xpath sink:xslt sink:xss source:contentprovider source:remote summary:taint summary:value
33 java.net 10 3 7 10 3 7
34 java.nio 15 6 13 2 6
35 java.sql 7 7
36 java.util 34 438 430 34 24 16 414
37 javax.faces.context 2 7 2 7
38 javax.json 123 100 23
39 javax.management.remote 2 2

View File

@@ -15,9 +15,9 @@ Java framework & library support
`Apache HttpComponents <https://hc.apache.org/>`_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,136,28,,,3,,,,25
`Google Guava <https://guava.dev/>`_,``com.google.common.*``,,728,35,,6,,,,,
`JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,,,
Java Standard Library,``java.*``,3,541,111,28,,,7,,,10
Java Standard Library,``java.*``,3,533,111,28,,,7,,,10
Java extensions,"``javax.*``, ``jakarta.*``",54,552,32,,,4,,1,1,2
`Spring <https://spring.io/>`_,``org.springframework.*``,29,472,96,,,,19,14,,29
Others,"``androidx.slice``, ``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.unboundid.ldap.sdk``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.logging.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jboss.logging``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``",44,283,921,,,,14,18,,
Totals,,182,6220,1424,106,6,10,107,33,1,81
Totals,,182,6212,1424,106,6,10,107,33,1,81

View File

@@ -1,6 +1,4 @@
name: codeql/java-examples
groups:
- java
- examples
version: 0.0.2
dependencies:
codeql/java-all: "*"
codeql/java-all: "*"

View File

@@ -78,12 +78,10 @@ private import FlowSummary
private module Frameworks {
private import internal.ContainerFlow
private import semmle.code.java.frameworks.android.Android
private import semmle.code.java.frameworks.android.ContentProviders
private import semmle.code.java.frameworks.android.Intent
private import semmle.code.java.frameworks.android.Notifications
private import semmle.code.java.frameworks.android.Slice
private import semmle.code.java.frameworks.android.SQLite
private import semmle.code.java.frameworks.android.Widget
private import semmle.code.java.frameworks.android.XssSinks
private import semmle.code.java.frameworks.ApacheHttp
private import semmle.code.java.frameworks.apache.Collections
@@ -101,7 +99,6 @@ private module Frameworks {
private import semmle.code.java.frameworks.Logging
private import semmle.code.java.frameworks.Objects
private import semmle.code.java.frameworks.Optional
private import semmle.code.java.frameworks.Regex
private import semmle.code.java.frameworks.Stream
private import semmle.code.java.frameworks.Strings
private import semmle.code.java.frameworks.ratpack.Ratpack

View File

@@ -1290,7 +1290,7 @@ class DataFlowCallOption extends TDataFlowCallOption {
}
}
/** A `Content` tagged with the type of a containing object. */
/** Content tagged with the type of a containing object. */
class TypedContent extends MkTypedContent {
private Content c;
private DataFlowType t;

View File

@@ -90,9 +90,7 @@ module Public {
predicate contains(SummaryComponent c) { c = this.drop(_).head() }
/** Gets the bottom element of this stack. */
SummaryComponent bottom() {
this = TSingletonSummaryComponentStack(result) or result = this.tail().bottom()
}
SummaryComponent bottom() { result = this.drop(this.length() - 1).head() }
/** Gets a textual representation of this stack. */
string toString() {

View File

@@ -1,20 +0,0 @@
/** Definitions related to `java.util.regex`. */
import semmle.code.java.dataflow.ExternalFlow
private class RegexModel extends SummaryModelCsv {
override predicate row(string s) {
s =
[
//`namespace; type; subtypes; name; signature; ext; input; output; kind`
"java.util.regex;Matcher;false;group;;;Argument[-1];ReturnValue;taint",
"java.util.regex;Matcher;false;replaceAll;;;Argument[-1];ReturnValue;taint",
"java.util.regex;Matcher;false;replaceAll;;;Argument[0];ReturnValue;taint",
"java.util.regex;Matcher;false;replaceFirst;;;Argument[-1];ReturnValue;taint",
"java.util.regex;Matcher;false;replaceFirst;;;Argument[0];ReturnValue;taint",
"java.util.regex;Pattern;false;matcher;;;Argument[0];ReturnValue;taint",
"java.util.regex;Pattern;false;quote;;;Argument[0];ReturnValue;taint",
"java.util.regex;Pattern;false;split;;;Argument[0];ReturnValue;taint",
]
}
}

View File

@@ -25,7 +25,6 @@ class ThriftIface extends Interface {
this.getFile() instanceof ThriftGeneratedFile
}
/** Gets an implementation of a method of this interface. */
Method getAnImplementingMethod() {
result.getDeclaringType().(Class).getASupertype+() = this and
result.overrides+(this.getAMethod()) and

View File

@@ -177,6 +177,42 @@ private class UriModel extends SummaryModelCsv {
}
}
private class ContentProviderSourceModels extends SourceModelCsv {
override predicate row(string row) {
row =
[
// ContentInterface models are here for backwards compatibility (it was removed in API 28)
"android.content;ContentInterface;true;call;(String,String,String,Bundle);;Parameter[0..3];contentprovider",
"android.content;ContentProvider;true;call;(String,String,String,Bundle);;Parameter[0..3];contentprovider",
"android.content;ContentProvider;true;call;(String,String,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;delete;(Uri,String,String[]);;Parameter[0..2];contentprovider",
"android.content;ContentInterface;true;delete;(Uri,Bundle);;Parameter[0..1];contentprovider",
"android.content;ContentProvider;true;delete;(Uri,Bundle);;Parameter[0..1];contentprovider",
"android.content;ContentInterface;true;getType;(Uri);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;getType;(Uri);;Parameter[0];contentprovider",
"android.content;ContentInterface;true;insert;(Uri,ContentValues,Bundle);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;insert;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;insert;(Uri,ContentValues);;Parameter[0..1];contentprovider",
"android.content;ContentInterface;true;openAssetFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;openAssetFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;openAssetFile;(Uri,String);;Parameter[0];contentprovider",
"android.content;ContentInterface;true;openTypedAssetFile;(Uri,String,Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;openTypedAssetFile;(Uri,String,Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;openTypedAssetFile;(Uri,String,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentInterface;true;openFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;openFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;openFile;(Uri,String);;Parameter[0];contentprovider",
"android.content;ContentInterface;true;query;(Uri,String[],Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;query;(Uri,String[],Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;query;(Uri,String[],String,String[],String);;Parameter[0..4];contentprovider",
"android.content;ContentProvider;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Parameter[0..4];contentprovider",
"android.content;ContentInterface;true;update;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;update;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;update;(Uri,ContentValues,String,String[]);;Parameter[0..3];contentprovider"
]
}
}
/** Interface for classes whose instances can be written to and restored from a Parcel. */
class TypeParcelable extends Interface {
TypeParcelable() { this.hasQualifiedName("android.os", "Parcelable") }

View File

@@ -1,59 +0,0 @@
/**
* Provides classes and predicates for working with Content Providers.
*/
import java
import semmle.code.java.dataflow.ExternalFlow
/** The class `android.content.ContentValues`. */
class ContentValues extends Class {
ContentValues() { this.hasQualifiedName("android.content", "ContentValues") }
}
private class ContentProviderSourceModels extends SourceModelCsv {
override predicate row(string row) {
row =
[
// ContentInterface models are here for backwards compatibility (it was removed in API 28)
"android.content;ContentInterface;true;call;(String,String,String,Bundle);;Parameter[0..3];contentprovider",
"android.content;ContentProvider;true;call;(String,String,String,Bundle);;Parameter[0..3];contentprovider",
"android.content;ContentProvider;true;call;(String,String,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;delete;(Uri,String,String[]);;Parameter[0..2];contentprovider",
"android.content;ContentInterface;true;delete;(Uri,Bundle);;Parameter[0..1];contentprovider",
"android.content;ContentProvider;true;delete;(Uri,Bundle);;Parameter[0..1];contentprovider",
"android.content;ContentInterface;true;getType;(Uri);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;getType;(Uri);;Parameter[0];contentprovider",
"android.content;ContentInterface;true;insert;(Uri,ContentValues,Bundle);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;insert;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;insert;(Uri,ContentValues);;Parameter[0..1];contentprovider",
"android.content;ContentInterface;true;openAssetFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;openAssetFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;openAssetFile;(Uri,String);;Parameter[0];contentprovider",
"android.content;ContentInterface;true;openTypedAssetFile;(Uri,String,Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;openTypedAssetFile;(Uri,String,Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;openTypedAssetFile;(Uri,String,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentInterface;true;openFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;openFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;openFile;(Uri,String);;Parameter[0];contentprovider",
"android.content;ContentInterface;true;query;(Uri,String[],Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;query;(Uri,String[],Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;query;(Uri,String[],String,String[],String);;Parameter[0..4];contentprovider",
"android.content;ContentProvider;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Parameter[0..4];contentprovider",
"android.content;ContentInterface;true;update;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;update;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;update;(Uri,ContentValues,String,String[]);;Parameter[0..3];contentprovider"
]
}
}
private class SummaryModels extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"android.content;ContentValues;false;put;;;Argument[0];MapKey of Argument[-1];value",
"android.content;ContentValues;false;put;;;Argument[1];MapValue of Argument[-1];value",
"android.content;ContentValues;false;putAll;;;MapKey of Argument[0];MapKey of Argument[-1];value",
"android.content;ContentValues;false;putAll;;;MapValue of Argument[0];MapValue of Argument[-1];value"
]
}
}

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