Merge branch 'mathiasvp/replace-ast-with-ir-use-usedataflow' into global-flow

This commit is contained in:
Mathias Vorreiter Pedersen
2023-02-01 13:37:10 +00:00
230 changed files with 21422 additions and 6426 deletions

View File

@@ -5,6 +5,11 @@ updates:
schedule:
interval: "daily"
- package-ecosystem: "cargo"
directory: "ql"
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
schedule:

View File

@@ -27,7 +27,7 @@ jobs:
uses: ./.github/actions/find-latest-bundle
- name: Find codeql
id: find-codeql
uses: github/codeql-action/init@45955cb1830b640e2c1603ad72ad542a49d47b96
uses: github/codeql-action/init@beae46e6b1da530ed5e9fc6a756f92433ca47ae1
with:
languages: javascript # does not matter
tools: ${{ steps.find-latest-bundle.outputs.url }}
@@ -139,7 +139,7 @@ jobs:
env:
CONF: ./ql-for-ql-config.yml
- name: Initialize CodeQL
uses: github/codeql-action/init@45955cb1830b640e2c1603ad72ad542a49d47b96
uses: github/codeql-action/init@beae46e6b1da530ed5e9fc6a756f92433ca47ae1
with:
languages: ql
db-location: ${{ runner.temp }}/db
@@ -152,7 +152,7 @@ jobs:
PACK: ${{ runner.temp }}/pack
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@45955cb1830b640e2c1603ad72ad542a49d47b96
uses: github/codeql-action/analyze@beae46e6b1da530ed5e9fc6a756f92433ca47ae1
with:
category: "ql-for-ql"
- name: Copy sarif file to CWD

View File

@@ -25,7 +25,7 @@ jobs:
- name: Find codeql
id: find-codeql
uses: github/codeql-action/init@45955cb1830b640e2c1603ad72ad542a49d47b96
uses: github/codeql-action/init@beae46e6b1da530ed5e9fc6a756f92433ca47ae1
with:
languages: javascript # does not matter
- uses: ./.github/actions/os-version

View File

@@ -6,11 +6,13 @@ on:
paths:
- "ql/**"
- codeql-workspace.yml
- .github/workflows/ql-for-ql-tests.yml
pull_request:
branches: [main]
paths:
- "ql/**"
- codeql-workspace.yml
- .github/workflows/ql-for-ql-tests.yml
env:
CARGO_TERM_COLOR: always
@@ -22,7 +24,7 @@ jobs:
- uses: actions/checkout@v3
- name: Find codeql
id: find-codeql
uses: github/codeql-action/init@45955cb1830b640e2c1603ad72ad542a49d47b96
uses: github/codeql-action/init@beae46e6b1da530ed5e9fc6a756f92433ca47ae1
with:
languages: javascript # does not matter
- uses: ./.github/actions/os-version
@@ -65,7 +67,7 @@ jobs:
echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH
- name: Find codeql
id: find-codeql
uses: github/codeql-action/init@77a8d2d10c0b403a8b4aadbd223dc489ecd22683
uses: github/codeql-action/init@beae46e6b1da530ed5e9fc6a756f92433ca47ae1
with:
languages: javascript # does not matter
- uses: ./.github/actions/os-version

View File

@@ -36,7 +36,6 @@
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll",
"swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll"

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -0,0 +1,263 @@
private import cpp
private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
float evaluateConstantExpr(Expr e) {
result = e.getValue().toFloat()
or
// This handles when a constant value is put into a variable
// and the variable is used later
exists(SsaDefinition defn, StackVariable sv |
defn.getAUse(sv) = e and
result = defn.getDefiningValue(sv).getValue().toFloat()
)
}
// If the constant right operand is negative or is greater than or equal to the number of
// bits in the left operands type, then the result is undefined (except on the IA-32
// architecture where the shift value is masked with 0b00011111, but we can't
// assume the architecture).
bindingset[val]
private predicate isValidShiftExprShift(float val, Expr l) {
val >= 0 and
// We use getFullyConverted because the spec says to use the *promoted* left operand
val < (l.getFullyConverted().getUnderlyingType().getSize() * 8)
}
bindingset[val, shift, max_val]
private predicate canLShiftOverflow(int val, int shift, int max_val) {
// val << shift = val * 2^shift > max_val => val > max_val/2^shift = max_val >> b
val > max_val.bitShiftRight(shift)
}
/**
* A range analysis expression consisting of the `>>` or `>>=` operator when at least
* one operand is a constant (and if the right operand is a constant, it must be "valid"
* (see `isValidShiftExprShift`)). When handling any undefined behavior, it leaves the
* values unconstrained. From the C++ standard: "The behavior is undefined if the right
* operand is negative, or greater than or equal to the length in bits of the promoted
* left operand. The value of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an
* unsigned type or if E1 has a signed type and a non-negative value, the value of the
* result is the integral part of the quotient of E1/2^E2. If E1 has a signed type and a
* negative value, the resulting value is implementation-defined."
*/
class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
/**
* Holds for `a >> b` or `a >>= b` in one of the following two cases:
* 1. `a` is a constant and `b` is not
* 2. `b` is constant
*
* We don't handle the case where `a` and `b` are both non-constant values.
*/
ConstantRShiftExprRange() {
getUnspecifiedType() instanceof IntegralType and
exists(Expr l, Expr r |
l = this.(RShiftExpr).getLeftOperand() and
r = this.(RShiftExpr).getRightOperand()
or
l = this.(AssignRShiftExpr).getLValue() and
r = this.(AssignRShiftExpr).getRValue()
|
l.getUnspecifiedType() instanceof IntegralType and
r.getUnspecifiedType() instanceof IntegralType and
(
// If the left operand is a constant, verify that the right operand is not a constant
exists(evaluateConstantExpr(l)) and not exists(evaluateConstantExpr(r))
or
// If the right operand is a constant, check if it is a valid shift expression
exists(float constROp |
constROp = evaluateConstantExpr(r) and isValidShiftExprShift(constROp, l)
)
)
)
}
Expr getLeftOperand() {
result = this.(RShiftExpr).getLeftOperand() or
result = this.(AssignRShiftExpr).getLValue()
}
Expr getRightOperand() {
result = this.(RShiftExpr).getRightOperand() or
result = this.(AssignRShiftExpr).getRValue()
}
override float getLowerBounds() {
exists(int lLower, int lUpper, int rLower, int rUpper |
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
lLower <= lUpper and
rLower <= rUpper
|
if
lLower < 0
or
not (
isValidShiftExprShift(rLower, getLeftOperand()) and
isValidShiftExprShift(rUpper, getLeftOperand())
)
then
// We don't want to deal with shifting negative numbers at the moment,
// and a negative shift is implementation defined, so we set the result
// to the minimum value
result = exprMinVal(this)
else
// We can get the smallest value by shifting the smallest bound by the largest bound
result = lLower.bitShiftRight(rUpper)
)
}
override float getUpperBounds() {
exists(int lLower, int lUpper, int rLower, int rUpper |
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
lLower <= lUpper and
rLower <= rUpper
|
if
lLower < 0
or
not (
isValidShiftExprShift(rLower, getLeftOperand()) and
isValidShiftExprShift(rUpper, getLeftOperand())
)
then
// We don't want to deal with shifting negative numbers at the moment,
// and a negative shift is implementation defined, so we set the result
// to the maximum value
result = exprMaxVal(this)
else
// We can get the largest value by shifting the largest bound by the smallest bound
result = lUpper.bitShiftRight(rLower)
)
}
override predicate dependsOnChild(Expr child) {
child = getLeftOperand() or child = getRightOperand()
}
}
/**
* A range analysis expression consisting of the `<<` or `<<=` operator when at least
* one operand is a constant (and if the right operand is a constant, it must be "valid"
* (see `isValidShiftExprShift`)). When handling any undefined behavior, it leaves the
* values unconstrained. From the C++ standard: "The behavior is undefined if the right
* operand is negative, or greater than or equal to the length in bits of the promoted left operand.
* The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1
* has an unsigned type, the value of the result is E1 x 2 E2, reduced modulo one more than the
* maximum value representable in the result type. Otherwise, if E1 has a signed type and
* non-negative value, and E1 x 2 E2 is representable in the corresponding unsigned type of the
* result type, then that value, converted to the result type, is the resulting value; otherwise,
* the behavior is undefined."
*/
class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
/**
* Holds for `a << b` or `a <<= b` in one of the following two cases:
* 1. `a` is a constant and `b` is not
* 2. `b` is constant
*
* We don't handle the case where `a` and `b` are both non-constant values.
*/
ConstantLShiftExprRange() {
getUnspecifiedType() instanceof IntegralType and
exists(Expr l, Expr r |
l = this.(LShiftExpr).getLeftOperand() and
r = this.(LShiftExpr).getRightOperand()
or
l = this.(AssignLShiftExpr).getLValue() and
r = this.(AssignLShiftExpr).getRValue()
|
l.getUnspecifiedType() instanceof IntegralType and
r.getUnspecifiedType() instanceof IntegralType and
(
// If the left operand is a constant, verify that the right operand is not a constant
exists(evaluateConstantExpr(l)) and not exists(evaluateConstantExpr(r))
or
// If the right operand is a constant, check if it is a valid shift expression
exists(float constROp |
constROp = evaluateConstantExpr(r) and isValidShiftExprShift(constROp, l)
)
)
)
}
Expr getLeftOperand() {
result = this.(LShiftExpr).getLeftOperand() or
result = this.(AssignLShiftExpr).getLValue()
}
Expr getRightOperand() {
result = this.(LShiftExpr).getRightOperand() or
result = this.(AssignLShiftExpr).getRValue()
}
override float getLowerBounds() {
exists(int lLower, int lUpper, int rLower, int rUpper |
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
lLower <= lUpper and
rLower <= rUpper
|
if
lLower < 0
or
not (
isValidShiftExprShift(rLower, getLeftOperand()) and
isValidShiftExprShift(rUpper, getLeftOperand())
)
then
// We don't want to deal with shifting negative numbers at the moment,
// and a negative shift is undefined, so we set to the minimum value
result = exprMinVal(this)
else
// If we have `0b01010000 << [0, 2]`, the max value for 8 bits is 0b10100000
// (a shift of 1) but doing a shift by the upper bound would give 0b01000000.
// So if the left shift operation causes an overflow, we just assume the max value
// If necessary, we may be able to improve this bound in the future
if canLShiftOverflow(lUpper, rUpper, exprMaxVal(this))
then result = exprMinVal(this)
else result = lLower.bitShiftLeft(rLower)
)
}
override float getUpperBounds() {
exists(int lLower, int lUpper, int rLower, int rUpper |
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
lLower <= lUpper and
rLower <= rUpper
|
if
lLower < 0
or
not (
isValidShiftExprShift(rLower, getLeftOperand()) and
isValidShiftExprShift(rUpper, getLeftOperand())
)
then
// We don't want to deal with shifting negative numbers at the moment,
// and a negative shift is undefined, so we set it to the maximum value
result = exprMaxVal(this)
else
// If we have `0b01010000 << [0, 2]`, the max value for 8 bits is 0b10100000
// (a shift of 1) but doing a shift by the upper bound would give 0b01000000.
// So if the left shift operation causes an overflow, we just assume the max value
// If necessary, we may be able to improve this bound in the future
if canLShiftOverflow(lUpper, rUpper, exprMaxVal(this))
then result = exprMaxVal(this)
else result = lUpper.bitShiftLeft(rUpper)
)
}
override predicate dependsOnChild(Expr child) {
child = getLeftOperand() or child = getRightOperand()
}
}

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -370,7 +370,7 @@ class ReturnIndirectionNode extends IndirectReturnNode, ReturnNode {
private Operand fullyConvertedCallStep(Operand op) {
not exists(getANonConversionUse(op)) and
exists(Instruction instr |
conversionFlow(op, instr, _) and
conversionFlow(op, instr, _, _) and
result = getAUse(instr)
)
}
@@ -397,7 +397,7 @@ Operand getAUse(Instruction instr) {
*/
private Instruction getANonConversionUse(Operand operand) {
result = getUse(operand) and
not conversionFlow(_, result, _)
not conversionFlow(_, result, _, _)
}
/**
@@ -559,7 +559,7 @@ private predicate numberOfLoadsFromOperandRec(Operand operandFrom, Operand opera
or
exists(Operand op, Instruction instr |
instr = op.getDef() and
conversionFlow(operandFrom, instr, _) and
conversionFlow(operandFrom, instr, _, _) and
numberOfLoadsFromOperand(op, operandTo, ind)
)
}
@@ -572,7 +572,7 @@ private predicate numberOfLoadsFromOperand(Operand operandFrom, Operand operandT
numberOfLoadsFromOperandRec(operandFrom, operandTo, n)
or
not Ssa::isDereference(_, operandFrom) and
not conversionFlow(operandFrom, _, _) and
not conversionFlow(operandFrom, _, _, _) and
operandFrom = operandTo and
n = 0
}
@@ -697,7 +697,9 @@ class Unit extends TUnit {
/** Holds if `n` should be hidden from path explanations. */
predicate nodeIsHidden(Node n) {
n instanceof OperandNode and not n instanceof ArgumentNode
n instanceof OperandNode and
not n instanceof ArgumentNode and
not n.asOperand() instanceof StoreValueOperand
or
n instanceof FinalGlobalValue
or

View File

@@ -81,9 +81,16 @@ class FieldAddress extends Operand {
*
* `isPointerArith` is `true` if `instrTo` is a `PointerArithmeticInstruction` and `opFrom`
* is the left operand.
*
* `additional` is `true` if the conversion is supplied by an implementation of the
* `Indirection` class. It is sometimes useful to exclude such conversions.
*/
predicate conversionFlow(Operand opFrom, Instruction instrTo, boolean isPointerArith) {
predicate conversionFlow(
Operand opFrom, Instruction instrTo, boolean isPointerArith, boolean additional
) {
isPointerArith = false and
(
additional = false and
(
instrTo.(CopyValueInstruction).getSourceValueOperand() = opFrom
or
@@ -92,11 +99,14 @@ predicate conversionFlow(Operand opFrom, Instruction instrTo, boolean isPointerA
instrTo.(CheckedConvertOrNullInstruction).getUnaryOperand() = opFrom
or
instrTo.(InheritanceConversionInstruction).getUnaryOperand() = opFrom
)
or
additional = true and
Ssa::isAdditionalConversionFlow(opFrom, instrTo)
)
or
isPointerArith = true and
additional = false and
instrTo.(PointerArithmeticInstruction).getLeftOperand() = opFrom
}
@@ -1445,7 +1455,7 @@ private module Cached {
private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo) {
// Treat all conversions as flow, even conversions between different numeric types.
conversionFlow(opFrom, iTo, false)
conversionFlow(opFrom, iTo, false, _)
or
iTo.(CopyInstruction).getSourceValueOperand() = opFrom
}

View File

@@ -392,7 +392,20 @@ class FinalParameterUse extends UseImpl, TFinalParameterUse {
override predicate isCertain() { any() }
override predicate hasIndexInBlock(IRBlock block, int index) {
exists(ReturnInstruction return |
// Ideally, this should always be a `ReturnInstruction`, but if
// someone forgets to write a `return` statement in a function
// with a non-void return type we generate an `UnreachedInstruction`.
// In this case we still want to generate flow out of such functions
// if they write to a parameter. So we pick the index of the
// `UnreachedInstruction` as the index of this use.
// Note that a function may have both a `ReturnInstruction` and an
// `UnreachedInstruction`. If that's the case this predicate will
// return multiple results. I don't think this is detrimental to
// performance, however.
exists(Instruction return |
return instanceof ReturnInstruction or
return instanceof UnreachedInstruction
|
block.getInstruction(index) = return and
return.getEnclosingFunction() = p.getFunction()
)
@@ -571,7 +584,7 @@ private predicate indirectConversionFlowStep(Node nFrom, Node nTo) {
hasOperandAndIndex(nFrom, op1, pragma[only_bind_into](indirectionIndex)) and
hasOperandAndIndex(nTo, op2, pragma[only_bind_into](indirectionIndex)) and
instr = op2.getDef() and
conversionFlow(op1, instr, _)
conversionFlow(op1, instr, _, _)
)
}

View File

@@ -208,7 +208,7 @@ private module IteratorIndirections {
override predicate isAdditionalDereference(Instruction deref, Operand address) {
exists(CallInstruction call |
operandForfullyConvertedCall(deref.getAUse(), call) and
operandForfullyConvertedCall(getAUse(deref), call) and
this = call.getStaticCallTarget().getClassAndName("operator*") and
address = call.getThisArgumentOperand()
)
@@ -538,6 +538,7 @@ private module Cached {
numberOfLoads >= 0 and
isUse(_, iteratorDerefAddress, iteratorBase, numberOfLoads + 2, 0) and
iteratorBase.getResultType() instanceof Interfaces::Iterator and
load.getSourceAddressOperand() = iteratorDerefAddress and
read.getPrimaryInstruction() = load.getSourceAddress() and
memory = read.getSideEffectOperand().getAnyDef()
)
@@ -585,6 +586,15 @@ private module Cached {
)
}
/** Holds if `op` is the only use of its defining instruction, and that op is used in a conversation */
private predicate isConversion(Operand op) {
exists(Instruction def, Operand use |
def = op.getDef() and
use = unique( | | getAUse(def)) and
conversionFlow(use, _, false, false)
)
}
/**
* Holds if `op` is a use of an SSA variable rooted at `base` with `ind` number
* of indirections.
@@ -602,6 +612,9 @@ private module Cached {
type = getLanguageType(op) and
upper = countIndirectionsForCppType(type) and
isUseImpl(op, base, ind0) and
// Don't count every conversion as their own use. Instead, only the first
// use (i.e., before any conversions are applied) will count as a use.
not isConversion(op) and
ind = ind0 + [0 .. upper] and
indirectionIndex = ind - ind0
)
@@ -652,7 +665,7 @@ private module Cached {
exists(Operand mid, Instruction instr |
isUseImpl(mid, base, ind) and
instr = operand.getDef() and
conversionFlow(mid, instr, false)
conversionFlow(mid, instr, false, _)
)
or
exists(int ind0 |
@@ -722,7 +735,7 @@ private module Cached {
exists(Operand mid, Instruction instr, boolean certain0, boolean isPointerArith |
isDefImpl(mid, base, ind, certain0) and
instr = operand.getDef() and
conversionFlow(mid, instr, isPointerArith) and
conversionFlow(mid, instr, isPointerArith, _) and
if isPointerArith = true then certain = false else certain = certain0
)
or

View File

@@ -155,8 +155,21 @@ private class FinalParameterUse extends UseImpl, TFinalParameterUse {
override string toString() { result = p.toString() }
final override predicate hasIndexInBlock(IRBlock block, int index) {
exists(ReturnInstruction return |
block.getInstruction(index + 1) = return and
// Ideally, this should always be a `ReturnInstruction`, but if
// someone forgets to write a `return` statement in a function
// with a non-void return type we generate an `UnreachedInstruction`.
// In this case we still want to generate flow out of such functions
// if they write to a parameter. So we pick the index of the
// `UnreachedInstruction` as the index of this use.
// Note that a function may have both a `ReturnInstruction` and an
// `UnreachedInstruction`. If that's the case this predicate will
// return multiple results. I don't think this is detrimental to
// performance, however.
exists(Instruction return |
return instanceof ReturnInstruction or
return instanceof UnreachedInstruction
|
block.getInstruction(index) = return and
return.getEnclosingFunction() = p.getFunction()
)
}

View File

@@ -412,6 +412,9 @@ class CallTargetOperand extends RegisterOperand {
*/
class ArgumentOperand extends RegisterOperand {
override ArgumentOperandTag tag;
/** Gets the `CallInstruction` for which this is an argument. */
CallInstruction getCall() { result.getAnArgumentOperand() = this }
}
/**

View File

@@ -412,6 +412,9 @@ class CallTargetOperand extends RegisterOperand {
*/
class ArgumentOperand extends RegisterOperand {
override ArgumentOperandTag tag;
/** Gets the `CallInstruction` for which this is an argument. */
CallInstruction getCall() { result.getAnArgumentOperand() = this }
}
/**

View File

@@ -412,6 +412,9 @@ class CallTargetOperand extends RegisterOperand {
*/
class ArgumentOperand extends RegisterOperand {
override ArgumentOperandTag tag;
/** Gets the `CallInstruction` for which this is an argument. */
CallInstruction getCall() { result.getAnArgumentOperand() = this }
}
/**

View File

@@ -107,130 +107,34 @@ private FunctionInput getIteratorArgumentInput(Operator op, int index) {
)
}
/**
* A non-member prefix `operator*` function for an iterator type.
*/
private class IteratorPointerDereferenceOperator extends Operator, TaintFunction,
IteratorReferenceFunction {
FunctionInput iteratorInput;
IteratorPointerDereferenceOperator() {
this.hasName("operator*") and
iteratorInput = getIteratorArgumentInput(this, 0)
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = iteratorInput and
output.isReturnValue()
or
input.isReturnValueDeref() and
output.isParameterDeref(0)
}
}
/**
* A non-member `operator++` or `operator--` function for an iterator type.
*
* Note that this class _only_ matches non-member functions. To find both
* non-member and versions, use `IteratorCrementOperator`.
*/
private class IteratorCrementOperator extends Operator, DataFlowFunction {
FunctionInput iteratorInput;
IteratorCrementOperator() {
class IteratorCrementNonMemberOperator extends Operator {
IteratorCrementNonMemberOperator() {
this.hasName(["operator++", "operator--"]) and
iteratorInput = getIteratorArgumentInput(this, 0)
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input = iteratorInput and
output.isReturnValue()
or
input.isParameterDeref(0) and output.isReturnValueDeref()
}
}
/**
* A non-member `operator+` function for an iterator type.
*/
private class IteratorAddOperator extends Operator, TaintFunction {
FunctionInput iteratorInput;
IteratorAddOperator() {
this.hasName("operator+") and
iteratorInput = getIteratorArgumentInput(this, [0, 1])
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = iteratorInput and
output.isReturnValue()
}
}
/**
* A non-member `operator-` function that takes a pointer difference type as its second argument.
*/
private class IteratorSubOperator extends Operator, TaintFunction {
FunctionInput iteratorInput;
IteratorSubOperator() {
this.hasName("operator-") and
iteratorInput = getIteratorArgumentInput(this, 0) and
this.getParameter(1).getUnspecifiedType() instanceof IntegralType // not an iterator difference
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = iteratorInput and
output.isReturnValue()
}
}
/**
* A non-member `operator+=` or `operator-=` function for an iterator type.
*/
class IteratorAssignArithmeticOperator extends Operator {
IteratorAssignArithmeticOperator() {
this.hasName(["operator+=", "operator-="]) and
exists(getIteratorArgumentInput(this, 0))
}
}
private class IteratorAssignArithmeticOperatorModel extends IteratorAssignArithmeticOperator,
DataFlowFunction, TaintFunction {
private class IteratorCrementNonMemberOperatorModel extends IteratorCrementNonMemberOperator,
DataFlowFunction {
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and
input = getIteratorArgumentInput(this, 0) and
output.isReturnValue()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
or
input.isParameterDeref(0) and output.isReturnValueDeref()
or
// reverse flow from returned reference to the object referenced by the first parameter
input.isReturnValueDeref() and
output.isParameterDeref(0)
or
(input.isParameter(1) or input.isParameterDeref(1)) and
output.isParameterDeref(0)
}
}
/**
* A prefix `operator*` member function for an iterator type.
*/
class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction,
IteratorReferenceFunction {
IteratorPointerDereferenceMemberOperator() {
this.getClassAndName("operator*") instanceof Iterator
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
output.isReturnValue()
or
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
/**
* An `operator++` or `operator--` member function for an iterator type.
*
* Note that this class _only_ matches member functions. To find both
* non-member and member versions, use `IteratorCrementOperator`.
*/
class IteratorCrementMemberOperator extends MemberFunction {
IteratorCrementMemberOperator() {
@@ -258,25 +162,49 @@ private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOp
}
/**
* A member `operator->` function for an iterator type.
* A (member or non-member) `operator++` or `operator--` function for an iterator type.
*/
private class IteratorFieldMemberOperator extends Operator, TaintFunction {
IteratorFieldMemberOperator() { this.getClassAndName("operator->") instanceof Iterator }
class IteratorCrementOperator extends Function {
IteratorCrementOperator() {
this instanceof IteratorCrementNonMemberOperator or
this instanceof IteratorCrementMemberOperator
}
}
/**
* A non-member `operator+` function for an iterator type.
*
* Note that this class _only_ matches non-member functions. To find both
* non-member and member versions, use `IteratorBinaryAddOperator`.
*/
class IteratorAddNonMemberOperator extends Operator {
IteratorAddNonMemberOperator() {
this.hasName("operator+") and
exists(getIteratorArgumentInput(this, [0, 1]))
}
}
private class IteratorAddNonMemberOperatorModel extends IteratorAddNonMemberOperator, TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
input = getIteratorArgumentInput(this, [0, 1]) and
output.isReturnValue()
}
}
/**
* An `operator+` or `operator-` member function of an iterator class.
*
* Note that this class _only_ matches member functions. To find both
* non-member and member versions, use `IteratorBinaryAddOperator`.
*/
private class IteratorBinaryArithmeticMemberOperator extends MemberFunction, TaintFunction {
class IteratorBinaryArithmeticMemberOperator extends MemberFunction {
IteratorBinaryArithmeticMemberOperator() {
this.getClassAndName(["operator+", "operator-"]) instanceof Iterator
}
}
private class IteratorBinaryArithmeticMemberOperatorModel extends IteratorBinaryArithmeticMemberOperator,
TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
output.isReturnValue()
@@ -284,14 +212,84 @@ private class IteratorBinaryArithmeticMemberOperator extends MemberFunction, Tai
}
/**
* An `operator+=` or `operator-=` member function of an iterator class.
* A (member or non-member) `operator+` or `operator-` function for an iterator type.
*/
private class IteratorAssignArithmeticMemberOperator extends MemberFunction, DataFlowFunction,
TaintFunction {
class IteratorBinaryArithmeticOperator extends Function {
IteratorBinaryArithmeticOperator() {
this instanceof IteratorAddNonMemberOperator or
this instanceof IteratorSubNonMemberOperator or
this instanceof IteratorBinaryArithmeticMemberOperator
}
}
/**
* A non-member `operator-` function that takes a pointer difference type as its second argument.
*
* Note that this class _only_ matches non-member functions. To find both
* non-member and member versions, use `IteratorBinaryArithmeticOperator` (which also
* includes `operator+` versions).
*/
class IteratorSubNonMemberOperator extends Operator {
IteratorSubNonMemberOperator() {
this.hasName("operator-") and
exists(getIteratorArgumentInput(this, 0)) and
this.getParameter(1).getUnspecifiedType() instanceof IntegralType // not an iterator difference
}
}
private class IteratorSubOperatorModel extends IteratorSubNonMemberOperator, TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = getIteratorArgumentInput(this, 0) and
output.isReturnValue()
}
}
/**
* A non-member `operator+=` or `operator-=` function for an iterator type.
*
* Note that this class _only_ matches non-member functions. To find both
* non-member and member versions, use `IteratorAssignArithmeticOperator`.
*/
class IteratorAssignArithmeticNonMemberOperator extends Operator {
IteratorAssignArithmeticNonMemberOperator() {
this.hasName(["operator+=", "operator-="]) and
exists(getIteratorArgumentInput(this, 0))
}
}
private class IteratorAssignArithmeticNonMemberOperatorModel extends IteratorAssignArithmeticNonMemberOperator,
DataFlowFunction, TaintFunction {
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and
output.isReturnValue()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(0) and output.isReturnValueDeref()
or
// reverse flow from returned reference to the object referenced by the first parameter
input.isReturnValueDeref() and
output.isParameterDeref(0)
or
(input.isParameter(1) or input.isParameterDeref(1)) and
output.isParameterDeref(0)
}
}
/**
* An `operator+=` or `operator-=` member function of an iterator class.
*
* Note that this class _only_ matches member functions. To find both
* non-member and member versions, use `IteratorAssignArithmeticOperator`.
*/
class IteratorAssignArithmeticMemberOperator extends MemberFunction {
IteratorAssignArithmeticMemberOperator() {
this.getClassAndName(["operator+=", "operator-="]) instanceof Iterator
}
}
private class IteratorAssignArithmeticMemberOperatorModel extends IteratorAssignArithmeticMemberOperator,
DataFlowFunction, TaintFunction {
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierAddress() and
output.isReturnValue()
@@ -310,6 +308,83 @@ private class IteratorAssignArithmeticMemberOperator extends MemberFunction, Dat
}
}
/**
* A (member or non-member) `operator+=` or `operator-=` function for an iterator type.
*/
class IteratorAssignArithmeticOperator extends Function {
IteratorAssignArithmeticOperator() {
this instanceof IteratorAssignArithmeticNonMemberOperator or
this instanceof IteratorAssignArithmeticMemberOperator
}
}
/**
* A prefix `operator*` member function for an iterator type.
*
* Note that this class _only_ matches member functions. To find both
* non-member and member versions, use `IteratorPointerDereferenceOperator`.
*/
class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction,
IteratorReferenceFunction {
IteratorPointerDereferenceMemberOperator() {
this.getClassAndName("operator*") instanceof Iterator
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
output.isReturnValue()
or
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
/**
* A non-member prefix `operator*` function for an iterator type.
*
* Note that this class _only_ matches non-member functions. To find both
* non-member and member versions, use `IteratorPointerDereferenceOperator`.
*/
class IteratorPointerDereferenceNonMemberOperator extends Operator, IteratorReferenceFunction {
IteratorPointerDereferenceNonMemberOperator() {
this.hasName("operator*") and
exists(getIteratorArgumentInput(this, 0))
}
}
private class IteratorPointerDereferenceNonMemberOperatorModel extends IteratorPointerDereferenceNonMemberOperator,
TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = getIteratorArgumentInput(this, 0) and
output.isReturnValue()
or
input.isReturnValueDeref() and
output.isParameterDeref(0)
}
}
/**
* A (member or non-member) prefix `operator*` function for an iterator type.
*/
class IteratorPointerDereferenceOperator extends Function {
IteratorPointerDereferenceOperator() {
this instanceof IteratorPointerDereferenceNonMemberOperator or
this instanceof IteratorPointerDereferenceMemberOperator
}
}
/**
* A member `operator->` function for an iterator type.
*/
private class IteratorFieldMemberOperator extends Operator, TaintFunction {
IteratorFieldMemberOperator() { this.getClassAndName("operator->") instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
output.isReturnValue()
}
}
/**
* An `operator[]` member function of an iterator class.
*/
@@ -326,17 +401,24 @@ private class IteratorArrayMemberOperator extends MemberFunction, TaintFunction,
/**
* An `operator=` member function of an iterator class that is not a copy or move assignment
* operator.
*
* The `hasTaintFlow` override provides flow through output iterators that return themselves with
* `operator*` and use their own `operator=` to assign to the container.
*/
private class IteratorAssignmentMemberOperator extends MemberFunction, TaintFunction {
class IteratorAssignmentMemberOperator extends MemberFunction {
IteratorAssignmentMemberOperator() {
this.getClassAndName("operator=") instanceof Iterator and
not this instanceof CopyAssignmentOperator and
not this instanceof MoveAssignmentOperator
}
}
/**
* An `operator=` member function of an iterator class that is not a copy or move assignment
* operator.
*
* The `hasTaintFlow` override provides flow through output iterators that return themselves with
* `operator*` and use their own `operator=` to assign to the container.
*/
private class IteratorAssignmentMemberOperatorModel extends IteratorAssignmentMemberOperator,
TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(0) and
output.isQualifierObject()

View File

@@ -120,11 +120,7 @@ pragma[noinline]
predicate isSanitizerNode(DataFlow::Node node) {
underscoreMacro(node.asExpr())
or
not exists(node.asIndirectExpr()) and
not exists(node.asDefiningArgument()) and
not exists(node.asIndirectVariable()) and
not node instanceof DataFlow::InitialGlobalValue and
not node instanceof DataFlow::FinalGlobalValue and
exists(node.asExpr()) and
cannotContainString(node.getType(), false)
}

View File

@@ -0,0 +1,44 @@
| bitshift.cpp:23:3:23:9 | ... <<= ... | 0.0 | 255.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
| bitshift.cpp:25:5:25:11 | ... <<= ... | 0.0 | 240.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
| bitshift.cpp:29:3:29:8 | ... << ... | 0.0 | 1020.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:32:3:32:9 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:35:3:35:9 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:38:3:38:22 | ... << ... | 0.0 | 32640.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:39:3:39:22 | ... << ... | 0.0 | 32640.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:40:3:40:22 | ... << ... | 0.0 | 32640.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:43:3:43:19 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:46:3:46:22 | ... << ... | 128.0 | 128.0 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:49:3:49:8 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:52:5:52:10 | ... << ... | 1.0 | 128.0 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:57:3:57:8 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:58:3:58:9 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:59:3:59:9 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:60:3:60:22 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:61:3:61:19 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:64:3:64:19 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:67:3:67:8 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:70:5:70:10 | ... << ... | 1.0 | 128.0 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:75:5:75:10 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:76:5:76:10 | ... << ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:90:3:90:9 | ... >>= ... | 0.0 | 63.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
| bitshift.cpp:92:5:92:11 | ... >>= ... | 0.0 | 15.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int |
| bitshift.cpp:96:3:96:8 | ... >> ... | 0.0 | 63.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:99:3:99:9 | ... >> ... | 0.0 | 0.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:103:3:103:9 | ... >> ... | 0.0 | 0.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:106:3:106:22 | ... >> ... | 0.0 | 63.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:107:3:107:22 | ... >> ... | 0.0 | 63.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:108:3:108:22 | ... >> ... | 0.0 | 63.0 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:111:3:111:19 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:114:3:114:24 | ... >> ... | 32.0 | 32.0 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:117:3:117:10 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:120:5:120:12 | ... >> ... | 32.0 | 128.0 | file://:0:0:0:0 | int | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:126:3:126:8 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:127:3:127:9 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:128:3:128:9 | ... >> ... | -1.0 | 0.0 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:129:3:129:22 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:130:3:130:19 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:133:3:133:21 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:136:3:136:10 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:139:5:139:12 | ... >> ... | 32.0 | 128.0 | file://:0:0:0:0 | int | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:144:5:144:10 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | signed char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |
| bitshift.cpp:145:5:145:10 | ... >> ... | -2.147483648E9 | 2.147483647E9 | file://:0:0:0:0 | signed char | file://:0:0:0:0 | unsigned char | file://:0:0:0:0 | int | file://:0:0:0:0 | int |

View File

@@ -0,0 +1,24 @@
import cpp
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
import experimental.semmle.code.cpp.rangeanalysis.extensions.ConstantShiftExprRange
Expr getLOp(Operation o) {
result = o.(BinaryOperation).getLeftOperand() or
result = o.(Assignment).getLValue()
}
Expr getROp(Operation o) {
result = o.(BinaryOperation).getRightOperand() or
result = o.(Assignment).getRValue()
}
from Operation o
where
(
o instanceof BinaryBitwiseOperation
or
o instanceof AssignBitwiseOperation
)
select o, lowerBound(o), upperBound(o), getLOp(o).getUnderlyingType(),
getROp(o).getUnderlyingType(), getLOp(o).getFullyConverted().getUnderlyingType(),
getROp(o).getFullyConverted().getUnderlyingType()

View File

@@ -0,0 +1,147 @@
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long uint64_t;
extern uint8_t value_known_at_runtime8();
void testLShiftOperator() {
uint8_t unsigned_const1 = 7;
uint8_t unsigned_const2(7);
uint8_t unsigned_const3{7};
int8_t signed_const = -7;
uint8_t x = value_known_at_runtime8();
int8_t y = (int8_t)value_known_at_runtime8();
uint8_t z = value_known_at_runtime8();
// An assign left shift operator. Note that no promotion occurs here
z <<= 2; // [0, 255]
if (z <= 60) {
z <<= 2; // [0, 240]
}
// A normal shift
x << 2; // [0, 1020]
// Possible to exceed the maximum size
x << 25; // [-2147483648, 2147483648]
// Undefined behavior
x << 34; // [-2147483648, 2147483648]
// A normal shift by a constant in a variable
x << unsigned_const1; // [0, 32640]
x << unsigned_const2; // [0, 32640]
x << unsigned_const3; // [0, 32640]
// Negative shifts are undefined
x << signed_const; // [-2147483648, 2147483648]
// Now the left operand is a constant
1 << unsigned_const1; // [128, 128]
// x could be large enough to cause undefined behavior
1 << x; // [-2147483648, 2147483647]
if (x < 8) {
// x is now constrained so the shift is defined
1 << x; // [1, 128]
}
// We don't support shifting negative values (and some of these are undefined
// anyway)
y << 2; // [-2147483648, 2147483647]
y << 25; // [-2147483648, 2147483648]
y << 34; // [-2147483648, 2147483648]
y << unsigned_const1; // [-2147483648, 2147483647]
y << signed_const; // [-2147483648, 2147483648]
// Negative shifts are undefined
1 << signed_const; // [-2147483648, 2147483648]
// We don't handle cases where the shift range could be negative
1 << y; // [-2147483648, 2147483648]
if (y >= 0 && y < 8) {
// The shift range is now positive
1 << y; // [1, 128]
}
if (x > 0 and x < 2 and y > 0 and x < 2) {
// We don't support shifts where neither operand is a constant at the moment
x << y; // [-2147483648, 2147483648]
y << x; // [-2147483648, 2147483648]
}
}
void testRShiftOperator() {
uint8_t unsigned_const1 = 2;
uint8_t unsigned_const2(2);
uint8_t unsigned_const3{2};
int8_t signed_const = -2;
uint8_t x = value_known_at_runtime8();
int8_t y = (int8_t)value_known_at_runtime8();
uint8_t z = value_known_at_runtime8();
// An assign right shift operator. Note that no promotion occurs here
z >>= 2; // [0, 63]
if (z <= 60) {
z >>= 2; // [0, 15]
}
// A normal shift
x >> 2; // [0, 63]
// Possible to exceed the maximum size
x >> 25; // [0, 0]
// Undefined behavior, but this case is handled by the SimpleRangeAnalysis
// library and sets the the bounds to [0, 0], which is fine
x >> 34; // [0, 0]
// A normal shift by a constant in a variable
x >> unsigned_const1; // [0, 63]
x >> unsigned_const2; // [0, 63]
x >> unsigned_const3; // [0, 63]
// Negative shifts are undefined
x >> signed_const; // [-2147483648, 2147483648]
// Now the left operand is a constant
128 >> unsigned_const1; // [32, 32]
// x could be large enough to cause undefined behavior
128 >> x; // [-2147483648, 2147483647]
if (x < 3) {
// x is now constrained so the shift is defined
128 >> x; // [32, 128]
}
// We don't support shifting negative values, but the SimpleRangeAnalysis
// library handles the first three cases even though they're implementation
// defined or undefined behavior (TODO: Check ideone)
y >> 2; // [-2147483648, 2147483647] (Default is [-32, 31])
y >> 25; // -2147483648, 2147483647] (Default is [-1, 0])
y >> 34; // [-1, 0] (My code doesn't touch this, so default code is used)
y >> unsigned_const1; // [-2147483648, 2147483647]
y >> signed_const; // [-2147483648, 2147483648]
// Negative shifts are undefined
128 >> signed_const; // [-2147483648, 2147483648]
// We don't handle cases where the shift range could be negative
128 >> y; // [-2147483648, 2147483648]
if (y >= 0 && y < 3) {
// The shift range is now positive
128 >> y; // [32, 128]
}
if (x > 0 and x < 2 and y > 0 and x < 2) {
// We don't support shifts where neither operand is a constant at the moment
x >> y; // [-2147483648, 2147483648]
y >> x; // [-2147483648, 2147483648]
}
}

View File

@@ -1,4 +1,5 @@
edges
| test.cpp:45:18:45:23 | buffer | test.cpp:45:7:45:10 | func indirection |
| test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode |
| test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode |
| test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode |
@@ -6,7 +7,9 @@ edges
| test.cpp:74:24:74:30 | medical | test.cpp:81:22:81:28 | medical |
| test.cpp:77:16:77:22 | medical | test.cpp:78:24:78:27 | temp |
| test.cpp:77:16:77:22 | medical | test.cpp:81:22:81:28 | medical |
| test.cpp:81:22:81:28 | medical | test.cpp:82:24:82:28 | buff5 |
| test.cpp:81:17:81:20 | call to func | test.cpp:82:24:82:28 | buff5 |
| test.cpp:81:22:81:28 | medical | test.cpp:45:18:45:23 | buffer |
| test.cpp:81:22:81:28 | medical | test.cpp:81:17:81:20 | call to func |
| test.cpp:96:37:96:46 | theZipcode | test.cpp:96:37:96:46 | theZipcode |
| test.cpp:96:37:96:46 | theZipcode | test.cpp:96:37:96:46 | theZipcode |
| test.cpp:96:37:96:46 | theZipcode | test.cpp:96:37:96:46 | theZipcode |
@@ -23,6 +26,8 @@ edges
| test.cpp:99:61:99:70 | theZipcode | test.cpp:99:42:99:51 | theZipcode |
| test.cpp:99:61:99:70 | theZipcode | test.cpp:99:42:99:51 | theZipcode |
nodes
| test.cpp:45:7:45:10 | func indirection | semmle.label | func indirection |
| test.cpp:45:18:45:23 | buffer | semmle.label | buffer |
| test.cpp:57:9:57:18 | theZipcode | semmle.label | theZipcode |
| test.cpp:57:9:57:18 | theZipcode | semmle.label | theZipcode |
| test.cpp:57:9:57:18 | theZipcode | semmle.label | theZipcode |
@@ -30,6 +35,7 @@ nodes
| test.cpp:74:24:74:30 | medical | semmle.label | medical |
| test.cpp:77:16:77:22 | medical | semmle.label | medical |
| test.cpp:78:24:78:27 | temp | semmle.label | temp |
| test.cpp:81:17:81:20 | call to func | semmle.label | call to func |
| test.cpp:81:22:81:28 | medical | semmle.label | medical |
| test.cpp:82:24:82:28 | buff5 | semmle.label | buff5 |
| test.cpp:96:37:96:46 | theZipcode | semmle.label | theZipcode |
@@ -42,6 +48,7 @@ nodes
| test.cpp:99:61:99:70 | theZipcode | semmle.label | theZipcode |
| test.cpp:99:61:99:70 | theZipcode | semmle.label | theZipcode |
subpaths
| test.cpp:81:22:81:28 | medical | test.cpp:45:18:45:23 | buffer | test.cpp:45:7:45:10 | func indirection | test.cpp:81:17:81:20 | call to func |
#select
| test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@. | test.cpp:57:9:57:18 | theZipcode | this source of private data. |
| test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@. | test.cpp:57:9:57:18 | theZipcode | this source of private data. |

View File

@@ -48,5 +48,5 @@ void following_pointers(
int stackArray[2] = { source(), source() };
stackArray[0] = source();
sink(stackArray); // $ ast ir ir=49:35 ir=50:19
sink(stackArray); // $ ast ir
}

View File

@@ -510,7 +510,7 @@ int intOutparamSourceMissingReturn(int *p) {
void viaOutparamMissingReturn() {
int x = 0;
intOutparamSourceMissingReturn(&x);
sink(x); // $ ast MISSING: ir
sink(x); // $ ast,ir
}
void uncertain_definition() {
@@ -533,12 +533,12 @@ void test_set_through_const_pointer(int *e)
}
void sink_then_source_1(int* p) {
sink(*p); // $ SPURIOUS: ir=537:10 ir=547:9
sink(*p); // $ ir // Flow from the unitialized x to the dereference.
*p = source();
}
void sink_then_source_2(int* p, int y) {
sink(y); // $ SPURIOUS: ast ir=542:10 ir=551:9
sink(y); // $ SPURIOUS: ast ir
*p = source();
}

View File

@@ -4,8 +4,9 @@ edges
| A.cpp:27:17:27:17 | c | A.cpp:27:22:27:32 | ... = ... |
| A.cpp:27:22:27:32 | ... = ... | A.cpp:27:28:27:28 | this indirection [post update] [c] |
| A.cpp:28:8:28:10 | this indirection [c] | A.cpp:28:23:28:26 | this indirection [c] |
| A.cpp:28:23:28:26 | this indirection [c] | A.cpp:28:8:28:10 | get indirection |
| A.cpp:28:23:28:26 | this indirection [c] | A.cpp:28:29:28:29 | c |
| A.cpp:28:23:28:26 | this indirection [c] | A.cpp:28:29:28:29 | c indirection |
| A.cpp:28:29:28:29 | c | A.cpp:28:8:28:10 | get indirection |
| A.cpp:28:29:28:29 | c indirection | A.cpp:28:8:28:10 | get indirection |
| A.cpp:29:23:29:23 | c | A.cpp:31:20:31:20 | c |
| A.cpp:31:14:31:21 | call to B [c] | A.cpp:29:15:29:18 | make indirection [c] |
@@ -13,8 +14,6 @@ edges
| A.cpp:31:20:31:20 | c | A.cpp:31:14:31:21 | call to B [c] |
| A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... indirection |
| A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... indirection |
| A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... indirection |
| A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... indirection |
| A.cpp:47:12:47:18 | new | A.cpp:48:20:48:20 | c |
| A.cpp:48:12:48:18 | call to make indirection [c] | A.cpp:49:10:49:10 | b indirection [c] |
| A.cpp:48:20:48:20 | c | A.cpp:29:23:29:23 | c |
@@ -209,8 +208,9 @@ edges
| C.cpp:31:10:31:11 | this indirection [s3] | C.cpp:31:10:31:11 | s3 |
| C.cpp:31:10:31:11 | this indirection [s3] | C.cpp:31:10:31:11 | s3 indirection |
| D.cpp:10:11:10:17 | this indirection [elem] | D.cpp:10:30:10:33 | this indirection [elem] |
| D.cpp:10:30:10:33 | elem | D.cpp:10:11:10:17 | getElem indirection |
| D.cpp:10:30:10:33 | elem indirection | D.cpp:10:11:10:17 | getElem indirection |
| D.cpp:10:30:10:33 | this indirection [elem] | D.cpp:10:11:10:17 | getElem indirection |
| D.cpp:10:30:10:33 | this indirection [elem] | D.cpp:10:30:10:33 | elem |
| D.cpp:10:30:10:33 | this indirection [elem] | D.cpp:10:30:10:33 | elem indirection |
| D.cpp:11:24:11:24 | e | D.cpp:11:29:11:36 | ... = ... |
| D.cpp:11:29:11:36 | ... = ... | D.cpp:11:29:11:32 | this indirection [post update] [elem] |
@@ -441,19 +441,23 @@ edges
| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:11:48:11:52 | value |
| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] |
| by_reference.cpp:31:46:31:46 | s indirection [a] | by_reference.cpp:32:12:32:12 | s indirection [a] |
| by_reference.cpp:32:12:32:12 | s indirection [a] | by_reference.cpp:31:16:31:28 | nonMemberGetA indirection |
| by_reference.cpp:32:12:32:12 | s indirection [a] | by_reference.cpp:32:15:32:15 | a |
| by_reference.cpp:32:12:32:12 | s indirection [a] | by_reference.cpp:32:15:32:15 | a indirection |
| by_reference.cpp:32:15:32:15 | a | by_reference.cpp:31:16:31:28 | nonMemberGetA indirection |
| by_reference.cpp:32:15:32:15 | a indirection | by_reference.cpp:31:16:31:28 | nonMemberGetA indirection |
| by_reference.cpp:35:9:35:19 | this indirection [a] | by_reference.cpp:36:12:36:15 | this indirection [a] |
| by_reference.cpp:36:12:36:15 | this indirection [a] | by_reference.cpp:35:9:35:19 | getDirectly indirection |
| by_reference.cpp:36:12:36:15 | this indirection [a] | by_reference.cpp:36:18:36:18 | a |
| by_reference.cpp:36:12:36:15 | this indirection [a] | by_reference.cpp:36:18:36:18 | a indirection |
| by_reference.cpp:36:18:36:18 | a | by_reference.cpp:35:9:35:19 | getDirectly indirection |
| by_reference.cpp:36:18:36:18 | a indirection | by_reference.cpp:35:9:35:19 | getDirectly indirection |
| by_reference.cpp:39:9:39:21 | this indirection [a] | by_reference.cpp:40:12:40:15 | this indirection [a] |
| by_reference.cpp:40:12:40:15 | this indirection [a] | by_reference.cpp:35:9:35:19 | this indirection [a] |
| by_reference.cpp:40:12:40:15 | this indirection [a] | by_reference.cpp:39:9:39:21 | getIndirectly indirection |
| by_reference.cpp:40:12:40:15 | this indirection [a] | by_reference.cpp:40:18:40:28 | call to getDirectly |
| by_reference.cpp:40:18:40:28 | call to getDirectly | by_reference.cpp:39:9:39:21 | getIndirectly indirection |
| by_reference.cpp:43:9:43:27 | this indirection [a] | by_reference.cpp:44:26:44:29 | this indirection [a] |
| by_reference.cpp:44:12:44:24 | call to nonMemberGetA | by_reference.cpp:43:9:43:27 | getThroughNonMember indirection |
| by_reference.cpp:44:26:44:29 | this indirection [a] | by_reference.cpp:31:46:31:46 | s indirection [a] |
| by_reference.cpp:44:26:44:29 | this indirection [a] | by_reference.cpp:43:9:43:27 | getThroughNonMember indirection |
| by_reference.cpp:44:26:44:29 | this indirection [a] | by_reference.cpp:44:12:44:24 | call to nonMemberGetA |
| by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | by_reference.cpp:51:8:51:8 | (const S)... indirection [a] |
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:15:26:15:30 | value |
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:50:3:50:3 | setDirectly output argument [a] |
@@ -569,12 +573,14 @@ edges
| by_reference.cpp:136:8:136:13 | pouter indirection [a] | by_reference.cpp:136:16:136:16 | a indirection |
| by_reference.cpp:136:16:136:16 | a indirection | by_reference.cpp:136:16:136:16 | a |
| complex.cpp:9:7:9:7 | this indirection [a_] | complex.cpp:9:20:9:21 | this indirection [a_] |
| complex.cpp:9:20:9:21 | a_ | complex.cpp:9:7:9:7 | a indirection |
| complex.cpp:9:20:9:21 | a_ indirection | complex.cpp:9:7:9:7 | a indirection |
| complex.cpp:9:20:9:21 | this indirection [a_] | complex.cpp:9:7:9:7 | a indirection |
| complex.cpp:9:20:9:21 | this indirection [a_] | complex.cpp:9:20:9:21 | a_ |
| complex.cpp:9:20:9:21 | this indirection [a_] | complex.cpp:9:20:9:21 | a_ indirection |
| complex.cpp:10:7:10:7 | this indirection [b_] | complex.cpp:10:20:10:21 | this indirection [b_] |
| complex.cpp:10:20:10:21 | b_ | complex.cpp:10:7:10:7 | b indirection |
| complex.cpp:10:20:10:21 | b_ indirection | complex.cpp:10:7:10:7 | b indirection |
| complex.cpp:10:20:10:21 | this indirection [b_] | complex.cpp:10:7:10:7 | b indirection |
| complex.cpp:10:20:10:21 | this indirection [b_] | complex.cpp:10:20:10:21 | b_ |
| complex.cpp:10:20:10:21 | this indirection [b_] | complex.cpp:10:20:10:21 | b_ indirection |
| complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:27 | ... = ... |
| complex.cpp:11:22:11:27 | ... = ... | complex.cpp:11:22:11:23 | this indirection [post update] [a_] |
@@ -673,12 +679,14 @@ edges
| conflated.cpp:61:12:61:15 | next indirection [y] | conflated.cpp:61:18:61:18 | y indirection |
| conflated.cpp:61:18:61:18 | y indirection | conflated.cpp:61:18:61:18 | y |
| constructors.cpp:18:9:18:9 | this indirection [a_] | constructors.cpp:18:22:18:23 | this indirection [a_] |
| constructors.cpp:18:22:18:23 | a_ | constructors.cpp:18:9:18:9 | a indirection |
| constructors.cpp:18:22:18:23 | a_ indirection | constructors.cpp:18:9:18:9 | a indirection |
| constructors.cpp:18:22:18:23 | this indirection [a_] | constructors.cpp:18:9:18:9 | a indirection |
| constructors.cpp:18:22:18:23 | this indirection [a_] | constructors.cpp:18:22:18:23 | a_ |
| constructors.cpp:18:22:18:23 | this indirection [a_] | constructors.cpp:18:22:18:23 | a_ indirection |
| constructors.cpp:19:9:19:9 | this indirection [b_] | constructors.cpp:19:22:19:23 | this indirection [b_] |
| constructors.cpp:19:22:19:23 | b_ | constructors.cpp:19:9:19:9 | b indirection |
| constructors.cpp:19:22:19:23 | b_ indirection | constructors.cpp:19:9:19:9 | b indirection |
| constructors.cpp:19:22:19:23 | this indirection [b_] | constructors.cpp:19:9:19:9 | b indirection |
| constructors.cpp:19:22:19:23 | this indirection [b_] | constructors.cpp:19:22:19:23 | b_ |
| constructors.cpp:19:22:19:23 | this indirection [b_] | constructors.cpp:19:22:19:23 | b_ indirection |
| constructors.cpp:23:13:23:13 | a | constructors.cpp:23:28:23:28 | a |
| constructors.cpp:23:20:23:20 | b | constructors.cpp:23:35:23:35 | b |
@@ -789,12 +797,14 @@ edges
| realistic.cpp:61:47:61:55 | bufferLen indirection | realistic.cpp:61:14:61:55 | bufferLen |
| realistic.cpp:61:47:61:55 | bufferLen indirection | realistic.cpp:61:47:61:55 | bufferLen |
| simple.cpp:18:9:18:9 | this indirection [a_] | simple.cpp:18:22:18:23 | this indirection [a_] |
| simple.cpp:18:22:18:23 | a_ | simple.cpp:18:9:18:9 | a indirection |
| simple.cpp:18:22:18:23 | a_ indirection | simple.cpp:18:9:18:9 | a indirection |
| simple.cpp:18:22:18:23 | this indirection [a_] | simple.cpp:18:9:18:9 | a indirection |
| simple.cpp:18:22:18:23 | this indirection [a_] | simple.cpp:18:22:18:23 | a_ |
| simple.cpp:18:22:18:23 | this indirection [a_] | simple.cpp:18:22:18:23 | a_ indirection |
| simple.cpp:19:9:19:9 | this indirection [b_] | simple.cpp:19:22:19:23 | this indirection [b_] |
| simple.cpp:19:22:19:23 | b_ | simple.cpp:19:9:19:9 | b indirection |
| simple.cpp:19:22:19:23 | b_ indirection | simple.cpp:19:9:19:9 | b indirection |
| simple.cpp:19:22:19:23 | this indirection [b_] | simple.cpp:19:9:19:9 | b indirection |
| simple.cpp:19:22:19:23 | this indirection [b_] | simple.cpp:19:22:19:23 | b_ |
| simple.cpp:19:22:19:23 | this indirection [b_] | simple.cpp:19:22:19:23 | b_ indirection |
| simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:29 | ... = ... |
| simple.cpp:20:24:20:29 | ... = ... | simple.cpp:20:24:20:25 | this indirection [post update] [a_] |
@@ -829,9 +839,10 @@ edges
| simple.cpp:67:10:67:11 | a2 indirection [i] | simple.cpp:67:13:67:13 | i indirection |
| simple.cpp:67:13:67:13 | i indirection | simple.cpp:67:13:67:13 | i |
| simple.cpp:78:9:78:15 | this indirection [f2, f1] | simple.cpp:79:16:79:17 | this indirection [f2, f1] |
| simple.cpp:79:16:79:17 | f2 indirection [f1] | simple.cpp:78:9:78:15 | getf2f1 indirection |
| simple.cpp:79:16:79:17 | f2 indirection [f1] | simple.cpp:79:19:79:20 | f1 |
| simple.cpp:79:16:79:17 | f2 indirection [f1] | simple.cpp:79:19:79:20 | f1 indirection |
| simple.cpp:79:16:79:17 | this indirection [f2, f1] | simple.cpp:79:16:79:17 | f2 indirection [f1] |
| simple.cpp:79:19:79:20 | f1 | simple.cpp:78:9:78:15 | getf2f1 indirection |
| simple.cpp:79:19:79:20 | f1 indirection | simple.cpp:78:9:78:15 | getf2f1 indirection |
| simple.cpp:83:9:83:10 | this indirection [post update] [f2, f1] | simple.cpp:84:14:84:20 | this indirection [f2, f1] |
| simple.cpp:83:9:83:28 | ... = ... | simple.cpp:83:12:83:13 | f2 indirection [post update] [f1] |
@@ -899,6 +910,7 @@ nodes
| A.cpp:28:8:28:10 | get indirection | semmle.label | get indirection |
| A.cpp:28:8:28:10 | this indirection [c] | semmle.label | this indirection [c] |
| A.cpp:28:23:28:26 | this indirection [c] | semmle.label | this indirection [c] |
| A.cpp:28:29:28:29 | c | semmle.label | c |
| A.cpp:28:29:28:29 | c indirection | semmle.label | c indirection |
| A.cpp:29:15:29:18 | make indirection [c] | semmle.label | make indirection [c] |
| A.cpp:29:23:29:23 | c | semmle.label | c |
@@ -907,7 +919,6 @@ nodes
| A.cpp:41:15:41:21 | new | semmle.label | new |
| A.cpp:41:15:41:21 | new | semmle.label | new |
| A.cpp:43:10:43:12 | & ... indirection | semmle.label | & ... indirection |
| A.cpp:43:10:43:12 | & ... indirection | semmle.label | & ... indirection |
| A.cpp:47:12:47:18 | new | semmle.label | new |
| A.cpp:48:12:48:18 | call to make indirection [c] | semmle.label | call to make indirection [c] |
| A.cpp:48:20:48:20 | c | semmle.label | c |
@@ -1086,6 +1097,7 @@ nodes
| C.cpp:31:10:31:11 | this indirection [s3] | semmle.label | this indirection [s3] |
| D.cpp:10:11:10:17 | getElem indirection | semmle.label | getElem indirection |
| D.cpp:10:11:10:17 | this indirection [elem] | semmle.label | this indirection [elem] |
| D.cpp:10:30:10:33 | elem | semmle.label | elem |
| D.cpp:10:30:10:33 | elem indirection | semmle.label | elem indirection |
| D.cpp:10:30:10:33 | this indirection [elem] | semmle.label | this indirection [elem] |
| D.cpp:11:24:11:24 | e | semmle.label | e |
@@ -1306,16 +1318,20 @@ nodes
| by_reference.cpp:31:16:31:28 | nonMemberGetA indirection | semmle.label | nonMemberGetA indirection |
| by_reference.cpp:31:46:31:46 | s indirection [a] | semmle.label | s indirection [a] |
| by_reference.cpp:32:12:32:12 | s indirection [a] | semmle.label | s indirection [a] |
| by_reference.cpp:32:15:32:15 | a | semmle.label | a |
| by_reference.cpp:32:15:32:15 | a indirection | semmle.label | a indirection |
| by_reference.cpp:35:9:35:19 | getDirectly indirection | semmle.label | getDirectly indirection |
| by_reference.cpp:35:9:35:19 | this indirection [a] | semmle.label | this indirection [a] |
| by_reference.cpp:36:12:36:15 | this indirection [a] | semmle.label | this indirection [a] |
| by_reference.cpp:36:18:36:18 | a | semmle.label | a |
| by_reference.cpp:36:18:36:18 | a indirection | semmle.label | a indirection |
| by_reference.cpp:39:9:39:21 | getIndirectly indirection | semmle.label | getIndirectly indirection |
| by_reference.cpp:39:9:39:21 | this indirection [a] | semmle.label | this indirection [a] |
| by_reference.cpp:40:12:40:15 | this indirection [a] | semmle.label | this indirection [a] |
| by_reference.cpp:40:18:40:28 | call to getDirectly | semmle.label | call to getDirectly |
| by_reference.cpp:43:9:43:27 | getThroughNonMember indirection | semmle.label | getThroughNonMember indirection |
| by_reference.cpp:43:9:43:27 | this indirection [a] | semmle.label | this indirection [a] |
| by_reference.cpp:44:12:44:24 | call to nonMemberGetA | semmle.label | call to nonMemberGetA |
| by_reference.cpp:44:26:44:29 | this indirection [a] | semmle.label | this indirection [a] |
| by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | semmle.label | setDirectly output argument [a] |
| by_reference.cpp:50:17:50:26 | call to user_input | semmle.label | call to user_input |
@@ -1417,10 +1433,12 @@ nodes
| by_reference.cpp:136:16:136:16 | a indirection | semmle.label | a indirection |
| complex.cpp:9:7:9:7 | a indirection | semmle.label | a indirection |
| complex.cpp:9:7:9:7 | this indirection [a_] | semmle.label | this indirection [a_] |
| complex.cpp:9:20:9:21 | a_ | semmle.label | a_ |
| complex.cpp:9:20:9:21 | a_ indirection | semmle.label | a_ indirection |
| complex.cpp:9:20:9:21 | this indirection [a_] | semmle.label | this indirection [a_] |
| complex.cpp:10:7:10:7 | b indirection | semmle.label | b indirection |
| complex.cpp:10:7:10:7 | this indirection [b_] | semmle.label | this indirection [b_] |
| complex.cpp:10:20:10:21 | b_ | semmle.label | b_ |
| complex.cpp:10:20:10:21 | b_ indirection | semmle.label | b_ indirection |
| complex.cpp:10:20:10:21 | this indirection [b_] | semmle.label | this indirection [b_] |
| complex.cpp:11:17:11:17 | a | semmle.label | a |
@@ -1509,10 +1527,12 @@ nodes
| conflated.cpp:61:18:61:18 | y indirection | semmle.label | y indirection |
| constructors.cpp:18:9:18:9 | a indirection | semmle.label | a indirection |
| constructors.cpp:18:9:18:9 | this indirection [a_] | semmle.label | this indirection [a_] |
| constructors.cpp:18:22:18:23 | a_ | semmle.label | a_ |
| constructors.cpp:18:22:18:23 | a_ indirection | semmle.label | a_ indirection |
| constructors.cpp:18:22:18:23 | this indirection [a_] | semmle.label | this indirection [a_] |
| constructors.cpp:19:9:19:9 | b indirection | semmle.label | b indirection |
| constructors.cpp:19:9:19:9 | this indirection [b_] | semmle.label | this indirection [b_] |
| constructors.cpp:19:22:19:23 | b_ | semmle.label | b_ |
| constructors.cpp:19:22:19:23 | b_ indirection | semmle.label | b_ indirection |
| constructors.cpp:19:22:19:23 | this indirection [b_] | semmle.label | this indirection [b_] |
| constructors.cpp:23:13:23:13 | a | semmle.label | a |
@@ -1616,10 +1636,12 @@ nodes
| realistic.cpp:61:47:61:55 | bufferLen indirection | semmle.label | bufferLen indirection |
| simple.cpp:18:9:18:9 | a indirection | semmle.label | a indirection |
| simple.cpp:18:9:18:9 | this indirection [a_] | semmle.label | this indirection [a_] |
| simple.cpp:18:22:18:23 | a_ | semmle.label | a_ |
| simple.cpp:18:22:18:23 | a_ indirection | semmle.label | a_ indirection |
| simple.cpp:18:22:18:23 | this indirection [a_] | semmle.label | this indirection [a_] |
| simple.cpp:19:9:19:9 | b indirection | semmle.label | b indirection |
| simple.cpp:19:9:19:9 | this indirection [b_] | semmle.label | this indirection [b_] |
| simple.cpp:19:22:19:23 | b_ | semmle.label | b_ |
| simple.cpp:19:22:19:23 | b_ indirection | semmle.label | b_ indirection |
| simple.cpp:19:22:19:23 | this indirection [b_] | semmle.label | this indirection [b_] |
| simple.cpp:20:19:20:19 | a | semmle.label | a |
@@ -1656,6 +1678,7 @@ nodes
| simple.cpp:78:9:78:15 | this indirection [f2, f1] | semmle.label | this indirection [f2, f1] |
| simple.cpp:79:16:79:17 | f2 indirection [f1] | semmle.label | f2 indirection [f1] |
| simple.cpp:79:16:79:17 | this indirection [f2, f1] | semmle.label | this indirection [f2, f1] |
| simple.cpp:79:19:79:20 | f1 | semmle.label | f1 |
| simple.cpp:79:19:79:20 | f1 indirection | semmle.label | f1 indirection |
| simple.cpp:83:9:83:10 | this indirection [post update] [f2, f1] | semmle.label | this indirection [post update] [f2, f1] |
| simple.cpp:83:9:83:28 | ... = ... | semmle.label | ... = ... |
@@ -1732,6 +1755,8 @@ subpaths
| D.cpp:51:27:51:27 | e | D.cpp:11:24:11:24 | e | D.cpp:11:29:11:32 | this indirection [post update] [elem] | D.cpp:51:8:51:14 | setElem output argument [elem] |
| by_reference.cpp:20:23:20:27 | value | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:11:16:11 | this indirection [post update] [a] | by_reference.cpp:20:5:20:8 | setDirectly output argument [a] |
| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:8:12:8 | s indirection [post update] [a] | by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] |
| by_reference.cpp:40:12:40:15 | this indirection [a] | by_reference.cpp:35:9:35:19 | this indirection [a] | by_reference.cpp:35:9:35:19 | getDirectly indirection | by_reference.cpp:40:18:40:28 | call to getDirectly |
| by_reference.cpp:44:26:44:29 | this indirection [a] | by_reference.cpp:31:46:31:46 | s indirection [a] | by_reference.cpp:31:16:31:28 | nonMemberGetA indirection | by_reference.cpp:44:12:44:24 | call to nonMemberGetA |
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:11:16:11 | this indirection [post update] [a] | by_reference.cpp:50:3:50:3 | setDirectly output argument [a] |
| by_reference.cpp:51:8:51:8 | (const S)... indirection [a] | by_reference.cpp:35:9:35:19 | this indirection [a] | by_reference.cpp:35:9:35:19 | getDirectly indirection | by_reference.cpp:51:10:51:20 | call to getDirectly |
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:19:28:19:32 | value | by_reference.cpp:20:5:20:8 | setDirectly output argument [a] | by_reference.cpp:56:3:56:3 | setIndirectly output argument [a] |
@@ -1765,8 +1790,6 @@ subpaths
#select
| A.cpp:43:10:43:12 | & ... indirection | A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... indirection | & ... indirection flows from $@ | A.cpp:41:15:41:21 | new | new |
| A.cpp:43:10:43:12 | & ... indirection | A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... indirection | & ... indirection flows from $@ | A.cpp:41:15:41:21 | new | new |
| A.cpp:43:10:43:12 | & ... indirection | A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... indirection | & ... indirection flows from $@ | A.cpp:41:15:41:21 | new | new |
| A.cpp:43:10:43:12 | & ... indirection | A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... indirection | & ... indirection flows from $@ | A.cpp:41:15:41:21 | new | new |
| A.cpp:49:10:49:13 | c | A.cpp:47:12:47:18 | new | A.cpp:49:10:49:13 | c | c flows from $@ | A.cpp:47:12:47:18 | new | new |
| A.cpp:49:13:49:13 | c | A.cpp:47:12:47:18 | new | A.cpp:49:13:49:13 | c | c flows from $@ | A.cpp:47:12:47:18 | new | new |
| A.cpp:56:10:56:17 | call to get | A.cpp:55:12:55:19 | new | A.cpp:56:10:56:17 | call to get | call to get flows from $@ | A.cpp:55:12:55:19 | new | new |

View File

@@ -41,57 +41,22 @@ edges
| test.cpp:178:22:178:26 | (const char *)... indirection | test.cpp:178:13:178:19 | strncat output argument |
| test.cpp:180:13:180:19 | strncat output argument | test.cpp:183:32:183:38 | array to pointer conversion indirection |
| test.cpp:180:22:180:29 | (const char *)... indirection | test.cpp:180:13:180:19 | strncat output argument |
| test.cpp:186:34:186:38 | flags | test.cpp:187:11:187:15 | strncat output argument |
| test.cpp:186:34:186:38 | flags | test.cpp:187:11:187:15 | strncat output argument |
| test.cpp:186:34:186:38 | flags | test.cpp:188:11:188:17 | strncat output argument |
| test.cpp:186:34:186:38 | flags | test.cpp:188:20:188:24 | (const char *)... indirection |
| test.cpp:186:34:186:38 | flags indirection | test.cpp:187:11:187:15 | strncat output argument |
| test.cpp:186:34:186:38 | flags indirection | test.cpp:187:11:187:15 | strncat output argument |
| test.cpp:186:34:186:38 | flags indirection | test.cpp:188:11:188:17 | strncat output argument |
| test.cpp:186:34:186:38 | flags indirection | test.cpp:188:20:188:24 | (const char *)... indirection |
| test.cpp:186:47:186:54 | filename | test.cpp:187:11:187:15 | strncat output argument |
| test.cpp:186:47:186:54 | filename | test.cpp:188:20:188:24 | (const char *)... indirection |
| test.cpp:186:47:186:54 | filename indirection | test.cpp:187:11:187:15 | strncat output argument |
| test.cpp:186:47:186:54 | filename indirection | test.cpp:187:18:187:25 | (const char *)... indirection |
| test.cpp:186:47:186:54 | filename indirection | test.cpp:188:20:188:24 | (const char *)... indirection |
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:11:188:17 | strncat output argument |
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:11:188:17 | strncat output argument |
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:11:188:17 | strncat output argument |
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | (const char *)... indirection |
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | (const char *)... indirection |
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | (const char *)... indirection |
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | (const char *)... indirection |
| test.cpp:187:18:187:25 | (const char *)... indirection | test.cpp:187:11:187:15 | strncat output argument |
| test.cpp:188:20:188:24 | (const char *)... indirection | test.cpp:188:11:188:17 | strncat output argument |
| test.cpp:188:20:188:24 | (const char *)... indirection | test.cpp:188:11:188:17 | strncat output argument |
| test.cpp:188:20:188:24 | (const char *)... indirection | test.cpp:188:11:188:17 | strncat output argument |
| test.cpp:188:20:188:24 | (const char *)... indirection | test.cpp:188:11:188:17 | strncat output argument |
| test.cpp:194:9:194:16 | fread output argument | test.cpp:196:26:196:33 | array to pointer conversion indirection |
| test.cpp:194:9:194:16 | fread output argument | test.cpp:196:26:196:33 | filename |
| test.cpp:196:10:196:16 | concat output argument | test.cpp:198:32:198:38 | array to pointer conversion indirection |
| test.cpp:196:10:196:16 | concat output argument | test.cpp:198:32:198:38 | array to pointer conversion indirection |
| test.cpp:196:19:196:23 | array to pointer conversion indirection | test.cpp:186:34:186:38 | flags indirection |
| test.cpp:196:19:196:23 | array to pointer conversion indirection | test.cpp:186:34:186:38 | flags indirection |
| test.cpp:196:19:196:23 | array to pointer conversion indirection | test.cpp:196:10:196:16 | concat output argument |
| test.cpp:196:19:196:23 | array to pointer conversion indirection | test.cpp:196:10:196:16 | concat output argument |
| test.cpp:196:19:196:23 | concat output argument | test.cpp:196:19:196:23 | array to pointer conversion indirection |
| test.cpp:196:19:196:23 | concat output argument | test.cpp:196:19:196:23 | array to pointer conversion indirection |
| test.cpp:196:19:196:23 | concat output argument | test.cpp:196:19:196:23 | flags |
| test.cpp:196:19:196:23 | concat output argument | test.cpp:196:19:196:23 | flags |
| test.cpp:196:19:196:23 | flags | test.cpp:186:34:186:38 | flags |
| test.cpp:196:19:196:23 | flags | test.cpp:186:34:186:38 | flags |
| test.cpp:196:19:196:23 | flags | test.cpp:196:10:196:16 | concat output argument |
| test.cpp:196:19:196:23 | flags | test.cpp:196:10:196:16 | concat output argument |
| test.cpp:196:19:196:23 | flags | test.cpp:196:19:196:23 | concat output argument |
| test.cpp:196:19:196:23 | flags | test.cpp:196:19:196:23 | concat output argument |
| test.cpp:196:26:196:33 | array to pointer conversion indirection | test.cpp:186:47:186:54 | filename indirection |
| test.cpp:196:26:196:33 | array to pointer conversion indirection | test.cpp:196:10:196:16 | concat output argument |
| test.cpp:196:26:196:33 | array to pointer conversion indirection | test.cpp:196:10:196:16 | concat output argument |
| test.cpp:196:26:196:33 | array to pointer conversion indirection | test.cpp:196:19:196:23 | concat output argument |
| test.cpp:196:26:196:33 | array to pointer conversion indirection | test.cpp:196:19:196:23 | concat output argument |
| test.cpp:196:26:196:33 | filename | test.cpp:186:47:186:54 | filename |
| test.cpp:196:26:196:33 | filename | test.cpp:196:10:196:16 | concat output argument |
| test.cpp:196:26:196:33 | filename | test.cpp:196:19:196:23 | concat output argument |
| test.cpp:218:9:218:16 | fread output argument | test.cpp:220:19:220:26 | (const char *)... indirection |
| test.cpp:218:9:218:16 | fread output argument | test.cpp:220:19:220:26 | (const char *)... indirection |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | array to pointer conversion indirection |
@@ -153,40 +118,18 @@ nodes
| test.cpp:183:32:183:38 | array to pointer conversion indirection | semmle.label | array to pointer conversion indirection |
| test.cpp:183:32:183:38 | array to pointer conversion indirection | semmle.label | array to pointer conversion indirection |
| test.cpp:183:32:183:38 | array to pointer conversion indirection | semmle.label | array to pointer conversion indirection |
| test.cpp:186:34:186:38 | flags | semmle.label | flags |
| test.cpp:186:34:186:38 | flags | semmle.label | flags |
| test.cpp:186:34:186:38 | flags indirection | semmle.label | flags indirection |
| test.cpp:186:34:186:38 | flags indirection | semmle.label | flags indirection |
| test.cpp:186:47:186:54 | filename | semmle.label | filename |
| test.cpp:186:47:186:54 | filename indirection | semmle.label | filename indirection |
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:187:18:187:25 | (const char *)... indirection | semmle.label | (const char *)... indirection |
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:188:20:188:24 | (const char *)... indirection | semmle.label | (const char *)... indirection |
| test.cpp:188:20:188:24 | (const char *)... indirection | semmle.label | (const char *)... indirection |
| test.cpp:188:20:188:24 | (const char *)... indirection | semmle.label | (const char *)... indirection |
| test.cpp:188:20:188:24 | (const char *)... indirection | semmle.label | (const char *)... indirection |
| test.cpp:194:9:194:16 | fread output argument | semmle.label | fread output argument |
| test.cpp:196:10:196:16 | concat output argument | semmle.label | concat output argument |
| test.cpp:196:10:196:16 | concat output argument | semmle.label | concat output argument |
| test.cpp:196:19:196:23 | array to pointer conversion indirection | semmle.label | array to pointer conversion indirection |
| test.cpp:196:19:196:23 | array to pointer conversion indirection | semmle.label | array to pointer conversion indirection |
| test.cpp:196:19:196:23 | concat output argument | semmle.label | concat output argument |
| test.cpp:196:19:196:23 | concat output argument | semmle.label | concat output argument |
| test.cpp:196:19:196:23 | flags | semmle.label | flags |
| test.cpp:196:19:196:23 | flags | semmle.label | flags |
| test.cpp:196:26:196:33 | array to pointer conversion indirection | semmle.label | array to pointer conversion indirection |
| test.cpp:196:26:196:33 | filename | semmle.label | filename |
| test.cpp:198:32:198:38 | array to pointer conversion indirection | semmle.label | array to pointer conversion indirection |
@@ -198,17 +141,8 @@ nodes
| test.cpp:220:19:220:26 | (const char *)... indirection | semmle.label | (const char *)... indirection |
| test.cpp:222:32:222:38 | array to pointer conversion indirection | semmle.label | array to pointer conversion indirection |
subpaths
| test.cpp:196:19:196:23 | array to pointer conversion indirection | test.cpp:186:34:186:38 | flags indirection | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
| test.cpp:196:19:196:23 | array to pointer conversion indirection | test.cpp:186:34:186:38 | flags indirection | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
| test.cpp:196:19:196:23 | flags | test.cpp:186:34:186:38 | flags | test.cpp:187:11:187:15 | strncat output argument | test.cpp:196:19:196:23 | concat output argument |
| test.cpp:196:19:196:23 | flags | test.cpp:186:34:186:38 | flags | test.cpp:187:11:187:15 | strncat output argument | test.cpp:196:19:196:23 | concat output argument |
| test.cpp:196:19:196:23 | flags | test.cpp:186:34:186:38 | flags | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
| test.cpp:196:19:196:23 | flags | test.cpp:186:34:186:38 | flags | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
| test.cpp:196:26:196:33 | array to pointer conversion indirection | test.cpp:186:47:186:54 | filename indirection | test.cpp:187:11:187:15 | strncat output argument | test.cpp:196:19:196:23 | concat output argument |
| test.cpp:196:26:196:33 | array to pointer conversion indirection | test.cpp:186:47:186:54 | filename indirection | test.cpp:187:11:187:15 | strncat output argument | test.cpp:196:19:196:23 | concat output argument |
| test.cpp:196:26:196:33 | array to pointer conversion indirection | test.cpp:186:47:186:54 | filename indirection | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
| test.cpp:196:26:196:33 | array to pointer conversion indirection | test.cpp:186:47:186:54 | filename indirection | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
| test.cpp:196:26:196:33 | filename | test.cpp:186:47:186:54 | filename | test.cpp:187:11:187:15 | strncat output argument | test.cpp:196:19:196:23 | concat output argument |
| test.cpp:196:26:196:33 | filename | test.cpp:186:47:186:54 | filename | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
#select
| test.cpp:23:12:23:19 | command1 | test.cpp:15:27:15:30 | argv indirection | test.cpp:23:12:23:19 | (const char *)... indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:15:27:15:30 | argv indirection | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument |

View File

@@ -3,10 +3,6 @@ edges
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
@@ -19,8 +15,6 @@ nodes
| test.c:15:20:15:23 | argv | semmle.label | argv |
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |

View File

@@ -11,10 +11,6 @@ edges
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
@@ -37,8 +33,6 @@ edges
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data |
@@ -53,36 +47,18 @@ edges
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer |
subpaths
@@ -102,8 +78,6 @@ nodes
| test.cpp:56:12:56:17 | fgets output argument | semmle.label | fgets output argument |
| test.cpp:62:10:62:15 | buffer | semmle.label | buffer |
| test.cpp:62:10:62:15 | buffer | semmle.label | buffer |
| test.cpp:62:10:62:15 | buffer | semmle.label | buffer |
| test.cpp:62:10:62:15 | buffer | semmle.label | buffer |
| test.cpp:63:10:63:13 | data | semmle.label | data |
| test.cpp:63:10:63:13 | data | semmle.label | data |
| test.cpp:63:10:63:13 | data | semmle.label | data |
@@ -119,22 +93,16 @@ nodes
| test.cpp:76:12:76:17 | fgets output argument | semmle.label | fgets output argument |
| test.cpp:78:10:78:15 | buffer | semmle.label | buffer |
| test.cpp:78:10:78:15 | buffer | semmle.label | buffer |
| test.cpp:78:10:78:15 | buffer | semmle.label | buffer |
| test.cpp:78:10:78:15 | buffer | semmle.label | buffer |
| test.cpp:98:17:98:22 | buffer | semmle.label | buffer |
| test.cpp:98:17:98:22 | buffer | semmle.label | buffer |
| test.cpp:98:17:98:22 | recv output argument | semmle.label | recv output argument |
| test.cpp:99:15:99:20 | buffer | semmle.label | buffer |
| test.cpp:99:15:99:20 | buffer | semmle.label | buffer |
| test.cpp:99:15:99:20 | buffer | semmle.label | buffer |
| test.cpp:99:15:99:20 | buffer | semmle.label | buffer |
| test.cpp:106:17:106:22 | buffer | semmle.label | buffer |
| test.cpp:106:17:106:22 | buffer | semmle.label | buffer |
| test.cpp:106:17:106:22 | recv output argument | semmle.label | recv output argument |
| test.cpp:107:15:107:20 | buffer | semmle.label | buffer |
| test.cpp:107:15:107:20 | buffer | semmle.label | buffer |
| test.cpp:107:15:107:20 | buffer | semmle.label | buffer |
| test.cpp:107:15:107:20 | buffer | semmle.label | buffer |
#select
| test.cpp:26:10:26:16 | command | test.cpp:42:18:42:23 | call to getenv | test.cpp:26:10:26:16 | command | The value of this argument may come from $@ and is being passed to system. | test.cpp:42:18:42:23 | call to getenv | call to getenv |
| test.cpp:31:10:31:16 | command | test.cpp:43:18:43:23 | call to getenv | test.cpp:31:10:31:16 | command | The value of this argument may come from $@ and is being passed to system. | test.cpp:43:18:43:23 | call to getenv | call to getenv |

View File

@@ -12,65 +12,24 @@ edges
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 |
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 |
| overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | src |
| overflowdestination.cpp:50:52:50:54 | src | overflowdestination.cpp:52:9:52:12 | memcpy output argument |
| overflowdestination.cpp:50:52:50:54 | src | overflowdestination.cpp:53:9:53:12 | memcpy output argument |
| overflowdestination.cpp:50:52:50:54 | src | overflowdestination.cpp:53:15:53:17 | src |
| overflowdestination.cpp:50:52:50:54 | src | overflowdestination.cpp:54:9:54:12 | memcpy output argument |
| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:52:9:52:12 | memcpy output argument |
| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:9:53:12 | memcpy output argument |
| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:15:53:17 | src |
| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:54:9:54:12 | memcpy output argument |
| overflowdestination.cpp:52:9:52:12 | memcpy output argument | overflowdestination.cpp:54:9:54:12 | memcpy output argument |
| overflowdestination.cpp:52:9:52:12 | memcpy output argument | overflowdestination.cpp:54:9:54:12 | memcpy output argument |
| overflowdestination.cpp:53:9:53:12 | memcpy output argument | overflowdestination.cpp:54:9:54:12 | memcpy output argument |
| overflowdestination.cpp:53:9:53:12 | memcpy output argument | overflowdestination.cpp:54:9:54:12 | memcpy output argument |
| overflowdestination.cpp:54:9:54:12 | memcpy output argument | overflowdestination.cpp:54:9:54:12 | memcpy output argument |
| overflowdestination.cpp:54:9:54:12 | memcpy output argument | overflowdestination.cpp:54:9:54:12 | memcpy output argument |
| overflowdestination.cpp:57:40:57:43 | dest | overflowdestination.cpp:65:9:65:13 | memcpy output argument |
| overflowdestination.cpp:57:40:57:43 | dest indirection | overflowdestination.cpp:65:9:65:13 | memcpy output argument |
| overflowdestination.cpp:57:52:57:54 | src | overflowdestination.cpp:63:9:63:13 | memcpy output argument |
| overflowdestination.cpp:57:52:57:54 | src | overflowdestination.cpp:64:9:64:13 | memcpy output argument |
| overflowdestination.cpp:57:52:57:54 | src | overflowdestination.cpp:64:16:64:19 | src2 |
| overflowdestination.cpp:57:52:57:54 | src | overflowdestination.cpp:65:9:65:13 | memcpy output argument |
| overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:63:9:63:13 | memcpy output argument |
| overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:64:9:64:13 | memcpy output argument |
| overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:64:16:64:19 | src2 |
| overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:65:9:65:13 | memcpy output argument |
| overflowdestination.cpp:63:9:63:13 | memcpy output argument | overflowdestination.cpp:65:9:65:13 | memcpy output argument |
| overflowdestination.cpp:63:9:63:13 | memcpy output argument | overflowdestination.cpp:65:9:65:13 | memcpy output argument |
| overflowdestination.cpp:64:9:64:13 | memcpy output argument | overflowdestination.cpp:65:9:65:13 | memcpy output argument |
| overflowdestination.cpp:64:9:64:13 | memcpy output argument | overflowdestination.cpp:65:9:65:13 | memcpy output argument |
| overflowdestination.cpp:65:9:65:13 | memcpy output argument | overflowdestination.cpp:65:9:65:13 | memcpy output argument |
| overflowdestination.cpp:65:9:65:13 | memcpy output argument | overflowdestination.cpp:65:9:65:13 | memcpy output argument |
| overflowdestination.cpp:65:9:65:13 | memcpy output argument | overflowdestination.cpp:65:9:65:13 | memcpy output argument |
| overflowdestination.cpp:65:9:65:13 | memcpy output argument | overflowdestination.cpp:65:9:65:13 | memcpy output argument |
| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:75:30:75:32 | array to pointer conversion indirection |
| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:75:30:75:32 | src |
| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:76:30:76:32 | array to pointer conversion indirection |
| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:76:30:76:32 | src |
| overflowdestination.cpp:75:24:75:27 | overflowdest_test2 output argument | overflowdestination.cpp:76:24:76:27 | array to pointer conversion indirection |
| overflowdestination.cpp:75:24:75:27 | overflowdest_test2 output argument | overflowdestination.cpp:76:24:76:27 | dest |
| overflowdestination.cpp:75:30:75:32 | array to pointer conversion indirection | overflowdestination.cpp:50:52:50:54 | src indirection |
| overflowdestination.cpp:75:30:75:32 | array to pointer conversion indirection | overflowdestination.cpp:75:24:75:27 | overflowdest_test2 output argument |
| overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | overflowdestination.cpp:76:30:76:32 | array to pointer conversion indirection |
| overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | overflowdestination.cpp:76:30:76:32 | src |
| overflowdestination.cpp:75:30:75:32 | src | overflowdestination.cpp:50:52:50:54 | src |
| overflowdestination.cpp:75:30:75:32 | src | overflowdestination.cpp:75:24:75:27 | overflowdest_test2 output argument |
| overflowdestination.cpp:75:30:75:32 | src | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument |
| overflowdestination.cpp:76:24:76:27 | array to pointer conversion indirection | overflowdestination.cpp:57:40:57:43 | dest indirection |
| overflowdestination.cpp:76:24:76:27 | array to pointer conversion indirection | overflowdestination.cpp:76:30:76:32 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:24:76:27 | dest | overflowdestination.cpp:57:40:57:43 | dest |
| overflowdestination.cpp:76:24:76:27 | dest | overflowdestination.cpp:76:24:76:27 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:24:76:27 | dest | overflowdestination.cpp:76:30:76:32 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:24:76:27 | overflowdest_test3 output argument | overflowdestination.cpp:76:24:76:27 | array to pointer conversion indirection |
| overflowdestination.cpp:76:24:76:27 | overflowdest_test3 output argument | overflowdestination.cpp:76:24:76:27 | dest |
| overflowdestination.cpp:76:30:76:32 | array to pointer conversion indirection | overflowdestination.cpp:57:52:57:54 | src indirection |
| overflowdestination.cpp:76:30:76:32 | array to pointer conversion indirection | overflowdestination.cpp:76:24:76:27 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:30:76:32 | overflowdest_test3 output argument | overflowdestination.cpp:76:30:76:32 | array to pointer conversion indirection |
| overflowdestination.cpp:76:30:76:32 | overflowdest_test3 output argument | overflowdestination.cpp:76:30:76:32 | src |
| overflowdestination.cpp:76:30:76:32 | src | overflowdestination.cpp:57:52:57:54 | src |
| overflowdestination.cpp:76:30:76:32 | src | overflowdestination.cpp:76:24:76:27 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:30:76:32 | src | overflowdestination.cpp:76:30:76:32 | overflowdest_test3 output argument |
nodes
| main.cpp:6:27:6:30 | argv | semmle.label | argv |
| main.cpp:6:27:6:30 | argv indirection | semmle.label | argv indirection |
@@ -86,57 +45,21 @@ nodes
| overflowdestination.cpp:46:15:46:17 | src | semmle.label | src |
| overflowdestination.cpp:50:52:50:54 | src | semmle.label | src |
| overflowdestination.cpp:50:52:50:54 | src indirection | semmle.label | src indirection |
| overflowdestination.cpp:52:9:52:12 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:52:9:52:12 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:53:9:53:12 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:53:9:53:12 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:53:15:53:17 | src | semmle.label | src |
| overflowdestination.cpp:54:9:54:12 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:54:9:54:12 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:57:40:57:43 | dest | semmle.label | dest |
| overflowdestination.cpp:57:40:57:43 | dest indirection | semmle.label | dest indirection |
| overflowdestination.cpp:57:52:57:54 | src | semmle.label | src |
| overflowdestination.cpp:57:52:57:54 | src indirection | semmle.label | src indirection |
| overflowdestination.cpp:63:9:63:13 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:63:9:63:13 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:64:9:64:13 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:64:9:64:13 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:64:16:64:19 | src2 | semmle.label | src2 |
| overflowdestination.cpp:65:9:65:13 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:65:9:65:13 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:65:9:65:13 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:65:9:65:13 | memcpy output argument | semmle.label | memcpy output argument |
| overflowdestination.cpp:73:8:73:10 | fgets output argument | semmle.label | fgets output argument |
| overflowdestination.cpp:75:24:75:27 | overflowdest_test2 output argument | semmle.label | overflowdest_test2 output argument |
| overflowdestination.cpp:75:30:75:32 | array to pointer conversion indirection | semmle.label | array to pointer conversion indirection |
| overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | semmle.label | overflowdest_test2 output argument |
| overflowdestination.cpp:75:30:75:32 | src | semmle.label | src |
| overflowdestination.cpp:76:24:76:27 | array to pointer conversion indirection | semmle.label | array to pointer conversion indirection |
| overflowdestination.cpp:76:24:76:27 | dest | semmle.label | dest |
| overflowdestination.cpp:76:24:76:27 | overflowdest_test3 output argument | semmle.label | overflowdest_test3 output argument |
| overflowdestination.cpp:76:30:76:32 | array to pointer conversion indirection | semmle.label | array to pointer conversion indirection |
| overflowdestination.cpp:76:30:76:32 | overflowdest_test3 output argument | semmle.label | overflowdest_test3 output argument |
| overflowdestination.cpp:76:30:76:32 | src | semmle.label | src |
subpaths
| overflowdestination.cpp:75:30:75:32 | array to pointer conversion indirection | overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:52:9:52:12 | memcpy output argument | overflowdestination.cpp:75:24:75:27 | overflowdest_test2 output argument |
| overflowdestination.cpp:75:30:75:32 | array to pointer conversion indirection | overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:9:53:12 | memcpy output argument | overflowdestination.cpp:75:24:75:27 | overflowdest_test2 output argument |
| overflowdestination.cpp:75:30:75:32 | array to pointer conversion indirection | overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:54:9:54:12 | memcpy output argument | overflowdestination.cpp:75:24:75:27 | overflowdest_test2 output argument |
| overflowdestination.cpp:75:30:75:32 | src | overflowdestination.cpp:50:52:50:54 | src | overflowdestination.cpp:52:9:52:12 | memcpy output argument | overflowdestination.cpp:75:24:75:27 | overflowdest_test2 output argument |
| overflowdestination.cpp:75:30:75:32 | src | overflowdestination.cpp:50:52:50:54 | src | overflowdestination.cpp:53:9:53:12 | memcpy output argument | overflowdestination.cpp:75:24:75:27 | overflowdest_test2 output argument |
| overflowdestination.cpp:75:30:75:32 | src | overflowdestination.cpp:50:52:50:54 | src | overflowdestination.cpp:53:9:53:12 | memcpy output argument | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument |
| overflowdestination.cpp:75:30:75:32 | src | overflowdestination.cpp:50:52:50:54 | src | overflowdestination.cpp:54:9:54:12 | memcpy output argument | overflowdestination.cpp:75:24:75:27 | overflowdest_test2 output argument |
| overflowdestination.cpp:75:30:75:32 | src | overflowdestination.cpp:50:52:50:54 | src | overflowdestination.cpp:54:9:54:12 | memcpy output argument | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument |
| overflowdestination.cpp:76:24:76:27 | array to pointer conversion indirection | overflowdestination.cpp:57:40:57:43 | dest indirection | overflowdestination.cpp:65:9:65:13 | memcpy output argument | overflowdestination.cpp:76:30:76:32 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:24:76:27 | dest | overflowdestination.cpp:57:40:57:43 | dest | overflowdestination.cpp:65:9:65:13 | memcpy output argument | overflowdestination.cpp:76:24:76:27 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:24:76:27 | dest | overflowdestination.cpp:57:40:57:43 | dest | overflowdestination.cpp:65:9:65:13 | memcpy output argument | overflowdestination.cpp:76:30:76:32 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:30:76:32 | array to pointer conversion indirection | overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:63:9:63:13 | memcpy output argument | overflowdestination.cpp:76:24:76:27 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:30:76:32 | array to pointer conversion indirection | overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:64:9:64:13 | memcpy output argument | overflowdestination.cpp:76:24:76:27 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:30:76:32 | array to pointer conversion indirection | overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:65:9:65:13 | memcpy output argument | overflowdestination.cpp:76:24:76:27 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:30:76:32 | src | overflowdestination.cpp:57:52:57:54 | src | overflowdestination.cpp:63:9:63:13 | memcpy output argument | overflowdestination.cpp:76:24:76:27 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:30:76:32 | src | overflowdestination.cpp:57:52:57:54 | src | overflowdestination.cpp:64:9:64:13 | memcpy output argument | overflowdestination.cpp:76:24:76:27 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:30:76:32 | src | overflowdestination.cpp:57:52:57:54 | src | overflowdestination.cpp:64:9:64:13 | memcpy output argument | overflowdestination.cpp:76:30:76:32 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:30:76:32 | src | overflowdestination.cpp:57:52:57:54 | src | overflowdestination.cpp:65:9:65:13 | memcpy output argument | overflowdestination.cpp:76:24:76:27 | overflowdest_test3 output argument |
| overflowdestination.cpp:76:30:76:32 | src | overflowdestination.cpp:57:52:57:54 | src | overflowdestination.cpp:65:9:65:13 | memcpy output argument | overflowdestination.cpp:76:30:76:32 | overflowdest_test3 output argument |
#select
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv | overflowdestination.cpp:30:17:30:20 | arg1 | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |

View File

@@ -53,12 +53,6 @@ edges
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 |
@@ -93,12 +87,6 @@ edges
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 |
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 |
@@ -181,9 +169,6 @@ nodes
| argvLocal.c:115:13:115:16 | argv | semmle.label | argv |
| argvLocal.c:116:9:116:10 | i3 | semmle.label | i3 |
| argvLocal.c:116:9:116:10 | i3 | semmle.label | i3 |
| argvLocal.c:116:9:116:10 | i3 | semmle.label | i3 |
| argvLocal.c:116:9:116:10 | i3 | semmle.label | i3 |
| argvLocal.c:117:15:117:16 | i3 | semmle.label | i3 |
| argvLocal.c:117:15:117:16 | i3 | semmle.label | i3 |
| argvLocal.c:117:15:117:16 | i3 | semmle.label | i3 |
| argvLocal.c:121:9:121:10 | i4 | semmle.label | i4 |
@@ -195,9 +180,6 @@ nodes
| argvLocal.c:126:10:126:13 | argv | semmle.label | argv |
| argvLocal.c:127:9:127:10 | i5 | semmle.label | i5 |
| argvLocal.c:127:9:127:10 | i5 | semmle.label | i5 |
| argvLocal.c:127:9:127:10 | i5 | semmle.label | i5 |
| argvLocal.c:127:9:127:10 | i5 | semmle.label | i5 |
| argvLocal.c:128:15:128:16 | i5 | semmle.label | i5 |
| argvLocal.c:128:15:128:16 | i5 | semmle.label | i5 |
| argvLocal.c:128:15:128:16 | i5 | semmle.label | i5 |
| argvLocal.c:131:9:131:14 | ... + ... | semmle.label | ... + ... |

View File

@@ -1,36 +1,18 @@
edges
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 |
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 |
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 |
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 |
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | e1 |
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | e1 |
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | e1 |
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | e1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 |
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 |
| funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | i3 |
| funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | i3 |
| funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | i3 |
| funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | i3 |
| funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 |
| funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 |
| funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 |
| funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 |
| funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 |
| funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 |
| funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 |
@@ -41,36 +23,18 @@ edges
| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 |
| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 |
| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 |
| funcsLocal.c:31:19:31:21 | fgets output argument | funcsLocal.c:32:9:32:10 | i4 |
| funcsLocal.c:31:19:31:21 | fgets output argument | funcsLocal.c:32:9:32:10 | i4 |
| funcsLocal.c:31:19:31:21 | fgets output argument | funcsLocal.c:32:9:32:10 | i4 |
| funcsLocal.c:31:19:31:21 | i41 | funcsLocal.c:32:9:32:10 | i4 |
| funcsLocal.c:31:19:31:21 | i41 | funcsLocal.c:32:9:32:10 | i4 |
| funcsLocal.c:31:19:31:21 | i41 | funcsLocal.c:32:9:32:10 | i4 |
| funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | i5 |
| funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | i5 |
| funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | i5 |
| funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | i5 |
| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 |
| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 |
| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 |
| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 |
| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 |
| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 |
| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 |
| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 |
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 |
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 |
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 |
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 |
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 |
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 |
| funcsLocal.c:41:18:41:20 | gets output argument | funcsLocal.c:42:9:42:10 | i6 |
| funcsLocal.c:41:18:41:20 | gets output argument | funcsLocal.c:42:9:42:10 | i6 |
| funcsLocal.c:41:18:41:20 | gets output argument | funcsLocal.c:42:9:42:10 | i6 |
| funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 |
| funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 |
| funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 |
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... |
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... |
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... |
@@ -86,12 +50,6 @@ edges
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... |
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... |
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... |
| funcsLocal.c:52:13:52:15 | gets output argument | funcsLocal.c:53:9:53:11 | * ... |
| funcsLocal.c:52:13:52:15 | gets output argument | funcsLocal.c:53:9:53:11 | * ... |
| funcsLocal.c:52:13:52:15 | gets output argument | funcsLocal.c:53:9:53:11 | * ... |
| funcsLocal.c:52:13:52:15 | i81 | funcsLocal.c:53:9:53:11 | * ... |
| funcsLocal.c:52:13:52:15 | i81 | funcsLocal.c:53:9:53:11 | * ... |
| funcsLocal.c:52:13:52:15 | i81 | funcsLocal.c:53:9:53:11 | * ... |
subpaths
nodes
| funcsLocal.c:16:8:16:9 | fread output argument | semmle.label | fread output argument |
@@ -99,19 +57,13 @@ nodes
| funcsLocal.c:16:8:16:9 | i1 | semmle.label | i1 |
| funcsLocal.c:17:9:17:10 | i1 | semmle.label | i1 |
| funcsLocal.c:17:9:17:10 | i1 | semmle.label | i1 |
| funcsLocal.c:17:9:17:10 | i1 | semmle.label | i1 |
| funcsLocal.c:17:9:17:10 | i1 | semmle.label | i1 |
| funcsLocal.c:26:8:26:9 | fgets output argument | semmle.label | fgets output argument |
| funcsLocal.c:26:8:26:9 | i3 | semmle.label | i3 |
| funcsLocal.c:26:8:26:9 | i3 | semmle.label | i3 |
| funcsLocal.c:27:9:27:10 | i3 | semmle.label | i3 |
| funcsLocal.c:27:9:27:10 | i3 | semmle.label | i3 |
| funcsLocal.c:27:9:27:10 | i3 | semmle.label | i3 |
| funcsLocal.c:27:9:27:10 | i3 | semmle.label | i3 |
| funcsLocal.c:31:13:31:17 | call to fgets | semmle.label | call to fgets |
| funcsLocal.c:31:13:31:17 | call to fgets | semmle.label | call to fgets |
| funcsLocal.c:31:19:31:21 | fgets output argument | semmle.label | fgets output argument |
| funcsLocal.c:31:19:31:21 | i41 | semmle.label | i41 |
| funcsLocal.c:32:9:32:10 | i4 | semmle.label | i4 |
| funcsLocal.c:32:9:32:10 | i4 | semmle.label | i4 |
| funcsLocal.c:32:9:32:10 | i4 | semmle.label | i4 |
@@ -120,12 +72,8 @@ nodes
| funcsLocal.c:36:7:36:8 | i5 | semmle.label | i5 |
| funcsLocal.c:37:9:37:10 | i5 | semmle.label | i5 |
| funcsLocal.c:37:9:37:10 | i5 | semmle.label | i5 |
| funcsLocal.c:37:9:37:10 | i5 | semmle.label | i5 |
| funcsLocal.c:37:9:37:10 | i5 | semmle.label | i5 |
| funcsLocal.c:41:13:41:16 | call to gets | semmle.label | call to gets |
| funcsLocal.c:41:13:41:16 | call to gets | semmle.label | call to gets |
| funcsLocal.c:41:18:41:20 | gets output argument | semmle.label | gets output argument |
| funcsLocal.c:41:18:41:20 | i61 | semmle.label | i61 |
| funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 |
| funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 |
| funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 |
@@ -137,24 +85,17 @@ nodes
| funcsLocal.c:47:9:47:11 | * ... | semmle.label | * ... |
| funcsLocal.c:52:8:52:11 | call to gets | semmle.label | call to gets |
| funcsLocal.c:52:8:52:11 | call to gets | semmle.label | call to gets |
| funcsLocal.c:52:13:52:15 | gets output argument | semmle.label | gets output argument |
| funcsLocal.c:52:13:52:15 | i81 | semmle.label | i81 |
| funcsLocal.c:53:9:53:11 | * ... | semmle.label | * ... |
| funcsLocal.c:53:9:53:11 | * ... | semmle.label | * ... |
| funcsLocal.c:53:9:53:11 | * ... | semmle.label | * ... |
| funcsLocal.c:58:9:58:10 | e1 | semmle.label | e1 |
| funcsLocal.c:58:9:58:10 | e1 | semmle.label | e1 |
| funcsLocal.c:58:9:58:10 | e1 | semmle.label | e1 |
| funcsLocal.c:58:9:58:10 | e1 | semmle.label | e1 |
#select
| funcsLocal.c:17:9:17:10 | i1 | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:16:8:16:9 | i1 | fread |
| funcsLocal.c:27:9:27:10 | i3 | funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:26:8:26:9 | i3 | fgets |
| funcsLocal.c:32:9:32:10 | i4 | funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:31:13:31:17 | call to fgets | fgets |
| funcsLocal.c:32:9:32:10 | i4 | funcsLocal.c:31:19:31:21 | i41 | funcsLocal.c:32:9:32:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:31:19:31:21 | i41 | fgets |
| funcsLocal.c:37:9:37:10 | i5 | funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:36:7:36:8 | i5 | gets |
| funcsLocal.c:42:9:42:10 | i6 | funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:41:13:41:16 | call to gets | gets |
| funcsLocal.c:42:9:42:10 | i6 | funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:41:18:41:20 | i61 | gets |
| funcsLocal.c:47:9:47:11 | * ... | funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:46:7:46:9 | * ... | gets |
| funcsLocal.c:53:9:53:11 | * ... | funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:52:8:52:11 | call to gets | gets |
| funcsLocal.c:53:9:53:11 | * ... | funcsLocal.c:52:13:52:15 | i81 | funcsLocal.c:53:9:53:11 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:52:13:52:15 | i81 | gets |
| funcsLocal.c:58:9:58:10 | e1 | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:16:8:16:9 | i1 | fread |

View File

@@ -11,12 +11,13 @@ edges
| test.c:137:13:137:16 | call to rand | test.c:139:10:139:10 | r |
| test.c:155:22:155:25 | call to rand | test.c:157:9:157:9 | r |
| test.c:155:22:155:27 | call to rand | test.c:157:9:157:9 | r |
| test.cpp:6:5:6:12 | get_rand indirection | test.cpp:25:7:25:7 | r |
| test.cpp:6:5:6:12 | get_rand indirection | test.cpp:24:11:24:18 | call to get_rand |
| test.cpp:8:9:8:12 | call to rand | test.cpp:6:5:6:12 | get_rand indirection |
| test.cpp:11:21:11:24 | dest | test.cpp:30:13:30:14 | get_rand2 output argument |
| test.cpp:13:10:13:13 | call to rand | test.cpp:11:21:11:24 | dest |
| test.cpp:16:21:16:24 | dest | test.cpp:36:13:36:13 | get_rand3 output argument |
| test.cpp:18:9:18:12 | call to rand | test.cpp:16:21:16:24 | dest |
| test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r |
| test.cpp:30:13:30:14 | get_rand2 output argument | test.cpp:31:7:31:7 | r |
| test.cpp:36:13:36:13 | get_rand3 output argument | test.cpp:37:7:37:7 | r |
| test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x |
@@ -60,6 +61,7 @@ nodes
| test.cpp:13:10:13:13 | call to rand | semmle.label | call to rand |
| test.cpp:16:21:16:24 | dest | semmle.label | dest |
| test.cpp:18:9:18:12 | call to rand | semmle.label | call to rand |
| test.cpp:24:11:24:18 | call to get_rand | semmle.label | call to get_rand |
| test.cpp:25:7:25:7 | r | semmle.label | r |
| test.cpp:30:13:30:14 | get_rand2 output argument | semmle.label | get_rand2 output argument |
| test.cpp:31:7:31:7 | r | semmle.label | r |

View File

@@ -6,11 +6,12 @@ edges
| test2.cpp:27:13:27:13 | v | test2.cpp:12:21:12:21 | v |
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:17:6:17:18 | call to getTaintedInt |
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:17:6:17:18 | call to getTaintedInt |
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:19:6:19:6 | y |
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:19:6:19:6 | y |
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:18:6:18:18 | call to getTaintedInt |
| test5.cpp:9:7:9:9 | buf | test5.cpp:5:5:5:17 | getTaintedInt indirection |
| test5.cpp:9:7:9:9 | buf | test5.cpp:5:5:5:17 | getTaintedInt indirection |
| test5.cpp:9:7:9:9 | gets output argument | test5.cpp:5:5:5:17 | getTaintedInt indirection |
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:19:6:19:6 | y |
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:19:6:19:6 | y |
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
@@ -37,6 +38,7 @@ nodes
| test5.cpp:9:7:9:9 | gets output argument | semmle.label | gets output argument |
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
| test5.cpp:18:6:18:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
| test5.cpp:19:6:19:6 | y | semmle.label | y |
| test5.cpp:19:6:19:6 | y | semmle.label | y |
| test.c:11:29:11:32 | argv | semmle.label | argv |

View File

@@ -1,11 +1,9 @@
edges
| test2.cpp:110:8:110:15 | gets output argument | test2.cpp:110:3:110:6 | call to gets |
| test.cpp:53:27:53:30 | argv | test.cpp:58:25:58:29 | input |
| test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input |
| test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input |
nodes
| test2.cpp:110:3:110:6 | call to gets | semmle.label | call to gets |
| test2.cpp:110:8:110:15 | gets output argument | semmle.label | gets output argument |
| test.cpp:53:27:53:30 | argv | semmle.label | argv |
| test.cpp:53:27:53:30 | argv indirection | semmle.label | argv indirection |
| test.cpp:53:27:53:30 | argv indirection | semmle.label | argv indirection |
@@ -13,7 +11,6 @@ nodes
subpaths
#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) |
| test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:8:110:15 | gets output argument | test2.cpp:110:3:110:6 | call to gets | This write into buffer 'password' may contain unencrypted data from $@. | test2.cpp:110:8:110:15 | gets output argument | user input (string read by gets) |
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:53:27:53:30 | argv | test.cpp:58:25:58:29 | input | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:53:27:53:30 | argv | user input (a command-line argument) |
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:53:27:53:30 | argv indirection | user input (a command-line argument) |
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:53:27:53:30 | argv indirection | user input (a command-line argument) |

View File

@@ -1,14 +1,9 @@
edges
| test2.cpp:62:18:62:25 | password | test2.cpp:65:31:65:34 | cpy1 |
| test2.cpp:72:15:72:24 | password | test2.cpp:73:30:73:32 | buf |
| test2.cpp:72:15:72:24 | password | test2.cpp:73:30:73:32 | buf |
| test2.cpp:72:15:72:24 | password | test2.cpp:76:30:76:32 | buf |
| test2.cpp:72:15:72:24 | password | test2.cpp:76:30:76:32 | buf |
| test2.cpp:72:17:72:24 | password | test2.cpp:73:30:73:32 | buf |
| test2.cpp:72:17:72:24 | password | test2.cpp:73:30:73:32 | buf |
| test2.cpp:72:17:72:24 | password | test2.cpp:76:30:76:32 | buf |
| test2.cpp:72:17:72:24 | password | test2.cpp:76:30:76:32 | buf |
| test2.cpp:98:45:98:52 | password | test2.cpp:99:27:99:32 | buffer |
| test2.cpp:98:45:98:52 | password | test2.cpp:99:27:99:32 | buffer |
| test.cpp:45:9:45:19 | thePassword | test.cpp:45:9:45:19 | thePassword |
| test.cpp:45:9:45:19 | thePassword | test.cpp:45:9:45:19 | thePassword |
@@ -41,14 +36,11 @@ nodes
| test2.cpp:72:15:72:24 | password | semmle.label | password |
| test2.cpp:72:17:72:24 | password | semmle.label | password |
| test2.cpp:73:30:73:32 | buf | semmle.label | buf |
| test2.cpp:73:30:73:32 | buf | semmle.label | buf |
| test2.cpp:76:30:76:32 | buf | semmle.label | buf |
| test2.cpp:76:30:76:32 | buf | semmle.label | buf |
| test2.cpp:86:36:86:43 | password | semmle.label | password |
| test2.cpp:91:50:91:63 | passwd_config2 | semmle.label | passwd_config2 |
| test2.cpp:98:45:98:52 | password | semmle.label | password |
| test2.cpp:99:27:99:32 | buffer | semmle.label | buffer |
| test2.cpp:99:27:99:32 | buffer | semmle.label | buffer |
| test.cpp:45:9:45:19 | thePassword | semmle.label | thePassword |
| test.cpp:45:9:45:19 | thePassword | semmle.label | thePassword |
| test.cpp:45:9:45:19 | thePassword | semmle.label | thePassword |
@@ -72,14 +64,9 @@ subpaths
| test2.cpp:57:2:57:8 | call to fprintf | test2.cpp:57:39:57:49 | call to getPassword | test2.cpp:57:39:57:49 | call to getPassword | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:57:39:57:49 | call to getPassword | this source. |
| test2.cpp:65:3:65:9 | call to fprintf | test2.cpp:62:18:62:25 | password | test2.cpp:65:31:65:34 | cpy1 | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:62:18:62:25 | password | this source. |
| test2.cpp:73:3:73:9 | call to fprintf | test2.cpp:72:15:72:24 | password | test2.cpp:73:30:73:32 | buf | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:72:17:72:24 | password | this source. |
| test2.cpp:73:3:73:9 | call to fprintf | test2.cpp:72:15:72:24 | password | test2.cpp:73:30:73:32 | buf | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:72:17:72:24 | password | this source. |
| test2.cpp:73:3:73:9 | call to fprintf | test2.cpp:72:17:72:24 | password | test2.cpp:73:30:73:32 | buf | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:72:17:72:24 | password | this source. |
| test2.cpp:73:3:73:9 | call to fprintf | test2.cpp:72:17:72:24 | password | test2.cpp:73:30:73:32 | buf | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:72:17:72:24 | password | this source. |
| test2.cpp:76:3:76:9 | call to fprintf | test2.cpp:72:15:72:24 | password | test2.cpp:76:30:76:32 | buf | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:72:17:72:24 | password | this source. |
| test2.cpp:76:3:76:9 | call to fprintf | test2.cpp:72:15:72:24 | password | test2.cpp:76:30:76:32 | buf | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:72:17:72:24 | password | this source. |
| test2.cpp:76:3:76:9 | call to fprintf | test2.cpp:72:17:72:24 | password | test2.cpp:76:30:76:32 | buf | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:72:17:72:24 | password | this source. |
| test2.cpp:76:3:76:9 | call to fprintf | test2.cpp:72:17:72:24 | password | test2.cpp:76:30:76:32 | buf | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:72:17:72:24 | password | this source. |
| test2.cpp:99:3:99:9 | call to fprintf | test2.cpp:98:45:98:52 | password | test2.cpp:99:27:99:32 | buffer | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:98:45:98:52 | password | this source. |
| test2.cpp:99:3:99:9 | call to fprintf | test2.cpp:98:45:98:52 | password | test2.cpp:99:27:99:32 | buffer | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:98:45:98:52 | password | this source. |
| test.cpp:45:3:45:7 | call to fputs | test.cpp:45:9:45:19 | thePassword | test.cpp:45:9:45:19 | thePassword | This write into file 'file' may contain unencrypted data from $@. | test.cpp:45:9:45:19 | thePassword | this source. |
| test.cpp:45:3:45:7 | call to fputs | test.cpp:45:9:45:19 | thePassword | test.cpp:45:9:45:19 | thePassword | This write into file 'file' may contain unencrypted data from $@. | test.cpp:45:9:45:19 | thePassword | this source. |

View File

@@ -2,10 +2,14 @@ edges
| test3.cpp:74:21:74:29 | password1 | test3.cpp:76:15:76:17 | ptr |
| test3.cpp:81:15:81:22 | password | test3.cpp:83:15:83:17 | ptr |
| test3.cpp:112:20:112:25 | buffer | test3.cpp:114:14:114:19 | buffer |
| test3.cpp:124:7:124:20 | get_global_str indirection | test3.cpp:146:15:146:18 | data |
| test3.cpp:117:28:117:33 | buffer | test3.cpp:117:13:117:14 | id indirection |
| test3.cpp:124:7:124:20 | get_global_str indirection | test3.cpp:144:16:144:29 | call to get_global_str |
| test3.cpp:126:9:126:23 | global_password | test3.cpp:124:7:124:20 | get_global_str indirection |
| test3.cpp:134:11:134:18 | password | test3.cpp:112:20:112:25 | buffer |
| test3.cpp:138:24:138:32 | password1 | test3.cpp:140:15:140:17 | ptr |
| test3.cpp:138:21:138:22 | call to id | test3.cpp:140:15:140:17 | ptr |
| test3.cpp:138:24:138:32 | password1 | test3.cpp:117:28:117:33 | buffer |
| test3.cpp:138:24:138:32 | password1 | test3.cpp:138:21:138:22 | call to id |
| test3.cpp:144:16:144:29 | call to get_global_str | test3.cpp:146:15:146:18 | data |
| test3.cpp:157:19:157:26 | password | test3.cpp:159:15:159:20 | buffer |
| test3.cpp:270:16:270:23 | password | test3.cpp:272:15:272:18 | data |
| test3.cpp:278:20:278:23 | data | test3.cpp:280:14:280:17 | data |
@@ -40,11 +44,15 @@ nodes
| test3.cpp:101:12:101:19 | password | semmle.label | password |
| test3.cpp:112:20:112:25 | buffer | semmle.label | buffer |
| test3.cpp:114:14:114:19 | buffer | semmle.label | buffer |
| test3.cpp:117:13:117:14 | id indirection | semmle.label | id indirection |
| test3.cpp:117:28:117:33 | buffer | semmle.label | buffer |
| test3.cpp:124:7:124:20 | get_global_str indirection | semmle.label | get_global_str indirection |
| test3.cpp:126:9:126:23 | global_password | semmle.label | global_password |
| test3.cpp:134:11:134:18 | password | semmle.label | password |
| test3.cpp:138:21:138:22 | call to id | semmle.label | call to id |
| test3.cpp:138:24:138:32 | password1 | semmle.label | password1 |
| test3.cpp:140:15:140:17 | ptr | semmle.label | ptr |
| test3.cpp:144:16:144:29 | call to get_global_str | semmle.label | call to get_global_str |
| test3.cpp:146:15:146:18 | data | semmle.label | data |
| test3.cpp:157:19:157:26 | password | semmle.label | password |
| test3.cpp:159:15:159:20 | buffer | semmle.label | buffer |
@@ -111,6 +119,7 @@ nodes
| test3.cpp:577:8:577:23 | call to get_home_address | semmle.label | call to get_home_address |
| test3.cpp:578:14:578:16 | str | semmle.label | str |
subpaths
| test3.cpp:138:24:138:32 | password1 | test3.cpp:117:28:117:33 | buffer | test3.cpp:117:13:117:14 | id indirection | test3.cpp:138:21:138:22 | call to id |
#select
| test3.cpp:22:3:22:6 | call to send | test3.cpp:22:15:22:23 | password1 | test3.cpp:22:15:22:23 | password1 | This operation transmits 'password1', which may contain unencrypted sensitive data from $@. | test3.cpp:22:15:22:23 | password1 | password1 |
| test3.cpp:26:3:26:6 | call to send | test3.cpp:26:15:26:23 | password2 | test3.cpp:26:15:26:23 | password2 | This operation transmits 'password2', which may contain unencrypted sensitive data from $@. | test3.cpp:26:15:26:23 | password2 | password2 |

View File

@@ -1,11 +1,8 @@
edges
| tests.c:57:21:57:28 | password | tests.c:70:70:70:77 | password |
| tests.c:57:21:57:28 | password | tests.c:70:70:70:77 | password |
nodes
| tests.c:57:21:57:28 | password | semmle.label | password |
| tests.c:70:70:70:77 | password | semmle.label | password |
| tests.c:70:70:70:77 | password | semmle.label | password |
subpaths
#select
| tests.c:70:70:70:77 | password | tests.c:57:21:57:28 | password | tests.c:70:70:70:77 | password | This operation potentially exposes sensitive system data from $@. | tests.c:57:21:57:28 | password | password |
| tests.c:70:70:70:77 | password | tests.c:57:21:57:28 | password | tests.c:70:70:70:77 | password | This operation potentially exposes sensitive system data from $@. | tests.c:57:21:57:28 | password | password |

View File

@@ -6,8 +6,6 @@ edges
| tests2.cpp:65:13:65:18 | call to getenv | tests2.cpp:65:13:65:30 | call to getenv |
| tests2.cpp:66:13:66:18 | call to getenv | tests2.cpp:66:13:66:34 | call to getenv |
| tests2.cpp:78:18:78:38 | call to mysql_get_client_info | tests2.cpp:81:14:81:19 | buffer |
| tests2.cpp:78:18:78:38 | call to mysql_get_client_info | tests2.cpp:81:14:81:19 | buffer |
| tests2.cpp:78:18:78:38 | call to mysql_get_client_info | tests2.cpp:81:14:81:19 | buffer |
| tests2.cpp:91:42:91:45 | str1 | tests2.cpp:93:14:93:17 | str1 |
| tests2.cpp:101:8:101:15 | call to getpwuid | tests2.cpp:102:14:102:15 | pw |
| tests2.cpp:109:3:109:36 | ... = ... | tests2.cpp:109:6:109:8 | c1 indirection [post update] [ptr] |
@@ -45,8 +43,6 @@ nodes
| tests2.cpp:78:18:78:38 | call to mysql_get_client_info | semmle.label | call to mysql_get_client_info |
| tests2.cpp:80:14:80:34 | call to mysql_get_client_info | semmle.label | call to mysql_get_client_info |
| tests2.cpp:81:14:81:19 | buffer | semmle.label | buffer |
| tests2.cpp:81:14:81:19 | buffer | semmle.label | buffer |
| tests2.cpp:81:14:81:19 | buffer | semmle.label | buffer |
| tests2.cpp:82:14:82:20 | global1 | semmle.label | global1 |
| tests2.cpp:91:42:91:45 | str1 | semmle.label | str1 |
| tests2.cpp:93:14:93:17 | str1 | semmle.label | str1 |

View File

@@ -14,8 +14,6 @@ edges
| tests.cpp:97:13:97:34 | call to getenv | tests.cpp:86:29:86:31 | msg |
| tests.cpp:107:30:107:32 | msg | tests.cpp:111:15:111:17 | tmp |
| tests.cpp:114:30:114:32 | msg | tests.cpp:119:7:119:12 | buffer |
| tests.cpp:114:30:114:32 | msg | tests.cpp:119:7:119:12 | buffer |
| tests.cpp:114:30:114:32 | msg | tests.cpp:119:7:119:12 | buffer |
| tests.cpp:122:30:122:32 | msg | tests.cpp:124:15:124:17 | msg |
| tests.cpp:131:14:131:19 | call to getenv | tests.cpp:131:14:131:35 | call to getenv |
| tests.cpp:131:14:131:35 | call to getenv | tests.cpp:107:30:107:32 | msg |
@@ -59,8 +57,6 @@ nodes
| tests.cpp:111:15:111:17 | tmp | semmle.label | tmp |
| tests.cpp:114:30:114:32 | msg | semmle.label | msg |
| tests.cpp:119:7:119:12 | buffer | semmle.label | buffer |
| tests.cpp:119:7:119:12 | buffer | semmle.label | buffer |
| tests.cpp:119:7:119:12 | buffer | semmle.label | buffer |
| tests.cpp:122:30:122:32 | msg | semmle.label | msg |
| tests.cpp:124:15:124:17 | msg | semmle.label | msg |
| tests.cpp:131:14:131:19 | call to getenv | semmle.label | call to getenv |
@@ -95,8 +91,6 @@ subpaths
| tests.cpp:97:13:97:34 | call to getenv | tests.cpp:97:13:97:18 | call to getenv | tests.cpp:97:13:97:34 | call to getenv | This operation potentially exposes sensitive system data from $@. | tests.cpp:97:13:97:18 | call to getenv | call to getenv |
| tests.cpp:111:15:111:17 | tmp | tests.cpp:131:14:131:19 | call to getenv | tests.cpp:111:15:111:17 | tmp | This operation potentially exposes sensitive system data from $@. | tests.cpp:131:14:131:19 | call to getenv | call to getenv |
| tests.cpp:119:7:119:12 | buffer | tests.cpp:132:14:132:19 | call to getenv | tests.cpp:119:7:119:12 | buffer | This operation potentially exposes sensitive system data from $@. | tests.cpp:132:14:132:19 | call to getenv | call to getenv |
| tests.cpp:119:7:119:12 | buffer | tests.cpp:132:14:132:19 | call to getenv | tests.cpp:119:7:119:12 | buffer | This operation potentially exposes sensitive system data from $@. | tests.cpp:132:14:132:19 | call to getenv | call to getenv |
| tests.cpp:119:7:119:12 | buffer | tests.cpp:132:14:132:19 | call to getenv | tests.cpp:119:7:119:12 | buffer | This operation potentially exposes sensitive system data from $@. | tests.cpp:132:14:132:19 | call to getenv | call to getenv |
| tests.cpp:124:15:124:17 | msg | tests.cpp:133:14:133:19 | call to getenv | tests.cpp:124:15:124:17 | msg | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:19 | call to getenv | call to getenv |
| tests.cpp:133:14:133:19 | call to getenv | tests.cpp:133:14:133:19 | call to getenv | tests.cpp:133:14:133:19 | call to getenv | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:19 | call to getenv | call to getenv |
| tests.cpp:133:14:133:35 | call to getenv | tests.cpp:133:14:133:19 | call to getenv | tests.cpp:133:14:133:35 | call to getenv | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:19 | call to getenv | call to getenv |

View File

@@ -0,0 +1,11 @@
class AnnotatedElement extends @cil_has_type_annotation {
string toString() { none() }
}
class Field extends @cil_field {
string toString() { none() }
}
from AnnotatedElement element, int annotation
where cil_type_annotation(element, annotation) and not element instanceof Field
select element, annotation

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
class AnnotatedElement extends @has_type_annotation {
string toString() { none() }
}
class Field extends @field {
string toString() { none() }
}
from AnnotatedElement element, int annotation
where type_annotation(element, annotation) and not element instanceof Field
select element, annotation

View File

@@ -0,0 +1,4 @@
description: Remove CIL fields as entities that can have type annotations and remove field type annotations.
compatibility: backwards
cil_type_annotation.rel: run cil_type_annotation.qlo
type_annotation.rel: run type_annotation.qlo

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using System.IO;
using System.Collections.Generic;
namespace Semmle.Extraction.CIL.Entities
{
@@ -38,6 +35,11 @@ namespace Semmle.Extraction.CIL.Entities
t = mt.Unmodified;
yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired);
}
if (t is ByRefType brt)
{
t = brt.ElementType;
yield return Tuples.cil_type_annotation(this, TypeAnnotation.Ref);
}
yield return Tuples.cil_field(this, DeclaringType, Name, t);
}
}

View File

@@ -30,6 +30,7 @@ namespace Semmle.Extraction.CSharp.Entities
PopulateAttributes();
ContainingType!.PopulateGenerics();
PopulateNullability(trapFile, Symbol.GetAnnotatedType());
PopulateRefKind(trapFile, Symbol.RefKind);
var unboundFieldKey = Field.Create(Context, Symbol.OriginalDefinition);
trapFile.fields(this, (Symbol.IsConst ? 2 : 1), Symbol.Name, ContainingType, Type.TypeRef, unboundFieldKey);

View File

@@ -25,19 +25,14 @@ namespace Semmle.Extraction.CSharp.Entities
public static string AccessibilityModifier(Accessibility access)
{
switch (access)
return access switch
{
case Accessibility.Private:
return "private";
case Accessibility.Protected:
return "protected";
case Accessibility.Public:
return "public";
case Accessibility.Internal:
return "internal";
default:
throw new InternalError("Unavailable modifier combination");
}
Accessibility.Private => Modifiers.Private,
Accessibility.Protected => Modifiers.Protected,
Accessibility.Public => Modifiers.Public,
Accessibility.Internal => Modifiers.Internal,
_ => throw new InternalError("Unavailable modifier combination"),
};
}
public static void HasAccessibility(Context cx, TextWriter trapFile, IEntity type, Accessibility access)
@@ -48,17 +43,17 @@ namespace Semmle.Extraction.CSharp.Entities
case Accessibility.Public:
case Accessibility.Protected:
case Accessibility.Internal:
HasModifier(cx, trapFile, type, Modifier.AccessibilityModifier(access));
HasModifier(cx, trapFile, type, AccessibilityModifier(access));
break;
case Accessibility.NotApplicable:
break;
case Accessibility.ProtectedOrInternal:
HasModifier(cx, trapFile, type, "protected");
HasModifier(cx, trapFile, type, "internal");
HasModifier(cx, trapFile, type, Modifiers.Protected);
HasModifier(cx, trapFile, type, Modifiers.Internal);
break;
case Accessibility.ProtectedAndInternal:
HasModifier(cx, trapFile, type, "protected");
HasModifier(cx, trapFile, type, "private");
HasModifier(cx, trapFile, type, Modifiers.Protected);
HasModifier(cx, trapFile, type, Modifiers.Private);
break;
default:
throw new InternalError($"Unhandled Microsoft.CodeAnalysis.Accessibility value: {access}");
@@ -70,6 +65,27 @@ namespace Semmle.Extraction.CSharp.Entities
trapFile.has_modifiers(target, Modifier.Create(cx, modifier));
}
private static void ExtractNamedTypeModifiers(Context cx, TextWriter trapFile, IEntity key, ISymbol symbol)
{
if (symbol.Kind != SymbolKind.NamedType)
return;
if (symbol is not INamedTypeSymbol nt)
throw new InternalError(symbol, "Symbol kind is inconsistent with its type");
if (nt.IsRecord)
HasModifier(cx, trapFile, key, Modifiers.Record);
if (nt.TypeKind == TypeKind.Struct)
{
if (nt.IsReadOnly)
HasModifier(cx, trapFile, key, Modifiers.Readonly);
if (nt.IsRefLikeType)
HasModifier(cx, trapFile, key, Modifiers.Ref);
}
}
public static void ExtractModifiers(Context cx, TextWriter trapFile, IEntity key, ISymbol symbol)
{
HasAccessibility(cx, trapFile, key, symbol.DeclaredAccessibility);
@@ -77,51 +93,35 @@ namespace Semmle.Extraction.CSharp.Entities
trapFile.has_modifiers(key, Modifier.Create(cx, Accessibility.Public));
if (symbol.IsAbstract && (symbol.Kind != SymbolKind.NamedType || ((INamedTypeSymbol)symbol).TypeKind != TypeKind.Interface))
HasModifier(cx, trapFile, key, "abstract");
HasModifier(cx, trapFile, key, Modifiers.Abstract);
if (symbol.IsSealed)
HasModifier(cx, trapFile, key, "sealed");
HasModifier(cx, trapFile, key, Modifiers.Sealed);
var fromSource = symbol.DeclaringSyntaxReferences.Length > 0;
if (symbol.IsStatic && !(symbol.Kind == SymbolKind.Field && ((IFieldSymbol)symbol).IsConst && !fromSource))
HasModifier(cx, trapFile, key, "static");
HasModifier(cx, trapFile, key, Modifiers.Static);
if (symbol.IsVirtual)
HasModifier(cx, trapFile, key, "virtual");
HasModifier(cx, trapFile, key, Modifiers.Virtual);
if (symbol.Kind == SymbolKind.Field && ((IFieldSymbol)symbol).IsReadOnly)
HasModifier(cx, trapFile, key, "readonly");
HasModifier(cx, trapFile, key, Modifiers.Readonly);
if (symbol.IsOverride)
HasModifier(cx, trapFile, key, "override");
HasModifier(cx, trapFile, key, Modifiers.Override);
if (symbol.Kind == SymbolKind.Method && ((IMethodSymbol)symbol).IsAsync)
HasModifier(cx, trapFile, key, "async");
HasModifier(cx, trapFile, key, Modifiers.Async);
if (symbol.IsExtern)
HasModifier(cx, trapFile, key, "extern");
HasModifier(cx, trapFile, key, Modifiers.Extern);
foreach (var modifier in symbol.GetSourceLevelModifiers())
HasModifier(cx, trapFile, key, modifier);
if (symbol.Kind == SymbolKind.NamedType)
{
var nt = symbol as INamedTypeSymbol;
if (nt is null)
throw new InternalError(symbol, "Symbol kind is inconsistent with its type");
if (nt.IsRecord)
HasModifier(cx, trapFile, key, "record");
if (nt.TypeKind == TypeKind.Struct)
{
if (nt.IsReadOnly)
HasModifier(cx, trapFile, key, "readonly");
if (nt.IsRefLikeType)
HasModifier(cx, trapFile, key, "ref");
}
}
ExtractNamedTypeModifiers(cx, trapFile, key, symbol);
}
public static Modifier Create(Context cx, string modifier)

View File

@@ -0,0 +1,20 @@
internal static class Modifiers
{
public const string Abstract = "abstract";
public const string Async = "async";
public const string Const = "const";
public const string Extern = "extern";
public const string Internal = "internal";
public const string New = "new";
public const string Override = "override";
public const string Partial = "partial";
public const string Private = "private";
public const string Protected = "protected";
public const string Public = "public";
public const string Readonly = "readonly";
public const string Record = "record";
public const string Ref = "ref";
public const string Sealed = "sealed";
public const string Static = "static";
public const string Virtual = "virtual";
}

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* C# 11: Added extractor support for `ref` fields in `ref struct` declarations.

View File

@@ -152,4 +152,7 @@ class Field extends DotNet::Field, Variable, Member, CustomModifierReceiver, @ci
override ValueOrRefType getDeclaringType() { cil_field(this, result, _, _) }
override Location getLocation() { result = this.getDeclaringType().getLocation() }
/** Holds if this declaration is `ref`. */
predicate isRef() { cil_type_annotation(this, 32) }
}

View File

@@ -399,6 +399,12 @@ class Field extends Variable, AssignableMember, Attributable, TopLevelExprParent
/** Holds if this field is `volatile`. */
predicate isVolatile() { this.hasModifier("volatile") }
/** Holds if this is a `ref` field. */
predicate isRef() { this.getAnnotatedType().isRef() }
/** Holds if this is a `ref readonly` field. */
predicate isReadonlyRef() { this.getAnnotatedType().isReadonlyRef() }
/** Holds if this field is `readonly`. */
predicate isReadOnly() { this.hasModifier("readonly") }

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1868,7 +1868,7 @@ cil_field(
@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event;
@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type;
@cil_parameterizable = @cil_method | @cil_function_pointer_type;
@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_method | @cil_function_pointer_type;
@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_field | @cil_method | @cil_function_pointer_type;
#keyset[parameterizable, index]
cil_parameter(

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Add CIL fields as entities that can have type annotations.
compatibility: backwards

View File

@@ -412,6 +412,9 @@ class CallTargetOperand extends RegisterOperand {
*/
class ArgumentOperand extends RegisterOperand {
override ArgumentOperandTag tag;
/** Gets the `CallInstruction` for which this is an argument. */
CallInstruction getCall() { result.getAnArgumentOperand() = this }
}
/**

View File

@@ -412,6 +412,9 @@ class CallTargetOperand extends RegisterOperand {
*/
class ArgumentOperand extends RegisterOperand {
override ArgumentOperandTag tag;
/** Gets the `CallInstruction` for which this is an argument. */
CallInstruction getCall() { result.getAnArgumentOperand() = this }
}
/**

View File

@@ -0,0 +1,15 @@
// TODO: Test needs to be enabled when .NET 7 is used as the runtime.
namespace structassembly;
public class MyEmptyClass { }
public ref struct RefStruct
{
public int MyInt;
public ref byte MyByte;
public ref object MyObject;
internal ref MyEmptyClass MyEmptyClass;
public ref readonly byte MyReadonlyByte;
public readonly ref object MyReadonlyObject;
public readonly ref readonly string MyReadonlyString;
}

View File

@@ -0,0 +1,14 @@
namespace structassembly;
public class MyEmptyClass { }
public ref struct RefStruct
{
public int MyInt;
public ref byte MyByte;
public ref object MyObject;
internal ref MyEmptyClass MyEmptyClass;
public ref readonly byte MyReadonlyByte;
public readonly ref object MyReadonlyObject;
public readonly ref readonly string MyReadonlyString;
}

View File

@@ -0,0 +1,6 @@
| file://:0:0:0:0 | MyByte | Byte |
| file://:0:0:0:0 | MyEmptyClass | MyEmptyClass |
| file://:0:0:0:0 | MyObject | Object |
| file://:0:0:0:0 | MyReadonlyByte | Byte |
| file://:0:0:0:0 | MyReadonlyObject | Object |
| file://:0:0:0:0 | MyReadonlyString | String |

View File

@@ -0,0 +1,5 @@
import cil
query predicate cilfields(CIL::Field f, string type) {
f.isRef() and type = f.getType().toString() and f.getDeclaringType().getName() = "RefStruct"
}

View File

@@ -0,0 +1,3 @@
reffields
readonlyreffields
readonlyfield

View File

@@ -0,0 +1,16 @@
import csharp
query predicate reffields(Field f) {
f.getFile().getStem() = "Struct" and
f.isRef()
}
query predicate readonlyreffields(Field f) {
f.getFile().getStem() = "Struct" and
f.isReadonlyRef()
}
query predicate readonlyfield(Field f) {
f.getFile().getStem() = "Struct" and
f.isReadOnly()
}

View File

@@ -45,7 +45,7 @@ The following properties are supported by all query files:
| | | ``high`` | |
| | | ``very-high`` | |
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``@problem.severity`` | | ``error`` | Defines the level of severity of any alerts generated by a non-security query. This, along with the ``@precision`` property, determines how the results are displayed on GitHub. |
| ``@problem.severity`` | | ``error`` | Defines the level of severity of any alerts generated by a non-security query. This, along with the ``@precision`` property, determines how the results are displayed on GitHub. For more information, see the `Query metadata style guide <https://github.com/github/codeql/blob/main/docs/query-metadata-style-guide.md>`__. |
| | | ``warning`` | |
| | | ``recommendation`` | |
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

View File

@@ -170,7 +170,7 @@ func GetPkgDir(pkgpath string, flags ...string) string {
// DepErrors checks there are any errors resolving dependencies for `pkgpath`. It passes the `go
// list` command the flags specified by `flags`.
func DepErrors(pkgpath string, flags ...string) bool {
out, err := runGoList("{{if .DepsErrors}}{{else}}error{{end}}", []string{pkgpath}, flags...)
out, err := runGoList("{{if .DepsErrors}}error{{else}}{{end}}", []string{pkgpath}, flags...)
if err != nil {
// if go list failed, assume dependencies are broken
return false

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -50,10 +50,6 @@ import com.semmle.util.trap.dependencies.TrapSet;
import com.semmle.util.trap.pathtransformers.PathTransformer;
public class OdasaOutput {
// By default we use lockless TRAP writing, but this can be set
// if we want to use the old TRAP locking for any reason.
private final boolean use_trap_locking = Env.systemEnv().getBoolean("CODEQL_EXTRACTOR_JAVA_TRAP_LOCKING", false);
// either these are set ...
private final File trapFolder;
private final File sourceArchiveFolder;
@@ -270,24 +266,6 @@ public class OdasaOutput {
* For functions for example, this means its parameter signature.
*/
private TrapFileManager getMembersWriterForDecl(File trap, File trapFileBase, TrapClassVersion trapFileVersion, IrElement sym, String signature) {
if (use_trap_locking) {
TrapClassVersion currVersion = TrapClassVersion.fromSymbol(sym, log);
String shortName = sym instanceof IrDeclarationWithName ? ((IrDeclarationWithName)sym).getName().asString() : "(name unknown)";
if (trap.exists()) {
// Only re-write an existing trap file if we encountered a newer version of the same class.
TrapClassVersion trapVersion = readVersionInfo(trap);
if (!currVersion.isValid()) {
log.trace("Not rewriting trap file for: " + shortName + " " + trapVersion + " " + currVersion + " " + trap);
} else if (currVersion.newerThan(trapVersion)) {
log.trace("Rewriting trap file for: " + shortName + " " + trapVersion + " " + currVersion + " " + trap);
deleteTrapFileAndDependencies(sym, signature);
} else {
return null;
}
} else {
log.trace("Writing trap file for: " + shortName + " " + currVersion + " " + trap);
}
} else {
// If the TRAP file already exists then we
// don't need to write it.
if (trap.exists()) {
@@ -322,7 +300,6 @@ public class OdasaOutput {
}
}
}
}
return trapWriter(trap, sym, signature);
}
@@ -374,25 +351,6 @@ public class OdasaOutput {
}
writeTrapDependencies(trapDependenciesForClass);
// If we are using TRAP locking then we
// need to write a metadata file.
if (use_trap_locking) {
// Record major/minor version information for extracted class files.
// This is subsequently used to determine whether to re-extract (a newer version of) the same class.
File metadataFile = new File(trapFile.getAbsolutePath().replace(".trap.gz", ".metadata"));
try {
Map<String, String> versionMap = new LinkedHashMap<>();
TrapClassVersion tcv = TrapClassVersion.fromSymbol(sym, log);
versionMap.put(MAJOR_VERSION, String.valueOf(tcv.getMajorVersion()));
versionMap.put(MINOR_VERSION, String.valueOf(tcv.getMinorVersion()));
versionMap.put(LAST_MODIFIED, String.valueOf(tcv.getLastModified()));
versionMap.put(EXTRACTOR_NAME, tcv.getExtractorName());
FileUtil.writePropertiesCSV(metadataFile, versionMap);
} catch (IOException e) {
log.warn("Could not save trap metadata file: " + metadataFile.getAbsolutePath(), e);
}
}
}
private void writeTrapDependencies(TrapDependencies trapDependencies) {
String dep = trapDependencies.trapFile().replace(".trap.gz", ".dep");
@@ -480,9 +438,6 @@ public class OdasaOutput {
trapFile = null;
} else {
File normalTrapFile = getTrapFileForDecl(sym, signature);
if (use_trap_locking) {
trapFile = normalTrapFile;
} else {
// We encode the metadata into the filename, so that the
// TRAP filenames for different metadatas don't overlap.
if (fromSource)
@@ -497,7 +452,6 @@ public class OdasaOutput {
trapFile = new File(trapFileBase.getPath() + '#' + trapFileVersion.toString() + ".trap.gz");
}
}
}
private TrapLocker(File jarFile) {
sym = null;
signature = null;
@@ -510,9 +464,6 @@ public class OdasaOutput {
}
public TrapFileManager getTrapFileManager() {
if (trapFile!=null) {
if (use_trap_locking) {
lockTrapFile(trapFile);
}
return getMembersWriterForDecl(trapFile, trapFileBase, trapFileVersion, sym, signature);
} else {
return null;
@@ -522,23 +473,14 @@ public class OdasaOutput {
@Override
public void close() {
if (trapFile!=null) {
try {
if (use_trap_locking) {
unlockTrapFile(trapFile);
}
} catch (NestedError e) {
log.warn("Error unlocking trap file " + trapFile.getAbsolutePath(), e);
}
// If we are writing TRAP file locklessly, then now that we
// have finished writing our TRAP file, we want to rename
// and TRAP file that matches our trapFileBase but doesn't
// have the latest metadata.
// Now that we have finished writing our TRAP file, we want
// to rename and TRAP file that matches our trapFileBase
// but doesn't have the latest metadata.
// Renaming it to trap-old means that it won't be imported,
// but we can still use its presence to avoid future
// invocations rewriting it, and it means that the information
// is in the TRAP directory if we need it for debugging.
if (!use_trap_locking && sym != null) {
if (sym != null) {
File trapFileDir = trapFileBase.getParentFile();
String trapFileBaseName = trapFileBase.getName();

View File

@@ -2,4 +2,7 @@ import sys
from create_database_utils import *
#The version of gradle used doesn't work on java 17
try_use_java11()
run_codeql_database_create([], lang="java")

View File

@@ -2,4 +2,7 @@ import sys
from create_database_utils import *
#The version of gradle used doesn't work on java 17
try_use_java11()
run_codeql_database_create([], lang="java")

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added sink models for the `createQuery`, `createNativeQuery`, and `createSQLQuery` methods of the `org.hibernate.query.QueryProducer` interface.

View File

@@ -3,9 +3,6 @@ extensions:
pack: codeql/java-all
extensible: sinkModel
data:
- ["org.hibernate", "QueryProducer", True, "createNativeQuery", "", "", "Argument[0]", "sql", "manual"]
- ["org.hibernate", "QueryProducer", True, "createQuery", "", "", "Argument[0]", "sql", "manual"]
- ["org.hibernate", "QueryProducer", True, "createSQLQuery", "", "", "Argument[0]", "sql", "manual"]
- ["org.hibernate", "Session", True, "createQuery", "", "", "Argument[0]", "sql", "manual"]
- ["org.hibernate", "Session", True, "createSQLQuery", "", "", "Argument[0]", "sql", "manual"]
- ["org.hibernate", "SharedSessionContract", True, "createQuery", "", "", "Argument[0]", "sql", "manual"]

View File

@@ -0,0 +1,8 @@
extensions:
- addsTo:
pack: codeql/java-all
extensible: sinkModel
data:
- ["org.hibernate.query", "QueryProducer", True, "createNativeQuery", "", "", "Argument[0]", "sql", "manual"]
- ["org.hibernate.query", "QueryProducer", True, "createQuery", "", "", "Argument[0]", "sql", "manual"]
- ["org.hibernate.query", "QueryProducer", True, "createSQLQuery", "", "", "Argument[0]", "sql", "manual"]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

View File

@@ -1487,6 +1487,10 @@ private module MkStage<StageSig PrevStage> {
PrevStage::readStepCand(node1, _, _, config)
}
bindingset[ap, c]
pragma[inline_late]
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
pragma[nomagic]
private predicate fwdFlowRead(
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
@@ -1494,7 +1498,7 @@ private module MkStage<StageSig PrevStage> {
) {
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
PrevStage::readStepCand(node1, c, node2, config) and
getHeadContent(ap) = c
hasHeadContent(ap, c)
}
pragma[nomagic]

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