upgrading to 2.16.3, resolving zipslip merge conflict

This commit is contained in:
Dilan Bhalla
2024-02-22 15:24:05 -08:00
1068 changed files with 71791 additions and 46445 deletions

View File

@@ -0,0 +1,19 @@
class Element extends @element {
string toString() { none() }
}
class Expr extends @expr {
string toString() { none() }
}
class Stmt extends @stmt {
string toString() { none() }
}
predicate isStmtWithInitializer(Stmt stmt) { exists(int kind | stmts(stmt, kind, _) | kind = 29) }
from Expr child, int index, int index_new, Element parent
where
exprparents(child, index, parent) and
if isStmtWithInitializer(parent) then index_new = index - 1 else index_new = index
select child, index_new, parent

View File

@@ -0,0 +1,9 @@
class Stmt extends @stmt {
string toString() { none() }
}
from Stmt f, Stmt i
where
for_initialization(f, i) and
f instanceof @stmt_for
select f, i

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
class Element extends @element {
string toString() { none() }
}
class Stmt extends @stmt {
string toString() { none() }
}
predicate isStmtWithInitializer(Stmt stmt) { exists(int kind | stmts(stmt, kind, _) | kind = 29) }
from Stmt child, int index, int index_new, Element parent
where
stmtparents(child, index, parent) and
(
not isStmtWithInitializer(parent)
or
index > 0
) and
if isStmtWithInitializer(parent) then index_new = index - 1 else index_new = index
select child, index_new, parent

View File

@@ -0,0 +1,5 @@
description: Support C++20 range-based for initializers
compatibility: partial
exprparents.rel: run exprparents.qlo
stmtparents.rel: run stmtparents.qlo
for_initialization.rel: run for_initialization.qlo

View File

@@ -1,3 +1,9 @@
## 0.12.6
### New Features
* A `getInitialization` predicate was added to the `RangeBasedForStmt` class that yields the C++20-style initializer of the range-based `for` statement when it exists.
## 0.12.5
### New Features

View File

@@ -0,0 +1,5 @@
## 0.12.6
### New Features
* A `getInitialization` predicate was added to the `RangeBasedForStmt` class that yields the C++20-style initializer of the range-based `for` statement when it exists.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.12.5
lastReleaseVersion: 0.12.6

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 0.12.5
version: 0.12.6
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -735,7 +735,9 @@ private predicate namedStmtChildPredicates(Locatable s, Element e, string pred)
or
s.(ForStmt).getStmt() = e and pred = "getStmt()"
or
s.(RangeBasedForStmt).getChild(0) = e and pred = "getChild(0)"
s.(RangeBasedForStmt).getInitialization() = e and pred = "getInitialization()"
or
s.(RangeBasedForStmt).getChild(1) = e and pred = "getChild(1)"
or
s.(RangeBasedForStmt).getBeginEndDeclaration() = e and pred = "getBeginEndDeclaration()"
or
@@ -743,7 +745,7 @@ private predicate namedStmtChildPredicates(Locatable s, Element e, string pred)
or
s.(RangeBasedForStmt).getUpdate() = e and pred = "getUpdate()"
or
s.(RangeBasedForStmt).getChild(4) = e and pred = "getChild(4)"
s.(RangeBasedForStmt).getChild(5) = e and pred = "getChild(5)"
or
s.(RangeBasedForStmt).getStmt() = e and pred = "getStmt()"
or
@@ -835,7 +837,11 @@ private predicate namedExprChildPredicates(Expr expr, Element ele, string pred)
or
expr.(OverloadedArrayExpr).getArrayOffset() = ele and pred = "getArrayOffset()"
or
expr.(OverloadedPointerDereferenceExpr).getExpr() = ele and pred = "getExpr()"
// OverloadedPointerDereferenceExpr::getExpr/0 also considers qualifiers, which are already handled above for all Call classes.
not expr.(OverloadedPointerDereferenceExpr).getQualifier() =
expr.(OverloadedPointerDereferenceExpr).getExpr() and
expr.(OverloadedPointerDereferenceExpr).getExpr() = ele and
pred = "getExpr()"
or
expr.(CommaExpr).getLeftOperand() = ele and pred = "getLeftOperand()"
or

View File

@@ -234,7 +234,16 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
* int f(int y) { return y; }
* ```
*/
override string getName() { var_decls(underlyingElement(this), _, _, result, _) and result != "" }
override string getName() {
exists(string name |
var_decls(underlyingElement(this), _, _, name, _) and
(
name != "" and result = name
or
name = "" and result = this.getVariable().(LocalVariable).getName()
)
)
}
/**
* Gets the type of the variable which is being declared or defined.

View File

@@ -203,30 +203,42 @@ private class GuardConditionFromIR extends GuardCondition {
* `&&` and `||`. See the detailed explanation on predicate `controls`.
*/
private predicate controlsBlock(BasicBlock controlled, boolean testIsTrue) {
exists(IRBlock irb, Instruction instr |
exists(IRBlock irb |
ir.controls(irb, testIsTrue) and
instr = irb.getAnInstruction() and
instr.getAst().(ControlFlowNode).getBasicBlock() = controlled and
not isUnreachedBlock(irb) and
not this.excludeAsControlledInstruction(instr)
nonExcludedIRAndBasicBlock(irb, controlled) and
not isUnreachedBlock(irb)
)
}
}
private predicate excludeAsControlledInstruction(Instruction instr) {
// Exclude the temporaries generated by a ternary expression.
exists(TranslatedConditionalExpr tce |
instr = tce.getInstruction(ConditionValueFalseStoreTag())
or
instr = tce.getInstruction(ConditionValueTrueStoreTag())
or
instr = tce.getInstruction(ConditionValueTrueTempAddressTag())
or
instr = tce.getInstruction(ConditionValueFalseTempAddressTag())
)
private predicate excludeAsControlledInstruction(Instruction instr) {
// Exclude the temporaries generated by a ternary expression.
exists(TranslatedConditionalExpr tce |
instr = tce.getInstruction(ConditionValueFalseStoreTag())
or
// Exclude unreached instructions, as their AST is the whole function and not a block.
instr instanceof UnreachedInstruction
}
instr = tce.getInstruction(ConditionValueTrueStoreTag())
or
instr = tce.getInstruction(ConditionValueTrueTempAddressTag())
or
instr = tce.getInstruction(ConditionValueFalseTempAddressTag())
)
or
// Exclude unreached instructions, as their AST is the whole function and not a block.
instr instanceof UnreachedInstruction
}
/**
* Holds if `irb` is the `IRBlock` corresponding to the AST basic block
* `controlled`, and `irb` does not contain any instruction(s) that should make
* the `irb` be ignored.
*/
pragma[nomagic]
private predicate nonExcludedIRAndBasicBlock(IRBlock irb, BasicBlock controlled) {
exists(Instruction instr |
instr = irb.getAnInstruction() and
instr.getAst().(ControlFlowNode).getBasicBlock() = controlled and
not excludeAsControlledInstruction(instr)
)
}
/**

View File

@@ -637,8 +637,10 @@ private predicate straightLineSparse(Node scope, int i, Node ni, Spec spec) {
any(RangeBasedForStmt for |
i = -1 and ni = for and spec.isAt()
or
i = 0 and ni = for.getInitialization() and spec.isAround()
or
exists(DeclStmt s | s.getADeclaration() = for.getRangeVariable() |
i = 0 and ni = s and spec.isAround()
i = 1 and ni = s and spec.isAround()
)
or
exists(DeclStmt s |
@@ -649,22 +651,22 @@ private predicate straightLineSparse(Node scope, int i, Node ni, Spec spec) {
// DeclStmt in that case.
exists(s.getADeclaration())
|
i = 1 and ni = s and spec.isAround()
i = 2 and ni = s and spec.isAround()
)
or
i = 2 and ni = for.getCondition() and spec.isBefore()
i = 3 and ni = for.getCondition() and spec.isBefore()
or
i = 3 and /* BARRIER */ ni = for and spec.isBarrier()
i = 4 and /* BARRIER */ ni = for and spec.isBarrier()
or
exists(DeclStmt declStmt | declStmt.getADeclaration() = for.getVariable() |
i = 4 and ni = declStmt and spec.isAfter()
i = 5 and ni = declStmt and spec.isAfter()
)
or
i = 5 and ni = for.getStmt() and spec.isAround()
i = 6 and ni = for.getStmt() and spec.isAround()
or
i = 6 and ni = for.getUpdate() and spec.isAround()
i = 7 and ni = for.getUpdate() and spec.isAround()
or
i = 7 and ni = for.getCondition() and spec.isBefore()
i = 8 and ni = for.getCondition() and spec.isBefore()
)
or
scope =

View File

@@ -244,9 +244,15 @@ class ConditionDeclExpr extends Expr, @condition_decl {
/**
* Gets the compiler-generated variable access that conceptually occurs after
* the initialization of the declared variable.
* the initialization of the declared variable, if any.
*/
VariableAccess getVariableAccess() { result = this.getChild(0) }
VariableAccess getVariableAccess() { result = this.getExpr() }
/**
* Gets the expression that is evaluated after the initialization of the declared
* variable.
*/
Expr getExpr() { result = this.getChild(0) }
/**
* Gets the expression that initializes the declared variable. This predicate

View File

@@ -709,7 +709,7 @@ class FinalGlobalValue extends Node, TFinalGlobalValue {
override DataFlowType getType() {
exists(int indirectionIndex |
indirectionIndex = globalUse.getIndirectionIndex() and
result = getTypeImpl(globalUse.getUnspecifiedType(), indirectionIndex - 1)
result = getTypeImpl(globalUse.getUnderlyingType(), indirectionIndex - 1)
)
}
@@ -740,7 +740,7 @@ class InitialGlobalValue extends Node, TInitialGlobalValue {
override DataFlowType getType() {
exists(DataFlowType type |
type = globalDef.getUnspecifiedType() and
type = globalDef.getUnderlyingType() and
if this.isGLValue()
then result = type
else result = getTypeImpl(type, globalDef.getIndirectionIndex() - 1)
@@ -943,10 +943,13 @@ private Type getTypeImpl0(Type t, int indirectionIndex) {
indirectionIndex > 0 and
exists(Type stripped |
stripped = stripPointer(t.stripTopLevelSpecifiers()) and
// We need to avoid the case where `stripPointer(t) = t` (which can happen on
// iterators that specify a `value_type` that is the iterator itself). Such a type
// would create an infinite loop otherwise. For these cases we simply don't produce
// a result for `getTypeImpl`.
// We need to avoid the case where `stripPointer(t) = t` (which can happen
// on iterators that specify a `value_type` that is the iterator itself).
// Such a type would create an infinite loop otherwise. For these cases we
// simply don't produce a result for `getTypeImpl`.
// To be on the safe side, we check whether the _unspecified_ type has
// changed since this also prevents an infinite loop when `stripped` and
// `t` only differ by const'ness or volatile'ness.
stripped.getUnspecifiedType() != t.getUnspecifiedType() and
result = getTypeImpl0(stripped, indirectionIndex - 1)
)
@@ -996,12 +999,14 @@ private module RawIndirectNodes {
override Declaration getEnclosingCallable() { result = this.getFunction() }
override predicate isGLValue() { this.getOperand().isGLValue() }
override DataFlowType getType() {
exists(int sub, DataFlowType type, boolean isGLValue |
type = getOperandType(this.getOperand(), isGLValue) and
if isGLValue = true then sub = 1 else sub = 0
|
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
result = getTypeImpl(type.getUnderlyingType(), indirectionIndex - sub)
)
}
@@ -1038,12 +1043,14 @@ private module RawIndirectNodes {
override Declaration getEnclosingCallable() { result = this.getFunction() }
override predicate isGLValue() { this.getInstruction().isGLValue() }
override DataFlowType getType() {
exists(int sub, DataFlowType type, boolean isGLValue |
type = getInstructionType(this.getInstruction(), isGLValue) and
if isGLValue = true then sub = 1 else sub = 0
|
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
result = getTypeImpl(type.getUnderlyingType(), indirectionIndex - sub)
)
}
@@ -1136,7 +1143,7 @@ class FinalParameterNode extends Node, TFinalParameterNode {
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowType getType() { result = getTypeImpl(p.getUnspecifiedType(), indirectionIndex) }
override DataFlowType getType() { result = getTypeImpl(p.getUnderlyingType(), indirectionIndex) }
final override Location getLocationImpl() {
// Parameters can have multiple locations. When there's a unique location we use
@@ -1789,7 +1796,7 @@ class VariableNode extends Node, TVariableNode {
}
override DataFlowType getType() {
result = getTypeImpl(v.getUnspecifiedType(), indirectionIndex - 1)
result = getTypeImpl(v.getUnderlyingType(), indirectionIndex - 1)
}
final override Location getLocationImpl() {

View File

@@ -507,13 +507,13 @@ module ProductFlow {
private predicate pathSuccPlus(TNodePair n1, TNodePair n2) = fastTC(pathSucc/2)(n1, n2)
private predicate localPathStep1(Flow1::PathNode pred, Flow1::PathNode succ) {
Flow1::PathGraph::edges(pred, succ) and
Flow1::PathGraph::edges(pred, succ, _, _) and
pragma[only_bind_out](pred.getNode().getEnclosingCallable()) =
pragma[only_bind_out](succ.getNode().getEnclosingCallable())
}
private predicate localPathStep2(Flow2::PathNode pred, Flow2::PathNode succ) {
Flow2::PathGraph::edges(pred, succ) and
Flow2::PathGraph::edges(pred, succ, _, _) and
pragma[only_bind_out](pred.getNode().getEnclosingCallable()) =
pragma[only_bind_out](succ.getNode().getEnclosingCallable())
}
@@ -530,7 +530,7 @@ module ProductFlow {
TJump()
private predicate intoImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) {
Flow1::PathGraph::edges(pred1, succ1) and
Flow1::PathGraph::edges(pred1, succ1, _, _) and
pred1.getNode().(ArgumentNode).getCall() = call and
succ1.getNode() instanceof ParameterNode
}
@@ -543,7 +543,7 @@ module ProductFlow {
}
private predicate outImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) {
Flow1::PathGraph::edges(pred1, succ1) and
Flow1::PathGraph::edges(pred1, succ1, _, _) and
exists(ReturnKindExt returnKind |
succ1.getNode() = returnKind.getAnOutNode(call) and
pred1.getNode().(ReturnNodeExt).getKind() = returnKind
@@ -558,7 +558,7 @@ module ProductFlow {
}
private predicate intoImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) {
Flow2::PathGraph::edges(pred2, succ2) and
Flow2::PathGraph::edges(pred2, succ2, _, _) and
pred2.getNode().(ArgumentNode).getCall() = call and
succ2.getNode() instanceof ParameterNode
}
@@ -571,7 +571,7 @@ module ProductFlow {
}
private predicate outImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) {
Flow2::PathGraph::edges(pred2, succ2) and
Flow2::PathGraph::edges(pred2, succ2, _, _) and
exists(ReturnKindExt returnKind |
succ2.getNode() = returnKind.getAnOutNode(call) and
pred2.getNode().(ReturnNodeExt).getKind() = returnKind
@@ -590,7 +590,7 @@ module ProductFlow {
Declaration predDecl, Declaration succDecl, Flow1::PathNode pred1, Flow1::PathNode succ1,
TKind kind
) {
Flow1::PathGraph::edges(pred1, succ1) and
Flow1::PathGraph::edges(pred1, succ1, _, _) and
predDecl != succDecl and
pred1.getNode().getEnclosingCallable() = predDecl and
succ1.getNode().getEnclosingCallable() = succDecl and
@@ -610,7 +610,7 @@ module ProductFlow {
Declaration predDecl, Declaration succDecl, Flow2::PathNode pred2, Flow2::PathNode succ2,
TKind kind
) {
Flow2::PathGraph::edges(pred2, succ2) and
Flow2::PathGraph::edges(pred2, succ2, _, _) and
predDecl != succDecl and
pred2.getNode().getEnclosingCallable() = predDecl and
succ2.getNode().getEnclosingCallable() = succDecl and

View File

@@ -142,7 +142,7 @@ private newtype TDefOrUseImpl =
exists(SsaInternals0::Def def |
def.getSourceVariable().getBaseVariable().(BaseIRVariable).getIRVariable().getAst() = p and
not def.getValue().asInstruction() instanceof InitializeParameterInstruction and
unspecifiedTypeIsModifiableAt(p.getUnspecifiedType(), indirectionIndex)
underlyingTypeIsModifiableAt(p.getUnderlyingType(), indirectionIndex)
)
}
@@ -172,11 +172,13 @@ private predicate isGlobalDefImpl(
)
}
private predicate unspecifiedTypeIsModifiableAt(Type unspecified, int indirectionIndex) {
indirectionIndex = [1 .. getIndirectionForUnspecifiedType(unspecified).getNumberOfIndirections()] and
private predicate underlyingTypeIsModifiableAt(Type underlying, int indirectionIndex) {
indirectionIndex =
[1 .. getIndirectionForUnspecifiedType(underlying.getUnspecifiedType())
.getNumberOfIndirections()] and
exists(CppType cppType |
cppType.hasUnspecifiedType(unspecified, _) and
isModifiableAt(cppType, indirectionIndex + 1)
cppType.hasUnderlyingType(underlying, false) and
isModifiableAt(cppType, indirectionIndex)
)
}
@@ -545,6 +547,11 @@ class GlobalUse extends UseImpl, TGlobalUse {
*/
Type getUnspecifiedType() { result = global.getUnspecifiedType() }
/**
* Gets the type of this use, after typedefs have been resolved.
*/
Type getUnderlyingType() { result = global.getUnderlyingType() }
override predicate isCertain() { any() }
override BaseSourceVariableInstruction getBase() { none() }
@@ -588,11 +595,16 @@ class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl {
int getIndirection() { result = indirectionIndex }
/**
* Gets the type of this use after specifiers have been deeply stripped
* and typedefs have been resolved.
* Gets the type of this definition after specifiers have been deeply
* stripped and typedefs have been resolved.
*/
Type getUnspecifiedType() { result = global.getUnspecifiedType() }
/**
* Gets the type of this definition, after typedefs have been resolved.
*/
Type getUnderlyingType() { result = global.getUnderlyingType() }
override string toString() { result = "Def of " + this.getSourceVariable() }
override Location getLocation() { result = f.getLocation() }
@@ -1092,6 +1104,11 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse {
*/
DataFlowType getUnspecifiedType() { result = global.getUnspecifiedType() }
/**
* Gets the type of this definition, after typedefs have been resolved.
*/
DataFlowType getUnderlyingType() { result = global.getUnderlyingType() }
/** Gets the `IRFunction` whose body is evaluated after this definition. */
IRFunction getIRFunction() { result = global.getIRFunction() }

View File

@@ -452,7 +452,7 @@ private module IsModifiableAtImpl {
private predicate impl(CppType cppType, int indirectionIndex) {
exists(Type pointerType, Type base |
isUnderlyingIndirectionType(pointerType) and
cppType.hasUnderlyingType(pointerType, _) and
cppType.hasUnderlyingType(pointerType, false) and
base = getTypeImpl(pointerType, indirectionIndex)
|
// The value cannot be modified if it has a const specifier,

View File

@@ -2125,13 +2125,6 @@ class ChiInstruction extends Instruction {
*/
final Instruction getPartial() { result = this.getPartialOperand().getDef() }
/**
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand.
*/
final predicate getUpdatedInterval(int startBit, int endBit) {
Construction::getIntervalUpdatedByChi(this, startBit, endBit)
}
/**
* Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`.
* This means that the `ChiPartialOperand` will not override the entire memory associated with the

View File

@@ -233,20 +233,6 @@ private module Cached {
)
}
/**
* Holds if the partial operand of this `ChiInstruction` updates the bit range
* `[startBitOffset, endBitOffset)` of the total operand.
*/
cached
predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBitOffset, int endBitOffset) {
exists(Alias::MemoryLocation location, OldInstruction oldInstruction |
oldInstruction = getOldInstruction(chi.getPartial()) and
location = Alias::getResultMemoryLocation(oldInstruction) and
startBitOffset = Alias::getStartBitOffset(location) and
endBitOffset = Alias::getEndBitOffset(location)
)
}
/**
* Holds if `operand` totally overlaps with its definition and consumes the bit range
* `[startBitOffset, endBitOffset)`.

View File

@@ -2125,13 +2125,6 @@ class ChiInstruction extends Instruction {
*/
final Instruction getPartial() { result = this.getPartialOperand().getDef() }
/**
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand.
*/
final predicate getUpdatedInterval(int startBit, int endBit) {
Construction::getIntervalUpdatedByChi(this, startBit, endBit)
}
/**
* Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`.
* This means that the `ChiPartialOperand` will not override the entire memory associated with the

View File

@@ -202,12 +202,6 @@ Instruction getMemoryOperandDefinition(
none()
}
/**
* Holds if the partial operand of this `ChiInstruction` updates the bit range
* `[startBitOffset, endBitOffset)` of the total operand.
*/
predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBit, int endBit) { none() }
/**
* Holds if the operand totally overlaps with its definition and consumes the
* bit range `[startBitOffset, endBitOffset)`.

View File

@@ -209,6 +209,8 @@ private predicate usedAsCondition(Expr expr) {
or
exists(IfStmt ifStmt | ifStmt.getCondition().getFullyConverted() = expr)
or
exists(ConstexprIfStmt ifStmt | ifStmt.getCondition().getFullyConverted() = expr)
or
exists(ConditionalExpr condExpr |
// The two-operand form of `ConditionalExpr` treats its condition as a value, since it needs to
// be reused as a value if the condition is true.
@@ -474,7 +476,6 @@ private module IRDeclarationEntries {
* This class exists to work around the fact that `DeclStmt`s in some cases
* do not have `DeclarationEntry`s. Currently, this is the case for:
* - `DeclStmt`s in template instantiations.
* - `DeclStmt`s that are generated by the desugaring of range-based for-loops.
*
* So instead, the IR works with `IRDeclarationEntry`s that synthesize missing
* `DeclarationEntry`s when there is no result for `DeclStmt::getDeclarationEntry`.

View File

@@ -3173,7 +3173,7 @@ class TranslatedConditionDeclExpr extends TranslatedNonConstantExpr {
private TranslatedConditionDecl getDecl() { result = getTranslatedConditionDecl(expr) }
private TranslatedExpr getConditionExpr() {
result = getTranslatedExpr(expr.getVariableAccess().getFullyConverted())
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
}
}

View File

@@ -774,6 +774,72 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
}
}
class TranslatedConstExprIfStmt extends TranslatedStmt, ConditionContext {
override ConstexprIfStmt stmt;
override Instruction getFirstInstruction(EdgeKind kind) {
if this.hasInitialization()
then result = this.getInitialization().getFirstInstruction(kind)
else result = this.getFirstConditionInstruction(kind)
}
override TranslatedElement getChild(int id) {
id = 0 and result = this.getInitialization()
or
id = 1 and result = this.getCondition()
or
id = 2 and result = this.getThen()
or
id = 3 and result = this.getElse()
}
private predicate hasInitialization() { exists(stmt.getInitialization()) }
private TranslatedStmt getInitialization() {
result = getTranslatedStmt(stmt.getInitialization())
}
private TranslatedCondition getCondition() {
result = getTranslatedCondition(stmt.getCondition().getFullyConverted())
}
private Instruction getFirstConditionInstruction(EdgeKind kind) {
result = this.getCondition().getFirstInstruction(kind)
}
private TranslatedStmt getThen() { result = getTranslatedStmt(stmt.getThen()) }
private TranslatedStmt getElse() { result = getTranslatedStmt(stmt.getElse()) }
private predicate hasElse() { exists(stmt.getElse()) }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
child = this.getCondition() and
result = this.getThen().getFirstInstruction(kind)
}
override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
child = this.getCondition() and
if this.hasElse()
then result = this.getElse().getFirstInstruction(kind)
else result = this.getParent().getChildSuccessor(this, kind)
}
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getInitialization() and
result = this.getFirstConditionInstruction(kind)
or
(child = this.getThen() or child = this.getElse()) and
result = this.getParent().getChildSuccessor(this, kind)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
none()
}
}
abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
override Loop stmt;
@@ -894,25 +960,38 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
override RangeBasedForStmt stmt;
override TranslatedElement getChild(int id) {
id = 0 and result = this.getRangeVariableDeclStmt()
id = 0 and result = this.getInitialization()
or
id = 1 and result = this.getRangeVariableDeclStmt()
or
// Note: `__begin` and `__end` are declared by the same `DeclStmt`
id = 1 and result = this.getBeginEndVariableDeclStmt()
id = 2 and result = this.getBeginEndVariableDeclStmt()
or
id = 2 and result = this.getCondition()
id = 3 and result = this.getCondition()
or
id = 3 and result = this.getUpdate()
id = 4 and result = this.getUpdate()
or
id = 4 and result = this.getVariableDeclStmt()
id = 5 and result = this.getVariableDeclStmt()
or
id = 5 and result = this.getBody()
id = 6 and result = this.getBody()
}
private predicate hasInitialization() { exists(stmt.getInitialization()) }
private TranslatedStmt getInitialization() {
result = getTranslatedStmt(stmt.getInitialization())
}
override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getRangeVariableDeclStmt().getFirstInstruction(kind)
if this.hasInitialization()
then result = this.getInitialization().getFirstInstruction(kind)
else result = this.getFirstRangeVariableDeclStmtInstruction(kind)
}
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getInitialization() and
result = this.getFirstRangeVariableDeclStmtInstruction(kind)
or
child = this.getRangeVariableDeclStmt() and
result = this.getBeginEndVariableDeclStmt().getFirstInstruction(kind)
or
@@ -952,6 +1031,10 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
)
}
private Instruction getFirstRangeVariableDeclStmtInstruction(EdgeKind kind) {
result = this.getRangeVariableDeclStmt().getFirstInstruction(kind)
}
private TranslatedDeclStmt getBeginEndVariableDeclStmt() {
exists(IRVariableDeclarationEntry entry |
entry.getStmt() = stmt.getBeginEndDeclaration() and

View File

@@ -2125,13 +2125,6 @@ class ChiInstruction extends Instruction {
*/
final Instruction getPartial() { result = this.getPartialOperand().getDef() }
/**
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand.
*/
final predicate getUpdatedInterval(int startBit, int endBit) {
Construction::getIntervalUpdatedByChi(this, startBit, endBit)
}
/**
* Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`.
* This means that the `ChiPartialOperand` will not override the entire memory associated with the

View File

@@ -233,20 +233,6 @@ private module Cached {
)
}
/**
* Holds if the partial operand of this `ChiInstruction` updates the bit range
* `[startBitOffset, endBitOffset)` of the total operand.
*/
cached
predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBitOffset, int endBitOffset) {
exists(Alias::MemoryLocation location, OldInstruction oldInstruction |
oldInstruction = getOldInstruction(chi.getPartial()) and
location = Alias::getResultMemoryLocation(oldInstruction) and
startBitOffset = Alias::getStartBitOffset(location) and
endBitOffset = Alias::getEndBitOffset(location)
)
}
/**
* Holds if `operand` totally overlaps with its definition and consumes the bit range
* `[startBitOffset, endBitOffset)`.

View File

@@ -3,6 +3,7 @@ private import implementations.Deallocation
private import implementations.Fread
private import implementations.Getenv
private import implementations.Gets
private import implementations.GetText
private import implementations.IdentityFunction
private import implementations.Inet
private import implementations.Iterator

View File

@@ -0,0 +1,33 @@
import semmle.code.cpp.models.interfaces.DataFlow
/**
* Returns the transated text index for a given gettext function `f`
*/
private int getTextArg(Function f) {
// basic variations of gettext
f.hasGlobalOrStdName("gettext") and result = 0
or
f.hasGlobalOrStdName("dgettext") and result = 1
or
f.hasGlobalOrStdName("dcgettext") and result = 1
or
// plural variations of gettext that take one format string for singular and another for plural form
f.hasGlobalOrStdName("ngettext") and
(result = 0 or result = 1)
or
f.hasGlobalOrStdName("dngettext") and
(result = 1 or result = 2)
or
f.hasGlobalOrStdName("dcngettext") and
(result = 1 or result = 2)
}
class GetTextFunction extends DataFlowFunction {
int argInd;
GetTextFunction() { argInd = getTextArg(this) }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(argInd) and output.isReturnValueDeref()
}
}

View File

@@ -22,11 +22,28 @@ private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, Alias
])
}
/**
* Gets the index of the parameter that specifies the fill character to insert, if any.
*/
private int getFillCharParameterIndex() {
(
this.hasGlobalOrStdOrBslName("memset")
or
this.hasGlobalOrStdName("wmemset")
or
this.hasGlobalName(["__builtin_memset", "__builtin_memset_chk"])
) and
result = 1
}
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and
output.isReturnValue()
or
input.isParameter(this.getFillCharParameterIndex()) and
(output.isParameterDeref(0) or output.isReturnValueDeref())
}
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {

View File

@@ -892,6 +892,26 @@ class DoStmt extends Loop, @stmt_end_test_while {
class RangeBasedForStmt extends Loop, @stmt_range_based_for {
override string getAPrimaryQlClass() { result = "RangeBasedForStmt" }
/**
* Gets the initialization statement of this 'for' statement, if any.
*
* For example, for
* ```
* for (int x = y; auto z : ... ) { }
* ```
* the result is `int x = y;`.
*
* Does not hold if the initialization statement is missing or an empty statement, as in
* ```
* for (auto z : ...) { }
* ```
* or
* ```
* for (; auto z : ) { }
* ```
*/
Stmt getInitialization() { for_initialization(underlyingElement(this), unresolveElement(result)) }
/**
* Gets the 'body' statement of this range-based 'for' statement.
*
@@ -901,7 +921,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
* ```
* the result is the `BlockStmt` `{ y += x; }`.
*/
override Stmt getStmt() { result = this.getChild(5) }
override Stmt getStmt() { result = this.getChild(6) }
override string toString() { result = "for(...:...) ..." }
@@ -914,7 +934,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
* ```
* the result is `int x`.
*/
LocalVariable getVariable() { result = this.getChild(4).(DeclStmt).getADeclaration() }
LocalVariable getVariable() { result = this.getChild(5).(DeclStmt).getADeclaration() }
/**
* Gets the expression giving the range to iterate over.
@@ -928,7 +948,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
Expr getRange() { result = this.getRangeVariable().getInitializer().getExpr() }
/** Gets the compiler-generated `__range` variable after desugaring. */
LocalVariable getRangeVariable() { result = this.getChild(0).(DeclStmt).getADeclaration() }
LocalVariable getRangeVariable() { result = this.getChild(1).(DeclStmt).getADeclaration() }
/**
* Gets the compiler-generated `__begin != __end` which is the
@@ -936,7 +956,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
* It will be either an `NEExpr` or a call to a user-defined
* `operator!=`.
*/
override Expr getCondition() { result = this.getChild(2) }
override Expr getCondition() { result = this.getChild(3) }
override Expr getControllingExpr() { result = this.getCondition() }
@@ -945,7 +965,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
* `__end`, initializing them to the values they have before entering the
* desugared loop.
*/
DeclStmt getBeginEndDeclaration() { result = this.getChild(1) }
DeclStmt getBeginEndDeclaration() { result = this.getChild(2) }
/** Gets the compiler-generated `__begin` variable after desugaring. */
LocalVariable getBeginVariable() { result = this.getBeginEndDeclaration().getDeclaration(0) }
@@ -959,7 +979,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
* be either a `PrefixIncrExpr` or a call to a user-defined
* `operator++`.
*/
Expr getUpdate() { result = this.getChild(3) }
Expr getUpdate() { result = this.getChild(4) }
/** Gets the compiler-generated `__begin` variable after desugaring. */
LocalVariable getAnIterationVariable() { result = this.getBeginVariable() }

View File

@@ -2050,8 +2050,11 @@ switch_body(
int body_id: @stmt ref
);
@stmt_for_or_range_based_for = @stmt_for
| @stmt_range_based_for;
for_initialization(
unique int for_stmt: @stmt_for ref,
unique int for_stmt: @stmt_for_or_range_based_for ref,
int init_id: @stmt ref
);

View File

@@ -0,0 +1,19 @@
class Element extends @element {
string toString() { none() }
}
class Expr extends @expr {
string toString() { none() }
}
class Stmt extends @stmt {
string toString() { none() }
}
predicate isStmtWithInitializer(Stmt stmt) { exists(int kind | stmts(stmt, kind, _) | kind = 29) }
from Expr child, int index, int index_new, Element parent
where
exprparents(child, index, parent) and
if isStmtWithInitializer(parent) then index_new = index + 1 else index_new = index
select child, index_new, parent

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
class Element extends @element {
string toString() { none() }
}
class Stmt extends @stmt {
string toString() { none() }
}
predicate isStmtWithInitializer(Stmt stmt) { exists(int kind | stmts(stmt, kind, _) | kind = 29) }
from Stmt child, int index, int index_new, Element parent
where
stmtparents(child, index, parent) and
if isStmtWithInitializer(parent) then index_new = index + 1 else index_new = index
select child, index_new, parent

View File

@@ -0,0 +1,4 @@
description: Support C++20 range-based for initializers
compatibility: partial
exprparents.rel: run exprparents.qlo
stmtparents.rel: run stmtparents.qlo

View File

@@ -1,3 +1,10 @@
## 0.9.5
### Minor Analysis Improvements
* The "non-constant format string" query (`cpp/non-constant-format`) has been updated to produce fewer false positives.
* Added dataflow models for the `gettext` function variants.
## 0.9.4
### Minor Analysis Improvements
@@ -6,7 +13,6 @@
* The "Incorrect return-value check for a 'scanf'-like function" query (`cpp/incorrectly-checked-scanf`) no longer reports an alert when an explicit check for EOF is added.
* The "Incorrect return-value check for a 'scanf'-like function" query (`cpp/incorrectly-checked-scanf`) now recognizes more EOF checks.
* The "Potentially uninitialized local variable" query (`cpp/uninitialized-local`) no longer reports an alert when the local variable is used as a qualifier to a static member function call.
* ```
* The diagnostic query `cpp/diagnostics/successfully-extracted-files` now considers any C/C++ file seen during extraction, even one with some errors, to be extracted / scanned. This affects the Code Scanning UI measure of scanned C/C++ files.
## 0.9.3

View File

@@ -1,9 +1,13 @@
/**
* @name Non-constant format string
* @description Passing a non-constant 'format' string to a printf-like function can lead
* @description Passing a value that is not a string literal 'format' string to a printf-like function can lead
* to a mismatch between the number of arguments defined by the 'format' and the number
* of arguments actually passed to the function. If the format string ultimately stems
* from an untrusted source, this can be used for exploits.
* This query finds format strings coming from non-literal sources. Note that format strings of
* type `const char*` it is still considered non-constant if the value is not coming from a string
* literal. For example, for a parameter with type `const char*` of an exported function that is
* used as a format string, there is no way to ensure the originating value was a string literal.
* @kind problem
* @problem.severity recommendation
* @security-severity 9.3
@@ -17,142 +21,117 @@
import semmle.code.cpp.ir.dataflow.TaintTracking
import semmle.code.cpp.commons.Printf
import semmle.code.cpp.security.FlowSources
import semmle.code.cpp.ir.dataflow.internal.ModelUtil
import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.ir.IR
// For the following `...gettext` functions, we assume that
// all translations preserve the type and order of `%` specifiers
// (and hence are safe to use as format strings). This
// assumption is hard-coded into the query.
predicate whitelistFunction(Function f, int arg) {
// basic variations of gettext
f.getName() = "_" and arg = 0
or
f.getName() = "gettext" and arg = 0
or
f.getName() = "dgettext" and arg = 1
or
f.getName() = "dcgettext" and arg = 1
or
// plural variations of gettext that take one format string for singular and another for plural form
f.getName() = "ngettext" and
(arg = 0 or arg = 1)
or
f.getName() = "dngettext" and
(arg = 1 or arg = 2)
or
f.getName() = "dcngettext" and
(arg = 1 or arg = 2)
class UncalledFunction extends Function {
UncalledFunction() {
not exists(Call c | c.getTarget() = this) and
// Ignore functions that appear to be function pointers
// function pointers may be seen as uncalled statically
not exists(FunctionAccess fa | fa.getTarget() = this)
}
}
// we assume that ALL uses of the `_` macro
// return constant string literals
predicate underscoreMacro(Expr e) {
exists(MacroInvocation mi |
mi.getMacroName() = "_" and
mi.getExpr() = e
/**
* Holds if `node` is a non-constant source of data flow for non-const format string detection.
* This is defined as either:
* 1) a `FlowSource`
* 2) a parameter of an 'uncalled' function
* 3) an argument to a function with no definition that is not known to define the output through its input
* 4) an out arg of a function with no definition that is not known to define the output through its input
*
* The latter two cases address identifying standard string manipulation libraries as input sources
* e.g., strcpy. More simply, functions without definitions that are known to manipulate the
* input to produce an output are not sources. Instead the ultimate source of input to these functions
* should be considered as the source.
*
* False Negative Implication: This approach has false negatives (fails to identify non-const sources)
* when the source is a field of a struct or object and the initialization is not observed statically.
* There are 3 general cases where this can occur:
* 1) Parameters of uncalled functions that are structs/objects and a field is accessed for a format string.
* 2) A local variable that is a struct/object and initialization of the field occurs in code that is unseen statically.
* e.g., an object constructor isn't known statically, or a function sets fields
* of a struct, but the function is not known statically.
* 3) A function meeting cases (3) and (4) above returns (through an out argument or return value)
* a struct or object where a field containing a format string has been initialized.
*
* Note, uninitialized variables used as format strings are never detected by design.
* Uninitialized variables are a separate vulnerability concern and should be addressed by a separate query.
*/
predicate isNonConst(DataFlow::Node node) {
node instanceof FlowSource
or
// Parameters of uncalled functions that aren't const
exists(UncalledFunction f, Parameter p |
f.getAParameter() = p and
p = node.asParameter()
)
or
// Consider as an input any out arg of a function or a function's return where the function is not:
// 1. a function with a known dataflow or taintflow from input to output and the `node` is the output
// 2. a function where there is a known definition
// i.e., functions that with unknown bodies and are not known to define the output through its input
// are considered as possible non-const sources
// The function's output must also not be const to be considered a non-const source
exists(Function func, CallInstruction call |
// NOTE: could use `Call` getAnArgument() instead of `CallInstruction` but requires two
// variables representing the same call in ordoer to use `callOutput` below.
exists(Expr arg |
call.getPositionalArgumentOperand(_).getDef().getUnconvertedResultExpression() = arg and
arg = node.asDefiningArgument()
)
or
call.getUnconvertedResultExpression() = node.asIndirectExpr()
|
func = call.getStaticCallTarget() and
not exists(FunctionOutput output |
// NOTE: we must include dataflow and taintflow. e.g., including only dataflow we will find sprintf
// variant function's output are now possible non-const sources
pragma[only_bind_out](func).(DataFlowFunction).hasDataFlow(_, output) or
pragma[only_bind_out](func).(TaintFunction).hasTaintFlow(_, output)
|
node = callOutput(call, output)
)
) and
not exists(Call c |
c.getTarget().hasDefinition() and
if node instanceof DataFlow::DefinitionByReferenceNode
then c.getAnArgument() = node.asDefiningArgument()
else c = [node.asExpr(), node.asIndirectExpr()]
)
}
/**
* Holds if `t` cannot hold a character array, directly or indirectly.
* Holds if `sink` is a sink is a format string of any
* `FormattingFunctionCall`.
*/
predicate cannotContainString(Type t, boolean isIndirect) {
isIndirect = false and
exists(Type unspecified |
unspecified = t.getUnspecifiedType() and
not unspecified instanceof UnknownType
|
unspecified instanceof BuiltInType or
unspecified instanceof IntegralOrEnumType
)
}
predicate isNonConst(DataFlow::Node node, boolean isIndirect) {
exists(Expr e |
e = node.asExpr() and isIndirect = false
or
e = node.asIndirectExpr() and isIndirect = true
|
exists(FunctionCall fc | fc = e |
not (
whitelistFunction(fc.getTarget(), _) or
fc.getTarget().hasDefinition()
)
)
or
exists(Parameter p | p = e.(VariableAccess).getTarget() |
p.getFunction().getName() = "main" and p.getType() instanceof PointerType
)
or
e instanceof CrementOperation
or
e instanceof AddressOfExpr
or
e instanceof ReferenceToExpr
or
e instanceof AssignPointerAddExpr
or
e instanceof AssignPointerSubExpr
or
e instanceof PointerArithmeticOperation
or
e instanceof FieldAccess
or
e instanceof PointerDereferenceExpr
or
e instanceof AddressOfExpr
or
e instanceof ExprCall
or
e instanceof NewArrayExpr
or
exists(Variable v | v = e.(VariableAccess).getTarget() |
v.getType().(ArrayType).getBaseType() instanceof CharType and
exists(AssignExpr ae |
ae.getLValue().(ArrayExpr).getArrayBase().(VariableAccess).getTarget() = v
)
)
)
or
node instanceof DataFlow::DefinitionByReferenceNode and
isIndirect = true
}
pragma[noinline]
predicate isBarrierNode(DataFlow::Node node) {
underscoreMacro([node.asExpr(), node.asIndirectExpr()])
or
exists(node.asExpr()) and
cannotContainString(node.getType(), false)
}
predicate isSinkImpl(DataFlow::Node sink, Expr formatString) {
[sink.asExpr(), sink.asIndirectExpr()] = formatString and
exists(FormattingFunctionCall fc | formatString = fc.getArgument(fc.getFormatParameterIndex()))
}
module NonConstFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(boolean isIndirect, Type t |
isNonConst(source, isIndirect) and
t = source.getType() and
not cannotContainString(t, isIndirect)
)
}
predicate isSource(DataFlow::Node source) { isNonConst(source) }
predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _) }
predicate isBarrier(DataFlow::Node node) { isBarrierNode(node) }
predicate isBarrier(DataFlow::Node node) {
// Ignore tracing non-const through array indices
exists(ArrayExpr a | a.getArrayOffset() = node.asExpr())
}
}
module NonConstFlow = TaintTracking::Global<NonConstFlowConfig>;
from FormattingFunctionCall call, Expr formatString
from FormattingFunctionCall call, Expr formatString, DataFlow::Node sink
where
call.getArgument(call.getFormatParameterIndex()) = formatString and
exists(DataFlow::Node sink |
NonConstFlow::flowTo(sink) and
isSinkImpl(sink, formatString)
)
NonConstFlow::flowTo(sink) and
isSinkImpl(sink, formatString)
select formatString,
"The format string argument to " + call.getTarget().getName() +
" should be constant to prevent security issues and other potential errors."

View File

@@ -6,5 +6,4 @@
* The "Incorrect return-value check for a 'scanf'-like function" query (`cpp/incorrectly-checked-scanf`) no longer reports an alert when an explicit check for EOF is added.
* The "Incorrect return-value check for a 'scanf'-like function" query (`cpp/incorrectly-checked-scanf`) now recognizes more EOF checks.
* The "Potentially uninitialized local variable" query (`cpp/uninitialized-local`) no longer reports an alert when the local variable is used as a qualifier to a static member function call.
* ```
* The diagnostic query `cpp/diagnostics/successfully-extracted-files` now considers any C/C++ file seen during extraction, even one with some errors, to be extracted / scanned. This affects the Code Scanning UI measure of scanned C/C++ files.

View File

@@ -0,0 +1,6 @@
## 0.9.5
### Minor Analysis Improvements
* The "non-constant format string" query (`cpp/non-constant-format`) has been updated to produce fewer false positives.
* Added dataflow models for the `gettext` function variants.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.9.4
lastReleaseVersion: 0.9.5

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.9.4
version: 0.9.5
groups:
- cpp
- queries

View File

@@ -1,5 +1,5 @@
edges
| test.cpp:22:27:22:30 | **argv | test.cpp:29:13:29:20 | *filePath |
| test.cpp:22:27:22:30 | **argv | test.cpp:29:13:29:20 | *filePath | provenance | |
nodes
| test.cpp:22:27:22:30 | **argv | semmle.label | **argv |
| test.cpp:29:13:29:20 | *filePath | semmle.label | *filePath |

View File

@@ -1,7 +1,7 @@
edges
| test.cpp:22:17:22:21 | ... * ... | test.cpp:23:33:23:37 | size1 |
| test.cpp:37:24:37:27 | size | test.cpp:37:46:37:49 | size |
| test.cpp:45:36:45:40 | ... * ... | test.cpp:37:24:37:27 | size |
| test.cpp:22:17:22:21 | ... * ... | test.cpp:23:33:23:37 | size1 | provenance | |
| test.cpp:37:24:37:27 | size | test.cpp:37:46:37:49 | size | provenance | |
| test.cpp:45:36:45:40 | ... * ... | test.cpp:37:24:37:27 | size | provenance | |
nodes
| test.cpp:13:33:13:37 | ... * ... | semmle.label | ... * ... |
| test.cpp:15:31:15:35 | ... * ... | semmle.label | ... * ... |

View File

@@ -1,43 +1,43 @@
edges
| test.cpp:4:17:4:22 | call to malloc | test.cpp:6:9:6:11 | arr |
| test.cpp:4:17:4:22 | call to malloc | test.cpp:10:9:10:11 | arr |
| test.cpp:19:9:19:16 | *mk_array [p] | test.cpp:28:19:28:26 | call to mk_array [p] |
| test.cpp:19:9:19:16 | *mk_array [p] | test.cpp:50:18:50:25 | call to mk_array [p] |
| test.cpp:21:5:21:7 | *arr [post update] [p] | test.cpp:22:5:22:7 | *arr [p] |
| test.cpp:21:5:21:24 | ... = ... | test.cpp:21:5:21:7 | *arr [post update] [p] |
| test.cpp:21:13:21:18 | call to malloc | test.cpp:21:5:21:24 | ... = ... |
| test.cpp:22:5:22:7 | *arr [p] | test.cpp:19:9:19:16 | *mk_array [p] |
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:31:9:31:11 | *arr [p] |
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:35:9:35:11 | *arr [p] |
| test.cpp:31:9:31:11 | *arr [p] | test.cpp:31:13:31:13 | p |
| test.cpp:35:9:35:11 | *arr [p] | test.cpp:35:13:35:13 | p |
| test.cpp:39:27:39:29 | arr [p] | test.cpp:41:9:41:11 | *arr [p] |
| test.cpp:39:27:39:29 | arr [p] | test.cpp:45:9:45:11 | *arr [p] |
| test.cpp:41:9:41:11 | *arr [p] | test.cpp:41:13:41:13 | p |
| test.cpp:45:9:45:11 | *arr [p] | test.cpp:45:13:45:13 | p |
| test.cpp:50:18:50:25 | call to mk_array [p] | test.cpp:39:27:39:29 | arr [p] |
| test.cpp:55:5:55:7 | *arr [post update] [p] | test.cpp:56:5:56:7 | *arr [p] |
| test.cpp:55:5:55:24 | ... = ... | test.cpp:55:5:55:7 | *arr [post update] [p] |
| test.cpp:55:13:55:18 | call to malloc | test.cpp:55:5:55:24 | ... = ... |
| test.cpp:56:5:56:7 | *arr [p] | test.cpp:59:9:59:11 | *arr [p] |
| test.cpp:56:5:56:7 | *arr [p] | test.cpp:63:9:63:11 | *arr [p] |
| test.cpp:59:9:59:11 | *arr [p] | test.cpp:59:13:59:13 | p |
| test.cpp:63:9:63:11 | *arr [p] | test.cpp:63:13:63:13 | p |
| test.cpp:67:10:67:19 | **mk_array_p [p] | test.cpp:76:20:76:29 | *call to mk_array_p [p] |
| test.cpp:67:10:67:19 | **mk_array_p [p] | test.cpp:98:18:98:27 | *call to mk_array_p [p] |
| test.cpp:69:5:69:7 | *arr [post update] [p] | test.cpp:70:5:70:7 | *arr [p] |
| test.cpp:69:5:69:25 | ... = ... | test.cpp:69:5:69:7 | *arr [post update] [p] |
| test.cpp:69:14:69:19 | call to malloc | test.cpp:69:5:69:25 | ... = ... |
| test.cpp:70:5:70:7 | *arr [p] | test.cpp:67:10:67:19 | **mk_array_p [p] |
| test.cpp:76:20:76:29 | *call to mk_array_p [p] | test.cpp:79:9:79:11 | *arr [p] |
| test.cpp:76:20:76:29 | *call to mk_array_p [p] | test.cpp:83:9:83:11 | *arr [p] |
| test.cpp:79:9:79:11 | *arr [p] | test.cpp:79:14:79:14 | p |
| test.cpp:83:9:83:11 | *arr [p] | test.cpp:83:14:83:14 | p |
| test.cpp:87:28:87:30 | *arr [p] | test.cpp:89:9:89:11 | *arr [p] |
| test.cpp:87:28:87:30 | *arr [p] | test.cpp:93:9:93:11 | *arr [p] |
| test.cpp:89:9:89:11 | *arr [p] | test.cpp:89:14:89:14 | p |
| test.cpp:93:9:93:11 | *arr [p] | test.cpp:93:14:93:14 | p |
| test.cpp:98:18:98:27 | *call to mk_array_p [p] | test.cpp:87:28:87:30 | *arr [p] |
| test.cpp:4:17:4:22 | call to malloc | test.cpp:6:9:6:11 | arr | provenance | |
| test.cpp:4:17:4:22 | call to malloc | test.cpp:10:9:10:11 | arr | provenance | |
| test.cpp:19:9:19:16 | *mk_array [p] | test.cpp:28:19:28:26 | call to mk_array [p] | provenance | |
| test.cpp:19:9:19:16 | *mk_array [p] | test.cpp:50:18:50:25 | call to mk_array [p] | provenance | |
| test.cpp:21:5:21:7 | *arr [post update] [p] | test.cpp:22:5:22:7 | *arr [p] | provenance | |
| test.cpp:21:5:21:24 | ... = ... | test.cpp:21:5:21:7 | *arr [post update] [p] | provenance | |
| test.cpp:21:13:21:18 | call to malloc | test.cpp:21:5:21:24 | ... = ... | provenance | |
| test.cpp:22:5:22:7 | *arr [p] | test.cpp:19:9:19:16 | *mk_array [p] | provenance | |
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:31:9:31:11 | *arr [p] | provenance | |
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:35:9:35:11 | *arr [p] | provenance | |
| test.cpp:31:9:31:11 | *arr [p] | test.cpp:31:13:31:13 | p | provenance | |
| test.cpp:35:9:35:11 | *arr [p] | test.cpp:35:13:35:13 | p | provenance | |
| test.cpp:39:27:39:29 | arr [p] | test.cpp:41:9:41:11 | *arr [p] | provenance | |
| test.cpp:39:27:39:29 | arr [p] | test.cpp:45:9:45:11 | *arr [p] | provenance | |
| test.cpp:41:9:41:11 | *arr [p] | test.cpp:41:13:41:13 | p | provenance | |
| test.cpp:45:9:45:11 | *arr [p] | test.cpp:45:13:45:13 | p | provenance | |
| test.cpp:50:18:50:25 | call to mk_array [p] | test.cpp:39:27:39:29 | arr [p] | provenance | |
| test.cpp:55:5:55:7 | *arr [post update] [p] | test.cpp:56:5:56:7 | *arr [p] | provenance | |
| test.cpp:55:5:55:24 | ... = ... | test.cpp:55:5:55:7 | *arr [post update] [p] | provenance | |
| test.cpp:55:13:55:18 | call to malloc | test.cpp:55:5:55:24 | ... = ... | provenance | |
| test.cpp:56:5:56:7 | *arr [p] | test.cpp:59:9:59:11 | *arr [p] | provenance | |
| test.cpp:56:5:56:7 | *arr [p] | test.cpp:63:9:63:11 | *arr [p] | provenance | |
| test.cpp:59:9:59:11 | *arr [p] | test.cpp:59:13:59:13 | p | provenance | |
| test.cpp:63:9:63:11 | *arr [p] | test.cpp:63:13:63:13 | p | provenance | |
| test.cpp:67:10:67:19 | **mk_array_p [p] | test.cpp:76:20:76:29 | *call to mk_array_p [p] | provenance | |
| test.cpp:67:10:67:19 | **mk_array_p [p] | test.cpp:98:18:98:27 | *call to mk_array_p [p] | provenance | |
| test.cpp:69:5:69:7 | *arr [post update] [p] | test.cpp:70:5:70:7 | *arr [p] | provenance | |
| test.cpp:69:5:69:25 | ... = ... | test.cpp:69:5:69:7 | *arr [post update] [p] | provenance | |
| test.cpp:69:14:69:19 | call to malloc | test.cpp:69:5:69:25 | ... = ... | provenance | |
| test.cpp:70:5:70:7 | *arr [p] | test.cpp:67:10:67:19 | **mk_array_p [p] | provenance | |
| test.cpp:76:20:76:29 | *call to mk_array_p [p] | test.cpp:79:9:79:11 | *arr [p] | provenance | |
| test.cpp:76:20:76:29 | *call to mk_array_p [p] | test.cpp:83:9:83:11 | *arr [p] | provenance | |
| test.cpp:79:9:79:11 | *arr [p] | test.cpp:79:14:79:14 | p | provenance | |
| test.cpp:83:9:83:11 | *arr [p] | test.cpp:83:14:83:14 | p | provenance | |
| test.cpp:87:28:87:30 | *arr [p] | test.cpp:89:9:89:11 | *arr [p] | provenance | |
| test.cpp:87:28:87:30 | *arr [p] | test.cpp:93:9:93:11 | *arr [p] | provenance | |
| test.cpp:89:9:89:11 | *arr [p] | test.cpp:89:14:89:14 | p | provenance | |
| test.cpp:93:9:93:11 | *arr [p] | test.cpp:93:14:93:14 | p | provenance | |
| test.cpp:98:18:98:27 | *call to mk_array_p [p] | test.cpp:87:28:87:30 | *arr [p] | provenance | |
nodes
| test.cpp:4:17:4:22 | call to malloc | semmle.label | call to malloc |
| test.cpp:6:9:6:11 | arr | semmle.label | arr |

View File

@@ -1,74 +1,74 @@
edges
| test.cpp:34:10:34:12 | buf | test.cpp:34:5:34:24 | access to array |
| test.cpp:35:10:35:12 | buf | test.cpp:35:5:35:22 | access to array |
| test.cpp:36:10:36:12 | buf | test.cpp:36:5:36:24 | access to array |
| test.cpp:39:14:39:16 | buf | test.cpp:39:9:39:19 | access to array |
| test.cpp:43:14:43:16 | buf | test.cpp:43:9:43:19 | access to array |
| test.cpp:48:10:48:12 | buf | test.cpp:48:5:48:24 | access to array |
| test.cpp:49:10:49:12 | buf | test.cpp:49:5:49:22 | access to array |
| test.cpp:50:10:50:12 | buf | test.cpp:50:5:50:24 | access to array |
| test.cpp:53:14:53:16 | buf | test.cpp:53:9:53:19 | access to array |
| test.cpp:57:14:57:16 | buf | test.cpp:57:9:57:19 | access to array |
| test.cpp:61:14:61:16 | buf | test.cpp:61:9:61:19 | access to array |
| test.cpp:70:33:70:33 | p | test.cpp:71:5:71:17 | access to array |
| test.cpp:70:33:70:33 | p | test.cpp:72:5:72:15 | access to array |
| test.cpp:76:26:76:46 | & ... | test.cpp:66:32:66:32 | p |
| test.cpp:76:32:76:34 | buf | test.cpp:76:26:76:46 | & ... |
| test.cpp:77:26:77:44 | & ... | test.cpp:66:32:66:32 | p |
| test.cpp:77:32:77:34 | buf | test.cpp:77:26:77:44 | & ... |
| test.cpp:79:27:79:34 | buf | test.cpp:70:33:70:33 | p |
| test.cpp:79:32:79:34 | buf | test.cpp:79:27:79:34 | buf |
| test.cpp:85:34:85:36 | buf | test.cpp:87:5:87:31 | access to array |
| test.cpp:85:34:85:36 | buf | test.cpp:88:5:88:27 | access to array |
| test.cpp:96:13:96:15 | arr | test.cpp:96:13:96:18 | access to array |
| test.cpp:111:17:111:19 | arr | test.cpp:111:17:111:22 | access to array |
| test.cpp:111:17:111:19 | arr | test.cpp:115:35:115:40 | access to array |
| test.cpp:111:17:111:19 | arr | test.cpp:119:17:119:22 | access to array |
| test.cpp:115:35:115:37 | arr | test.cpp:111:17:111:22 | access to array |
| test.cpp:115:35:115:37 | arr | test.cpp:115:35:115:40 | access to array |
| test.cpp:115:35:115:37 | arr | test.cpp:119:17:119:22 | access to array |
| test.cpp:119:17:119:19 | arr | test.cpp:111:17:111:22 | access to array |
| test.cpp:119:17:119:19 | arr | test.cpp:115:35:115:40 | access to array |
| test.cpp:119:17:119:19 | arr | test.cpp:119:17:119:22 | access to array |
| test.cpp:128:9:128:11 | arr | test.cpp:128:9:128:14 | access to array |
| test.cpp:134:25:134:27 | arr | test.cpp:136:9:136:16 | ... += ... |
| test.cpp:136:9:136:16 | ... += ... | test.cpp:138:13:138:15 | arr |
| test.cpp:143:18:143:21 | asdf | test.cpp:134:25:134:27 | arr |
| test.cpp:143:18:143:21 | asdf | test.cpp:143:18:143:21 | asdf |
| test.cpp:146:26:146:26 | *p | test.cpp:147:4:147:9 | -- ... |
| test.cpp:156:12:156:14 | buf | test.cpp:156:12:156:18 | ... + ... |
| test.cpp:156:12:156:18 | ... + ... | test.cpp:158:17:158:18 | *& ... |
| test.cpp:158:17:158:18 | *& ... | test.cpp:146:26:146:26 | *p |
| test.cpp:218:23:218:28 | buffer | test.cpp:220:5:220:11 | access to array |
| test.cpp:218:23:218:28 | buffer | test.cpp:221:5:221:11 | access to array |
| test.cpp:229:25:229:29 | array | test.cpp:231:5:231:10 | access to array |
| test.cpp:229:25:229:29 | array | test.cpp:232:5:232:10 | access to array |
| test.cpp:245:30:245:30 | p | test.cpp:261:27:261:30 | access to array |
| test.cpp:245:30:245:30 | p | test.cpp:261:27:261:30 | access to array |
| test.cpp:274:14:274:20 | buffer3 | test.cpp:245:30:245:30 | p |
| test.cpp:274:14:274:20 | buffer3 | test.cpp:274:14:274:20 | buffer3 |
| test.cpp:277:35:277:35 | p | test.cpp:278:14:278:14 | p |
| test.cpp:278:14:278:14 | p | test.cpp:245:30:245:30 | p |
| test.cpp:283:19:283:25 | buffer1 | test.cpp:277:35:277:35 | p |
| test.cpp:283:19:283:25 | buffer1 | test.cpp:283:19:283:25 | buffer1 |
| test.cpp:286:19:286:25 | buffer2 | test.cpp:277:35:277:35 | p |
| test.cpp:286:19:286:25 | buffer2 | test.cpp:286:19:286:25 | buffer2 |
| test.cpp:289:19:289:25 | buffer3 | test.cpp:277:35:277:35 | p |
| test.cpp:289:19:289:25 | buffer3 | test.cpp:289:19:289:25 | buffer3 |
| test.cpp:292:25:292:27 | arr | test.cpp:299:16:299:21 | access to array |
| test.cpp:292:25:292:27 | arr | test.cpp:299:16:299:21 | access to array |
| test.cpp:306:20:306:23 | arr1 | test.cpp:292:25:292:27 | arr |
| test.cpp:306:20:306:23 | arr1 | test.cpp:306:20:306:23 | arr1 |
| test.cpp:309:20:309:23 | arr2 | test.cpp:292:25:292:27 | arr |
| test.cpp:309:20:309:23 | arr2 | test.cpp:309:20:309:23 | arr2 |
| test.cpp:319:19:319:22 | temp | test.cpp:319:19:319:27 | ... + ... |
| test.cpp:319:19:319:22 | temp | test.cpp:324:23:324:32 | ... + ... |
| test.cpp:319:19:319:27 | ... + ... | test.cpp:325:24:325:26 | end |
| test.cpp:322:19:322:22 | temp | test.cpp:322:19:322:27 | ... + ... |
| test.cpp:322:19:322:22 | temp | test.cpp:324:23:324:32 | ... + ... |
| test.cpp:322:19:322:27 | ... + ... | test.cpp:325:24:325:26 | end |
| test.cpp:324:23:324:26 | temp | test.cpp:324:23:324:32 | ... + ... |
| test.cpp:324:23:324:32 | ... + ... | test.cpp:325:15:325:19 | temp2 |
| test.cpp:34:10:34:12 | buf | test.cpp:34:5:34:24 | access to array | provenance | |
| test.cpp:35:10:35:12 | buf | test.cpp:35:5:35:22 | access to array | provenance | |
| test.cpp:36:10:36:12 | buf | test.cpp:36:5:36:24 | access to array | provenance | |
| test.cpp:39:14:39:16 | buf | test.cpp:39:9:39:19 | access to array | provenance | |
| test.cpp:43:14:43:16 | buf | test.cpp:43:9:43:19 | access to array | provenance | |
| test.cpp:48:10:48:12 | buf | test.cpp:48:5:48:24 | access to array | provenance | |
| test.cpp:49:10:49:12 | buf | test.cpp:49:5:49:22 | access to array | provenance | |
| test.cpp:50:10:50:12 | buf | test.cpp:50:5:50:24 | access to array | provenance | |
| test.cpp:53:14:53:16 | buf | test.cpp:53:9:53:19 | access to array | provenance | |
| test.cpp:57:14:57:16 | buf | test.cpp:57:9:57:19 | access to array | provenance | |
| test.cpp:61:14:61:16 | buf | test.cpp:61:9:61:19 | access to array | provenance | |
| test.cpp:70:33:70:33 | p | test.cpp:71:5:71:17 | access to array | provenance | |
| test.cpp:70:33:70:33 | p | test.cpp:72:5:72:15 | access to array | provenance | |
| test.cpp:76:26:76:46 | & ... | test.cpp:66:32:66:32 | p | provenance | |
| test.cpp:76:32:76:34 | buf | test.cpp:76:26:76:46 | & ... | provenance | |
| test.cpp:77:26:77:44 | & ... | test.cpp:66:32:66:32 | p | provenance | |
| test.cpp:77:32:77:34 | buf | test.cpp:77:26:77:44 | & ... | provenance | |
| test.cpp:79:27:79:34 | buf | test.cpp:70:33:70:33 | p | provenance | |
| test.cpp:79:32:79:34 | buf | test.cpp:79:27:79:34 | buf | provenance | |
| test.cpp:85:34:85:36 | buf | test.cpp:87:5:87:31 | access to array | provenance | |
| test.cpp:85:34:85:36 | buf | test.cpp:88:5:88:27 | access to array | provenance | |
| test.cpp:96:13:96:15 | arr | test.cpp:96:13:96:18 | access to array | provenance | |
| test.cpp:111:17:111:19 | arr | test.cpp:111:17:111:22 | access to array | provenance | |
| test.cpp:111:17:111:19 | arr | test.cpp:115:35:115:40 | access to array | provenance | |
| test.cpp:111:17:111:19 | arr | test.cpp:119:17:119:22 | access to array | provenance | |
| test.cpp:115:35:115:37 | arr | test.cpp:111:17:111:22 | access to array | provenance | |
| test.cpp:115:35:115:37 | arr | test.cpp:115:35:115:40 | access to array | provenance | |
| test.cpp:115:35:115:37 | arr | test.cpp:119:17:119:22 | access to array | provenance | |
| test.cpp:119:17:119:19 | arr | test.cpp:111:17:111:22 | access to array | provenance | |
| test.cpp:119:17:119:19 | arr | test.cpp:115:35:115:40 | access to array | provenance | |
| test.cpp:119:17:119:19 | arr | test.cpp:119:17:119:22 | access to array | provenance | |
| test.cpp:128:9:128:11 | arr | test.cpp:128:9:128:14 | access to array | provenance | |
| test.cpp:134:25:134:27 | arr | test.cpp:136:9:136:16 | ... += ... | provenance | |
| test.cpp:136:9:136:16 | ... += ... | test.cpp:138:13:138:15 | arr | provenance | |
| test.cpp:143:18:143:21 | asdf | test.cpp:134:25:134:27 | arr | provenance | |
| test.cpp:143:18:143:21 | asdf | test.cpp:143:18:143:21 | asdf | provenance | |
| test.cpp:146:26:146:26 | *p | test.cpp:147:4:147:9 | -- ... | provenance | |
| test.cpp:156:12:156:14 | buf | test.cpp:156:12:156:18 | ... + ... | provenance | |
| test.cpp:156:12:156:18 | ... + ... | test.cpp:158:17:158:18 | *& ... | provenance | |
| test.cpp:158:17:158:18 | *& ... | test.cpp:146:26:146:26 | *p | provenance | |
| test.cpp:218:23:218:28 | buffer | test.cpp:220:5:220:11 | access to array | provenance | |
| test.cpp:218:23:218:28 | buffer | test.cpp:221:5:221:11 | access to array | provenance | |
| test.cpp:229:25:229:29 | array | test.cpp:231:5:231:10 | access to array | provenance | |
| test.cpp:229:25:229:29 | array | test.cpp:232:5:232:10 | access to array | provenance | |
| test.cpp:245:30:245:30 | p | test.cpp:261:27:261:30 | access to array | provenance | |
| test.cpp:245:30:245:30 | p | test.cpp:261:27:261:30 | access to array | provenance | |
| test.cpp:274:14:274:20 | buffer3 | test.cpp:245:30:245:30 | p | provenance | |
| test.cpp:274:14:274:20 | buffer3 | test.cpp:274:14:274:20 | buffer3 | provenance | |
| test.cpp:277:35:277:35 | p | test.cpp:278:14:278:14 | p | provenance | |
| test.cpp:278:14:278:14 | p | test.cpp:245:30:245:30 | p | provenance | |
| test.cpp:283:19:283:25 | buffer1 | test.cpp:277:35:277:35 | p | provenance | |
| test.cpp:283:19:283:25 | buffer1 | test.cpp:283:19:283:25 | buffer1 | provenance | |
| test.cpp:286:19:286:25 | buffer2 | test.cpp:277:35:277:35 | p | provenance | |
| test.cpp:286:19:286:25 | buffer2 | test.cpp:286:19:286:25 | buffer2 | provenance | |
| test.cpp:289:19:289:25 | buffer3 | test.cpp:277:35:277:35 | p | provenance | |
| test.cpp:289:19:289:25 | buffer3 | test.cpp:289:19:289:25 | buffer3 | provenance | |
| test.cpp:292:25:292:27 | arr | test.cpp:299:16:299:21 | access to array | provenance | |
| test.cpp:292:25:292:27 | arr | test.cpp:299:16:299:21 | access to array | provenance | |
| test.cpp:306:20:306:23 | arr1 | test.cpp:292:25:292:27 | arr | provenance | |
| test.cpp:306:20:306:23 | arr1 | test.cpp:306:20:306:23 | arr1 | provenance | |
| test.cpp:309:20:309:23 | arr2 | test.cpp:292:25:292:27 | arr | provenance | |
| test.cpp:309:20:309:23 | arr2 | test.cpp:309:20:309:23 | arr2 | provenance | |
| test.cpp:319:19:319:22 | temp | test.cpp:319:19:319:27 | ... + ... | provenance | |
| test.cpp:319:19:319:22 | temp | test.cpp:324:23:324:32 | ... + ... | provenance | |
| test.cpp:319:19:319:27 | ... + ... | test.cpp:325:24:325:26 | end | provenance | |
| test.cpp:322:19:322:22 | temp | test.cpp:322:19:322:27 | ... + ... | provenance | |
| test.cpp:322:19:322:22 | temp | test.cpp:324:23:324:32 | ... + ... | provenance | |
| test.cpp:322:19:322:27 | ... + ... | test.cpp:325:24:325:26 | end | provenance | |
| test.cpp:324:23:324:26 | temp | test.cpp:324:23:324:32 | ... + ... | provenance | |
| test.cpp:324:23:324:32 | ... + ... | test.cpp:325:15:325:19 | temp2 | provenance | |
nodes
| test.cpp:34:5:34:24 | access to array | semmle.label | access to array |
| test.cpp:34:10:34:12 | buf | semmle.label | buf |

View File

@@ -1,14 +1,14 @@
edges
| test.cpp:45:18:45:23 | buffer | test.cpp:45:7:45:10 | *func |
| test.cpp:74:24:74:30 | medical | test.cpp:78:24:78:27 | temp |
| 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: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:99:42:99:51 | theZipcode |
| test.cpp:99:61:99:70 | theZipcode | test.cpp:99:42:99:51 | theZipcode |
| test.cpp:45:18:45:23 | buffer | test.cpp:45:7:45:10 | *func | provenance | |
| test.cpp:74:24:74:30 | medical | test.cpp:78:24:78:27 | temp | provenance | |
| test.cpp:74:24:74:30 | medical | test.cpp:81:22:81:28 | medical | provenance | |
| test.cpp:77:16:77:22 | medical | test.cpp:78:24:78:27 | temp | provenance | |
| test.cpp:77:16:77:22 | medical | test.cpp:81:22:81:28 | medical | provenance | |
| test.cpp:81:17:81:20 | call to func | test.cpp:82:24:82:28 | buff5 | provenance | |
| test.cpp:81:22:81:28 | medical | test.cpp:45:18:45:23 | buffer | provenance | |
| test.cpp:81:22:81:28 | medical | test.cpp:81:17:81:20 | call to func | provenance | |
| test.cpp:96:37:96:46 | theZipcode | test.cpp:99:42:99:51 | theZipcode | provenance | |
| test.cpp:99:61:99:70 | theZipcode | test.cpp:99:42:99:51 | theZipcode | provenance | |
nodes
| test.cpp:45:7:45:10 | *func | semmle.label | *func |
| test.cpp:45:18:45:23 | buffer | semmle.label | buffer |

View File

@@ -165,6 +165,7 @@ postWithInFlow
| test.cpp:931:5:931:18 | global_pointer [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:932:5:932:19 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:932:6:932:19 | global_pointer [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:1045:9:1045:11 | ref arg buf | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge
uniqueParameterNodeAtPosition
uniqueParameterNodePosition

View File

@@ -25,6 +25,7 @@ postWithInFlow
| test.cpp:391:10:391:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
| test.cpp:400:10:400:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
| test.cpp:407:10:407:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
| test.cpp:1045:9:1045:11 | memset output argument | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge
uniqueParameterNodeAtPosition
uniqueParameterNodePosition

View File

@@ -303,6 +303,13 @@ irFlow
| test.cpp:914:46:914:53 | source | test.cpp:919:10:919:30 | global_pointer_static |
| test.cpp:915:57:915:76 | *indirect_source(1) | test.cpp:921:19:921:50 | *global_pointer_static_indirect_1 |
| test.cpp:932:23:932:28 | call to source | test.cpp:937:10:937:24 | * ... |
| test.cpp:958:18:958:32 | *call to indirect_source | test.cpp:961:19:961:28 | *translated |
| test.cpp:973:18:973:32 | *call to indirect_source | test.cpp:977:19:977:28 | *translated |
| test.cpp:994:18:994:32 | *call to indirect_source | test.cpp:999:19:999:28 | *translated |
| test.cpp:994:18:994:32 | *call to indirect_source | test.cpp:1003:19:1003:28 | *translated |
| test.cpp:1021:18:1021:32 | *call to indirect_source | test.cpp:1027:19:1027:28 | *translated |
| test.cpp:1021:18:1021:32 | *call to indirect_source | test.cpp:1031:19:1031:28 | *translated |
| test.cpp:1045:14:1045:19 | call to source | test.cpp:1046:7:1046:10 | * ... |
| true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x |
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |

View File

@@ -936,4 +936,112 @@ namespace global_variable_conflation_test {
sink(global_pointer); // clean
sink(*global_pointer); // $ ir MISSING: ast
}
}
char* gettext(const char*);
char* dgettext(const char*, const char*);
char* ngettext(const char*, const char*, unsigned long int);
char* dngettext (const char*, const char *, const char *, unsigned long int);
namespace test_gettext {
char* source();
char* indirect_source();
void test_gettext() {
char* data = source();
char* translated = gettext(data);
sink(translated); // clean
indirect_sink(translated); // clean
}
void indirect_test_dgettext() {
char* data = indirect_source();
char* translated = gettext(data);
sink(translated); // clean
indirect_sink(translated); // $ ir MISSING: ast
}
void test_dgettext() {
char* data = source();
char* domain = source(); // Should not trace from this source
char* translated = dgettext(domain, data);
sink(translated); // clean
indirect_sink(translated); // clean
}
void indirect_test_gettext() {
char* data = indirect_source();
char* domain = indirect_source(); // Should not trace from this source
char* translated = dgettext(domain, data);
sink(translated); // clean
indirect_sink(translated); // $ ir MISSING: ast
}
void test_ngettext() {
char* data = source();
char* np = nullptr; // Don't coun't as a source
char* translated = ngettext(data, np, 0);
sink(translated); // clean
indirect_sink(translated); // clean
translated = ngettext(np, data, 0);
sink(translated); // clean
indirect_sink(translated); // clean
}
void indirect_test_ngettext() {
char* data = indirect_source();
char* np = nullptr; // Don't coun't as a source
char* translated = ngettext(data, np, 0);
sink(translated); // clean
indirect_sink(translated); // $ ir MISSING: ast
translated = ngettext(np, data, 0);
sink(translated); // clean
indirect_sink(translated); // $ ir MISSING: ast
}
void test_dngettext() {
char* data = source();
char* np = nullptr; // Don't coun't as a source
char* domain = source(); // Should not trace from this source
char* translated = dngettext(domain, data, np, 0);
sink(translated); // clean
indirect_sink(translated); // clean
translated = dngettext(domain, np, data, 0);
sink(translated); // clean
indirect_sink(translated); // clean
}
void indirect_test_dngettext() {
char* data = indirect_source();
char* np = nullptr; // Don't coun't as a source
char* domain = indirect_source(); // Should not trace from this source
char* translated = dngettext(domain, data, np, 0);
sink(translated); // clean
indirect_sink(translated); // $ ir MISSING: ast
translated = dngettext(domain, np, data, 0);
sink(translated); // clean
indirect_sink(translated); // $ ir MISSING: ast
}
void indirect_test_gettext_no_flow_from_domain() {
char* domain = source(); // Should not trace from this source
char* translated = dgettext(domain, nullptr);
sink(translated); // clean
indirect_sink(translated); // clean
}
}
void* memset(void*, int, size_t);
void memset_test(char* buf) { // $ ast-def=buf
memset(buf, source(), 10);
sink(*buf); // $ ir MISSING: ast
}

View File

@@ -1,3 +1,18 @@
astTypeBugs
irTypeBugs
incorrectBaseType
| clang.cpp:22:8:22:20 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
| clang.cpp:23:17:23:29 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
| flowOut.cpp:50:14:50:15 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
| flowOut.cpp:84:9:84:10 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
| flowOut.cpp:101:13:101:14 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
| self_parameter_flow.cpp:8:8:8:9 | *& ... | Expected 'Node.getType()' to be unsigned char, but it was unsigned char * |
| test.cpp:67:28:67:37 | (reference dereference) | Expected 'Node.getType()' to be const int, but it was int * |
| test.cpp:531:39:531:40 | *& ... | Expected 'Node.getType()' to be int, but it was const int * |
| test.cpp:615:13:615:21 | *& ... | Expected 'Node.getType()' to be int, but it was void |
| test.cpp:704:22:704:25 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
| test.cpp:715:24:715:25 | *& ... | Expected 'Node.getType()' to be unsigned char, but it was unsigned char * |
| test.cpp:848:23:848:25 | (reference dereference) | Expected 'Node.getType()' to be int, but it was int * |
| test.cpp:854:10:854:36 | * ... | Expected 'Node.getType()' to be const int, but it was int |
| test.cpp:867:10:867:30 | * ... | Expected 'Node.getType()' to be const int, but it was int |
failures

View File

@@ -25,6 +25,17 @@ module IrTest {
n != 1
)
}
query predicate incorrectBaseType(Node n, string msg) {
exists(PointerType pointerType, Type nodeType, Type baseType |
not n.isGLValue() and
pointerType = n.asIndirectExpr(1).getActualType() and
baseType = pointerType.getBaseType() and
nodeType = n.getType() and
nodeType != baseType and
msg = "Expected 'Node.getType()' to be " + baseType + ", but it was " + nodeType
)
}
}
import IrTest

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,11 @@ unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
operandAcrossFunctions
instructionWithoutUniqueBlock
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
containsLoopOfForwardEdges
missingIRType
multipleIRTypes
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
@@ -24,8 +28,4 @@ nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
thisArgumentIsNonPointer
nonUniqueIRVariable
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType
multipleIRTypes
missingCppType

View File

@@ -12,7 +12,11 @@ unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
operandAcrossFunctions
instructionWithoutUniqueBlock
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
containsLoopOfForwardEdges
missingIRType
multipleIRTypes
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
@@ -24,8 +28,4 @@ nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
thisArgumentIsNonPointer
nonUniqueIRVariable
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType
multipleIRTypes
missingCppType

View File

@@ -1065,6 +1065,8 @@ struct vector {
bool operator!=(iterator right) const;
};
vector(T);
~vector();
iterator begin() const;
iterator end() const;
};
@@ -2112,4 +2114,56 @@ char* test_strtod(char *s) {
return end;
}
// semmle-extractor-options: -std=c++17 --clang
struct HasOperatorBool {
operator bool();
};
void call_as_child_of_ConditionDeclExpr() {
if(HasOperatorBool b = HasOperatorBool()) {}
}
class ClassWithDestructor {
char *x;
public:
ClassWithDestructor() { x = new char; }
~ClassWithDestructor() { delete x; }
void set_x(char y) { *x = y; }
char get_x() { return *x; }
};
constexpr bool initialization_with_destructor_bool = true;
void initialization_with_destructor(bool b, char c) {
if (ClassWithDestructor x; b)
x.set_x('a');
if constexpr (ClassWithDestructor x; initialization_with_destructor_bool)
x.set_x('a');
switch(ClassWithDestructor x; c) {
case 'a':
x.set_x('a');
break;
default:
x.set_x('b');
break;
}
ClassWithDestructor x;
for(vector<ClassWithDestructor> ys(x); ClassWithDestructor y : ys)
y.set_x('a');
for(vector<ClassWithDestructor> ys(x); ClassWithDestructor y : ys) {
y.set_x('a');
if (y.get_x() == 'b')
return;
}
for(vector<int> ys(1); int y : ys) {
if (y == 1)
return;
}
}
// semmle-extractor-options: -std=c++20 --clang

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,7 @@ multipleIRTypes
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
| ir.cpp:1486:8:1486:8 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | ir.cpp:1486:8:1486:8 | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() |
| ir.cpp:1488:8:1488:8 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | ir.cpp:1488:8:1488:8 | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() |
| try_except.c:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:6:6:6:6 | void f() | void f() |
| try_except.c:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:6:6:6:6 | void f() | void f() |
| try_except.c:39:15:39:15 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:32:6:32:6 | void h(int) | void h(int) |

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,11 @@ unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
operandAcrossFunctions
instructionWithoutUniqueBlock
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
containsLoopOfForwardEdges
missingIRType
multipleIRTypes
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
@@ -24,8 +28,4 @@ nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
thisArgumentIsNonPointer
nonUniqueIRVariable
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType
multipleIRTypes
missingCppType

View File

@@ -12,7 +12,11 @@ unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
operandAcrossFunctions
instructionWithoutUniqueBlock
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
containsLoopOfForwardEdges
missingIRType
multipleIRTypes
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
@@ -24,8 +28,4 @@ nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
thisArgumentIsNonPointer
nonUniqueIRVariable
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType
multipleIRTypes
missingCppType

View File

@@ -8,10 +8,6 @@ duplicateChiOperand
sideEffectWithoutPrimary
instructionWithoutSuccessor
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
| condition_decls.cpp:16:19:16:20 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
| condition_decls.cpp:26:23:26:24 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
| condition_decls.cpp:41:22:41:23 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| condition_decls.cpp:48:52:48:53 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
@@ -21,7 +17,11 @@ unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
operandAcrossFunctions
instructionWithoutUniqueBlock
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
containsLoopOfForwardEdges
missingIRType
multipleIRTypes
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
@@ -36,8 +36,4 @@ thisArgumentIsNonPointer
| pointer_to_member.cpp:23:5:23:54 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
| pointer_to_member.cpp:24:5:24:49 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
nonUniqueIRVariable
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType
multipleIRTypes
missingCppType

View File

@@ -1,8 +1,4 @@
missingOperand
| condition_decls.cpp:16:6:16:20 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
| condition_decls.cpp:26:10:26:24 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
| condition_decls.cpp:41:9:41:23 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| condition_decls.cpp:48:39:48:53 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| misc.c:125:5:125:11 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | misc.c:97:6:97:10 | void misc3() | void misc3() |
| try_catch.cpp:23:5:23:18 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | try_catch.cpp:19:6:19:23 | void throw_from_nonstmt(int) | void throw_from_nonstmt(int) |
unexpectedOperand
@@ -15,14 +11,6 @@ instructionWithoutSuccessor
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
| VacuousDestructorCall.cpp:3:3:3:3 | VariableAddress: x | Instruction 'VariableAddress: x' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
| VacuousDestructorCall.cpp:4:3:4:3 | Load: y | Instruction 'Load: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
| condition_decls.cpp:16:19:16:20 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
| condition_decls.cpp:26:19:26:20 | IndirectMayWriteSideEffect: bi | Instruction 'IndirectMayWriteSideEffect: bi' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
| condition_decls.cpp:26:23:26:24 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
| condition_decls.cpp:41:22:41:23 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| condition_decls.cpp:48:52:48:53 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |

View File

@@ -8,10 +8,6 @@ duplicateChiOperand
sideEffectWithoutPrimary
instructionWithoutSuccessor
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
| condition_decls.cpp:16:19:16:20 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
| condition_decls.cpp:26:23:26:24 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
| condition_decls.cpp:41:22:41:23 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| condition_decls.cpp:48:52:48:53 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
@@ -21,7 +17,11 @@ unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
operandAcrossFunctions
instructionWithoutUniqueBlock
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
containsLoopOfForwardEdges
missingIRType
multipleIRTypes
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
@@ -36,8 +36,4 @@ thisArgumentIsNonPointer
| pointer_to_member.cpp:23:5:23:54 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
| pointer_to_member.cpp:24:5:24:49 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
nonUniqueIRVariable
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType
multipleIRTypes
missingCppType

View File

@@ -1,16 +1,16 @@
edges
| test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:14:10:14:10 | a |
| test_free.cpp:30:10:30:10 | pointer to free output argument | test_free.cpp:31:27:31:27 | a |
| test_free.cpp:35:10:35:10 | pointer to free output argument | test_free.cpp:37:27:37:27 | a |
| test_free.cpp:42:27:42:27 | pointer to free output argument | test_free.cpp:46:10:46:10 | a |
| test_free.cpp:44:27:44:27 | pointer to free output argument | test_free.cpp:46:10:46:10 | a |
| test_free.cpp:50:27:50:27 | pointer to free output argument | test_free.cpp:51:10:51:10 | a |
| test_free.cpp:69:10:69:10 | pointer to free output argument | test_free.cpp:72:14:72:14 | a |
| test_free.cpp:83:12:83:12 | pointer to operator delete output argument | test_free.cpp:85:12:85:12 | a |
| test_free.cpp:101:10:101:10 | pointer to free output argument | test_free.cpp:103:10:103:10 | a |
| test_free.cpp:128:10:128:11 | pointer to free output argument | test_free.cpp:129:10:129:11 | * ... |
| test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:154:10:154:10 | a |
| test_free.cpp:207:10:207:10 | pointer to free output argument | test_free.cpp:209:10:209:10 | a |
| test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:14:10:14:10 | a | provenance | |
| test_free.cpp:30:10:30:10 | pointer to free output argument | test_free.cpp:31:27:31:27 | a | provenance | |
| test_free.cpp:35:10:35:10 | pointer to free output argument | test_free.cpp:37:27:37:27 | a | provenance | |
| test_free.cpp:42:27:42:27 | pointer to free output argument | test_free.cpp:46:10:46:10 | a | provenance | |
| test_free.cpp:44:27:44:27 | pointer to free output argument | test_free.cpp:46:10:46:10 | a | provenance | |
| test_free.cpp:50:27:50:27 | pointer to free output argument | test_free.cpp:51:10:51:10 | a | provenance | |
| test_free.cpp:69:10:69:10 | pointer to free output argument | test_free.cpp:72:14:72:14 | a | provenance | |
| test_free.cpp:83:12:83:12 | pointer to operator delete output argument | test_free.cpp:85:12:85:12 | a | provenance | |
| test_free.cpp:101:10:101:10 | pointer to free output argument | test_free.cpp:103:10:103:10 | a | provenance | |
| test_free.cpp:128:10:128:11 | pointer to free output argument | test_free.cpp:129:10:129:11 | * ... | provenance | |
| test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:154:10:154:10 | a | provenance | |
| test_free.cpp:207:10:207:10 | pointer to free output argument | test_free.cpp:209:10:209:10 | a | provenance | |
nodes
| test_free.cpp:11:10:11:10 | pointer to free output argument | semmle.label | pointer to free output argument |
| test_free.cpp:14:10:14:10 | a | semmle.label | a |

View File

@@ -1,27 +1,27 @@
edges
| test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:12:5:12:5 | a |
| test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:13:5:13:6 | * ... |
| test_free.cpp:42:27:42:27 | pointer to free output argument | test_free.cpp:45:5:45:5 | a |
| test_free.cpp:44:27:44:27 | pointer to free output argument | test_free.cpp:45:5:45:5 | a |
| test_free.cpp:69:10:69:10 | pointer to free output argument | test_free.cpp:71:9:71:9 | a |
| test_free.cpp:83:12:83:12 | pointer to operator delete output argument | test_free.cpp:84:5:84:5 | a |
| test_free.cpp:90:10:90:10 | pointer to free output argument | test_free.cpp:91:5:91:5 | a |
| test_free.cpp:95:10:95:10 | pointer to free output argument | test_free.cpp:96:9:96:9 | a |
| test_free.cpp:101:10:101:10 | pointer to free output argument | test_free.cpp:102:23:102:23 | a |
| test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:153:5:153:5 | a |
| test_free.cpp:233:14:233:15 | pointer to free output argument | test_free.cpp:236:9:236:10 | * ... |
| test_free.cpp:239:14:239:15 | pointer to free output argument | test_free.cpp:241:9:241:10 | * ... |
| test_free.cpp:245:10:245:11 | pointer to free output argument | test_free.cpp:246:9:246:10 | * ... |
| test_free.cpp:277:8:277:8 | *s [post update] [buf] | test_free.cpp:278:12:278:12 | *s [buf] |
| test_free.cpp:277:8:277:13 | pointer to free output argument | test_free.cpp:277:8:277:8 | *s [post update] [buf] |
| test_free.cpp:278:12:278:12 | *s [buf] | test_free.cpp:278:15:278:17 | buf |
| test_free.cpp:282:8:282:8 | *s [post update] [buf] | test_free.cpp:283:12:283:12 | *s [buf] |
| test_free.cpp:282:8:282:12 | pointer to free output argument | test_free.cpp:282:8:282:8 | *s [post update] [buf] |
| test_free.cpp:283:12:283:12 | *s [buf] | test_free.cpp:283:14:283:16 | buf |
| test_free.cpp:293:8:293:10 | pointer to free output argument | test_free.cpp:294:3:294:13 | ... = ... |
| test_free.cpp:294:3:294:3 | *s [post update] [buf] | test_free.cpp:295:12:295:12 | *s [buf] |
| test_free.cpp:294:3:294:13 | ... = ... | test_free.cpp:294:3:294:3 | *s [post update] [buf] |
| test_free.cpp:295:12:295:12 | *s [buf] | test_free.cpp:295:14:295:16 | buf |
| test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:12:5:12:5 | a | provenance | |
| test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:13:5:13:6 | * ... | provenance | |
| test_free.cpp:42:27:42:27 | pointer to free output argument | test_free.cpp:45:5:45:5 | a | provenance | |
| test_free.cpp:44:27:44:27 | pointer to free output argument | test_free.cpp:45:5:45:5 | a | provenance | |
| test_free.cpp:69:10:69:10 | pointer to free output argument | test_free.cpp:71:9:71:9 | a | provenance | |
| test_free.cpp:83:12:83:12 | pointer to operator delete output argument | test_free.cpp:84:5:84:5 | a | provenance | |
| test_free.cpp:90:10:90:10 | pointer to free output argument | test_free.cpp:91:5:91:5 | a | provenance | |
| test_free.cpp:95:10:95:10 | pointer to free output argument | test_free.cpp:96:9:96:9 | a | provenance | |
| test_free.cpp:101:10:101:10 | pointer to free output argument | test_free.cpp:102:23:102:23 | a | provenance | |
| test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:153:5:153:5 | a | provenance | |
| test_free.cpp:233:14:233:15 | pointer to free output argument | test_free.cpp:236:9:236:10 | * ... | provenance | |
| test_free.cpp:239:14:239:15 | pointer to free output argument | test_free.cpp:241:9:241:10 | * ... | provenance | |
| test_free.cpp:245:10:245:11 | pointer to free output argument | test_free.cpp:246:9:246:10 | * ... | provenance | |
| test_free.cpp:277:8:277:8 | *s [post update] [buf] | test_free.cpp:278:12:278:12 | *s [buf] | provenance | |
| test_free.cpp:277:8:277:13 | pointer to free output argument | test_free.cpp:277:8:277:8 | *s [post update] [buf] | provenance | |
| test_free.cpp:278:12:278:12 | *s [buf] | test_free.cpp:278:15:278:17 | buf | provenance | |
| test_free.cpp:282:8:282:8 | *s [post update] [buf] | test_free.cpp:283:12:283:12 | *s [buf] | provenance | |
| test_free.cpp:282:8:282:12 | pointer to free output argument | test_free.cpp:282:8:282:8 | *s [post update] [buf] | provenance | |
| test_free.cpp:283:12:283:12 | *s [buf] | test_free.cpp:283:14:283:16 | buf | provenance | |
| test_free.cpp:293:8:293:10 | pointer to free output argument | test_free.cpp:294:3:294:13 | ... = ... | provenance | |
| test_free.cpp:294:3:294:3 | *s [post update] [buf] | test_free.cpp:295:12:295:12 | *s [buf] | provenance | |
| test_free.cpp:294:3:294:13 | ... = ... | test_free.cpp:294:3:294:3 | *s [post update] [buf] | provenance | |
| test_free.cpp:295:12:295:12 | *s [buf] | test_free.cpp:295:14:295:16 | buf | provenance | |
nodes
| test_free.cpp:11:10:11:10 | pointer to free output argument | semmle.label | pointer to free output argument |
| test_free.cpp:12:5:12:5 | a | semmle.label | a |

View File

@@ -1,25 +1,25 @@
edges
| test.cpp:26:29:26:29 | b | test.cpp:27:2:27:2 | b |
| test.cpp:30:34:30:34 | b | test.cpp:31:2:31:2 | b |
| test.cpp:34:31:34:31 | b | test.cpp:35:2:35:2 | b |
| test.cpp:57:19:57:19 | d | test.cpp:26:29:26:29 | b |
| test.cpp:57:19:57:19 | d | test.cpp:58:25:58:25 | d |
| test.cpp:57:19:57:19 | d | test.cpp:59:21:59:21 | d |
| test.cpp:58:25:58:25 | d | test.cpp:30:34:30:34 | b |
| test.cpp:58:25:58:25 | d | test.cpp:59:21:59:21 | d |
| test.cpp:59:21:59:21 | d | test.cpp:34:31:34:31 | b |
| test.cpp:74:19:74:21 | dss | test.cpp:26:29:26:29 | b |
| test.cpp:74:19:74:21 | dss | test.cpp:75:25:75:27 | dss |
| test.cpp:74:19:74:21 | dss | test.cpp:76:21:76:23 | dss |
| test.cpp:75:25:75:27 | dss | test.cpp:30:34:30:34 | b |
| test.cpp:75:25:75:27 | dss | test.cpp:76:21:76:23 | dss |
| test.cpp:76:21:76:23 | dss | test.cpp:34:31:34:31 | b |
| test.cpp:86:19:86:20 | d2 | test.cpp:26:29:26:29 | b |
| test.cpp:86:19:86:20 | d2 | test.cpp:87:25:87:26 | d2 |
| test.cpp:86:19:86:20 | d2 | test.cpp:88:21:88:22 | d2 |
| test.cpp:87:25:87:26 | d2 | test.cpp:30:34:30:34 | b |
| test.cpp:87:25:87:26 | d2 | test.cpp:88:21:88:22 | d2 |
| test.cpp:88:21:88:22 | d2 | test.cpp:34:31:34:31 | b |
| test.cpp:26:29:26:29 | b | test.cpp:27:2:27:2 | b | provenance | |
| test.cpp:30:34:30:34 | b | test.cpp:31:2:31:2 | b | provenance | |
| test.cpp:34:31:34:31 | b | test.cpp:35:2:35:2 | b | provenance | |
| test.cpp:57:19:57:19 | d | test.cpp:26:29:26:29 | b | provenance | |
| test.cpp:57:19:57:19 | d | test.cpp:58:25:58:25 | d | provenance | |
| test.cpp:57:19:57:19 | d | test.cpp:59:21:59:21 | d | provenance | |
| test.cpp:58:25:58:25 | d | test.cpp:30:34:30:34 | b | provenance | |
| test.cpp:58:25:58:25 | d | test.cpp:59:21:59:21 | d | provenance | |
| test.cpp:59:21:59:21 | d | test.cpp:34:31:34:31 | b | provenance | |
| test.cpp:74:19:74:21 | dss | test.cpp:26:29:26:29 | b | provenance | |
| test.cpp:74:19:74:21 | dss | test.cpp:75:25:75:27 | dss | provenance | |
| test.cpp:74:19:74:21 | dss | test.cpp:76:21:76:23 | dss | provenance | |
| test.cpp:75:25:75:27 | dss | test.cpp:30:34:30:34 | b | provenance | |
| test.cpp:75:25:75:27 | dss | test.cpp:76:21:76:23 | dss | provenance | |
| test.cpp:76:21:76:23 | dss | test.cpp:34:31:34:31 | b | provenance | |
| test.cpp:86:19:86:20 | d2 | test.cpp:26:29:26:29 | b | provenance | |
| test.cpp:86:19:86:20 | d2 | test.cpp:87:25:87:26 | d2 | provenance | |
| test.cpp:86:19:86:20 | d2 | test.cpp:88:21:88:22 | d2 | provenance | |
| test.cpp:87:25:87:26 | d2 | test.cpp:30:34:30:34 | b | provenance | |
| test.cpp:87:25:87:26 | d2 | test.cpp:88:21:88:22 | d2 | provenance | |
| test.cpp:88:21:88:22 | d2 | test.cpp:34:31:34:31 | b | provenance | |
nodes
| test.cpp:26:29:26:29 | b | semmle.label | b |
| test.cpp:27:2:27:2 | b | semmle.label | b |

View File

@@ -23,7 +23,7 @@ extern char *dcngettext (const char *__domainname, const char *__msgid1,
extern char *any_random_function(const char *);
#define NULL ((void*)0)
#define _(X) any_random_function((X))
#define _(X) gettext(X)
int main(int argc, char **argv) {
if(argc > 1)
@@ -40,10 +40,9 @@ int main(int argc, char **argv) {
printf(gettext("%d arguments\n"), argc-1); // GOOD
printf(any_random_function("%d arguments\n"), argc-1); // BAD
// Even though `_` is mapped to `some_random_function` above,
// the following call should not be flagged.
printf(_(any_random_function("%d arguments\n")),
argc-1); // GOOD
printf(_(any_random_function("%d arguments\n")), argc-1); // BAD
return 0;
}

View File

@@ -1,24 +1,21 @@
| NonConstantFormat.c:30:10:30:16 | access to array | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| NonConstantFormat.c:41:9:41:27 | call to any_random_function | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| NonConstantFormat.c:45:9:45:48 | call to gettext | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| nested.cpp:21:23:21:26 | fmt0 | The format string argument to snprintf should be constant to prevent security issues and other potential errors. |
| nested.cpp:79:32:79:38 | call to get_fmt | The format string argument to diagnostic should be constant to prevent security issues and other potential errors. |
| nested.cpp:87:18:87:20 | fmt | The format string argument to diagnostic should be constant to prevent security issues and other potential errors. |
| test.cpp:51:10:51:21 | call to make_message | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:57:12:57:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:60:12:60:21 | call to const_wash | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:61:12:61:26 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:62:12:62:17 | + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:63:12:63:18 | * ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:64:12:64:18 | & ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:65:12:65:39 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:67:10:67:35 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:70:12:70:20 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:76:12:76:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:82:12:82:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:88:12:88:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:93:12:93:18 | ++ ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:100:12:100:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:110:12:110:24 | new[] | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:115:12:115:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:130:20:130:26 | access to array | The format string argument to sprintf should be constant to prevent security issues and other potential errors. |
| test.cpp:157:12:157:15 | data | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:170:12:170:14 | res | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:195:31:195:33 | str | The format string argument to StringCchPrintfW should be constant to prevent security issues and other potential errors. |
| test.cpp:197:11:197:14 | wstr | The format string argument to wprintf should be constant to prevent security issues and other potential errors. |
| test.cpp:205:12:205:20 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:206:12:206:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:211:12:211:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:217:12:217:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:223:12:223:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:228:12:228:18 | ++ ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:235:12:235:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:242:12:242:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:247:12:247:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |

View File

@@ -18,7 +18,7 @@ extern "C" int snprintf ( char * s, int n, const char * format, ... );
struct A {
void do_print(const char *fmt0) {
char buf[32];
snprintf(buf, 32, fmt0); // GOOD [FALSE POSITIVE]
snprintf(buf, 32, fmt0); // BAD, all paths from unknown const char*, not assuming literal
}
};
@@ -34,12 +34,12 @@ struct C {
void do_some_printing(const char *fmt) {
b.do_printing(fmt);
}
const char *ext_fmt_str(void);
const char *ext_fmt_str(void); // NOTE: not assuming result is literal
};
void foo(void) {
C c;
c.do_some_printing(c.ext_fmt_str()); // BAD [NOT DETECTED]
c.do_some_printing(c.ext_fmt_str());
}
struct some_class {
@@ -76,12 +76,12 @@ void diagnostic(const char *fmt, ...)
}
void bar(void) {
diagnostic (some_instance->get_fmt()); // BAD
diagnostic (some_instance->get_fmt()); // BAD const char* but not assuming literal
}
namespace ns {
class blab {
class blab {
void out1(void) {
char *fmt = (char *)__builtin_alloca(10);
diagnostic(fmt); // BAD

View File

@@ -54,66 +54,66 @@ int main(int argc, char **argv) {
{
char hello[] = "hello, World\n";
hello[0] = 'H';
printf(hello); // BAD
printf(hello); // GOOD
printf(_(hello)); // GOOD
printf(gettext(hello)); // GOOD
printf(const_wash(hello)); // BAD
printf((hello + 1) + 1); // BAD
printf(+hello); // BAD
printf(*&hello); // BAD
printf(&*hello); // BAD
printf((char*)(void*)+(hello+1) + 1); // BAD
printf(const_wash(hello)); // GOOD
printf((hello + 1) + 1); // GOOD
printf(+hello); // GOOD
printf(*&hello); // GOOD
printf(&*hello); // GOOD
printf((char*)(void*)+(hello+1) + 1); // GOOD
}
printf(("Hello, World\n" + 1) + 1); // BAD
printf(("Hello, World\n" + 1) + 1); // GOOD
{
const char *hello = "Hello, World\n";
printf(hello + 1); // BAD
printf(hello + 1); // GOOD
printf(hello); // GOOD
}
{
const char *hello = "Hello, World\n";
hello += 1;
printf(hello); // BAD
printf(hello); // GOOD
}
{
// Same as above block but using "x = x + 1" syntax
const char *hello = "Hello, World\n";
hello = hello + 1;
printf(hello); // BAD
printf(hello); // GOOD
}
{
// Same as above block but using "x++" syntax
const char *hello = "Hello, World\n";
hello++;
printf(hello); // BAD
printf(hello); // GOOD
}
{
// Same as above block but using "++x" as subexpression
const char *hello = "Hello, World\n";
printf(++hello); // BAD
printf(++hello); // GOOD
}
{
// Same as above block but through a pointer
const char *hello = "Hello, World\n";
const char **p = &hello;
(*p)++;
printf(hello); // BAD
printf(hello); // GOOD
}
{
// Same as above block but through a C++ reference
const char *hello = "Hello, World\n";
const char *&p = hello;
p++;
printf(hello); // BAD [NOT DETECTED]
printf(hello); // GOOD
}
if (gettext_debug) {
printf(new char[100]); // BAD
printf(new char[100]); // BAD [FALSE NEGATIVE: uninitialized value not considered a source]
}
{
const char *hello = "Hello, World\n";
const char *const *p = &hello; // harmless reference to const pointer
printf(hello); // GOOD [FALSE POSITIVE]
hello++; // modification comes after use and so does no harm
const char *const *p = &hello;
printf(hello); // GOOD
hello++;
}
printf(argc > 2 ? "More than one\n" : _("Only one\n")); // GOOD
@@ -154,7 +154,7 @@ void print_ith_message() {
void fmt_via_strcpy(char *data) {
strcpy(data, "some string");
printf(data); // BAD
printf(data); // GOOD [FALSE POSITIVE: Due to inaccurate dataflow killers]
}
void fmt_with_assignment() {
@@ -163,3 +163,107 @@ void fmt_with_assignment() {
x = y = "a";
printf(y); // GOOD
}
void fmt_via_strcpy_bad(char *data) {
char res[100];
strcpy(res, data);
printf(res); // BAD
}
int wprintf(const wchar_t *format,...);
typedef wchar_t *STRSAFE_LPWSTR;
typedef const wchar_t *STRSAFE_LPCWSTR;
typedef unsigned int size_t;
void StringCchPrintfW(
STRSAFE_LPWSTR pszDest,
size_t cchDest,
STRSAFE_LPCWSTR pszFormat,
...
);
void wchar_t_test_good(){
wchar_t wstr[100];
StringCchPrintfW(wstr, 100, L"STRING"); // GOOD
wprintf(wstr); // GOOD
}
void wchar_t_test_bad(wchar_t* str){
wchar_t wstr[100];
StringCchPrintfW(wstr, 100, str); // BAD
wprintf(wstr); // BAD
}
char* get_string();
void pointer_arithmetic_test_on_bad_string(){
{
const char *hello = get_string();
printf(hello + 1); // BAD
printf(hello); // BAD
}
{
const char *hello = get_string();
hello += 1;
printf(hello); // BAD
}
{
// Same as above block but using "x = x + 1" syntax
const char *hello = get_string();
hello = hello + 1;
printf(hello); // BAD
}
{
// Same as above block but using "x++" syntax
const char *hello = get_string();
hello++;
printf(hello); // BAD
}
{
// Same as above block but using "++x" as subexpression
const char *hello = get_string();
printf(++hello); // BAD
}
{
// Same as above block but through a pointer
const char *hello = get_string();
const char **p = &hello;
(*p)++;
printf(hello); // BAD
}
{
// Same as above block but through a C++ reference
const char *hello = get_string();
const char *&p = hello;
p++;
printf(hello); // BAD
}
{
const char *hello = get_string();
const char *const *p = &hello;
printf(hello); // BAD
}
}
struct struct1 {
char *non_const;
const char* const_member = "TEST";
char * const_member2 = "TEST";
struct struct2{
char *nested_non_const;
const char* nested_const_member = "TEST";
char * nested_const_member2 = "TEST";
} nested;
};
int test_uncalled_func_with_struct_param(struct struct1 *s) {
printf(s->non_const); // BAD [FALSE NEGATIVE]
printf(s->const_member); // GOOD
printf(s->const_member2); // GOOD
printf(s->nested.nested_non_const); // BAD [FALSE NEGATIVE]
printf(s->nested.nested_const_member); // GOOD
printf(s->nested.nested_const_member2); // GOOD
}

View File

@@ -1,5 +1,5 @@
edges
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | *data |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | *data | provenance | |
nodes
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | semmle.label | fgets output argument |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | *data | semmle.label | *data |

View File

@@ -1,9 +1,9 @@
edges
| test.c:8:27:8:30 | **argv | test.c:17:11:17:18 | *fileName |
| test.c:8:27:8:30 | **argv | test.c:32:11:32:18 | *fileName |
| test.c:8:27:8:30 | **argv | test.c:57:10:57:16 | *access to array |
| test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | *fileName |
| test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | *fileName |
| test.c:8:27:8:30 | **argv | test.c:17:11:17:18 | *fileName | provenance | |
| test.c:8:27:8:30 | **argv | test.c:32:11:32:18 | *fileName | provenance | |
| test.c:8:27:8:30 | **argv | test.c:57:10:57:16 | *access to array | provenance | |
| test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | *fileName | provenance | |
| test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | *fileName | provenance | |
nodes
| test.c:8:27:8:30 | **argv | semmle.label | **argv |
| test.c:17:11:17:18 | *fileName | semmle.label | *fileName |

View File

@@ -1,9 +1,9 @@
edges
| tests.cpp:26:15:26:23 | **badSource | tests.cpp:51:12:51:20 | *call to badSource |
| tests.cpp:33:34:33:39 | *call to getenv | tests.cpp:38:39:38:49 | *environment |
| tests.cpp:38:25:38:36 | strncat output argument | tests.cpp:26:15:26:23 | **badSource |
| tests.cpp:38:39:38:49 | *environment | tests.cpp:38:25:38:36 | strncat output argument |
| tests.cpp:51:12:51:20 | *call to badSource | tests.cpp:53:16:53:19 | *data |
| tests.cpp:26:15:26:23 | **badSource | tests.cpp:51:12:51:20 | *call to badSource | provenance | |
| tests.cpp:33:34:33:39 | *call to getenv | tests.cpp:38:39:38:49 | *environment | provenance | |
| tests.cpp:38:25:38:36 | strncat output argument | tests.cpp:26:15:26:23 | **badSource | provenance | |
| tests.cpp:38:39:38:49 | *environment | tests.cpp:38:25:38:36 | strncat output argument | provenance | |
| tests.cpp:51:12:51:20 | *call to badSource | tests.cpp:53:16:53:19 | *data | provenance | |
nodes
| tests.cpp:26:15:26:23 | **badSource | semmle.label | **badSource |
| tests.cpp:33:34:33:39 | *call to getenv | semmle.label | *call to getenv |

View File

@@ -1,70 +1,70 @@
edges
| test.cpp:15:27:15:30 | **argv | test.cpp:22:45:22:52 | *userName |
| test.cpp:22:13:22:20 | sprintf output argument | test.cpp:23:12:23:19 | *command1 |
| test.cpp:22:45:22:52 | *userName | test.cpp:22:13:22:20 | sprintf output argument |
| test.cpp:47:21:47:26 | *call to getenv | test.cpp:50:35:50:43 | *envCflags |
| test.cpp:50:11:50:17 | sprintf output argument | test.cpp:51:10:51:16 | *command |
| test.cpp:50:35:50:43 | *envCflags | test.cpp:50:11:50:17 | sprintf output argument |
| test.cpp:62:9:62:16 | fread output argument | test.cpp:64:20:64:27 | *filename |
| test.cpp:64:11:64:17 | strncat output argument | test.cpp:65:10:65:16 | *command |
| test.cpp:64:20:64:27 | *filename | test.cpp:64:11:64:17 | strncat output argument |
| test.cpp:82:9:82:16 | fread output argument | test.cpp:84:20:84:27 | *filename |
| test.cpp:84:11:84:17 | strncat output argument | test.cpp:85:32:85:38 | *command |
| test.cpp:84:20:84:27 | *filename | test.cpp:84:11:84:17 | strncat output argument |
| test.cpp:91:9:91:16 | fread output argument | test.cpp:93:17:93:24 | *filename |
| test.cpp:93:11:93:14 | strncat output argument | test.cpp:94:45:94:48 | *path |
| test.cpp:93:17:93:24 | *filename | test.cpp:93:11:93:14 | strncat output argument |
| test.cpp:106:20:106:38 | *call to getenv | test.cpp:107:33:107:36 | *path |
| test.cpp:107:31:107:31 | call to operator+ | test.cpp:108:18:108:22 | *call to c_str |
| test.cpp:107:33:107:36 | *path | test.cpp:107:31:107:31 | call to operator+ |
| test.cpp:113:20:113:38 | *call to getenv | test.cpp:114:19:114:22 | *path |
| test.cpp:114:10:114:23 | call to operator+ | test.cpp:114:25:114:29 | *call to c_str |
| test.cpp:114:10:114:23 | call to operator+ | test.cpp:114:25:114:29 | *call to c_str |
| test.cpp:114:17:114:17 | call to operator+ | test.cpp:114:10:114:23 | call to operator+ |
| test.cpp:114:19:114:22 | *path | test.cpp:114:10:114:23 | call to operator+ |
| test.cpp:114:19:114:22 | *path | test.cpp:114:17:114:17 | call to operator+ |
| test.cpp:119:20:119:38 | *call to getenv | test.cpp:120:19:120:22 | *path |
| test.cpp:120:17:120:17 | call to operator+ | test.cpp:120:10:120:30 | *call to data |
| test.cpp:120:19:120:22 | *path | test.cpp:120:17:120:17 | call to operator+ |
| test.cpp:140:9:140:11 | fread output argument | test.cpp:142:31:142:33 | *str |
| test.cpp:142:11:142:17 | sprintf output argument | test.cpp:143:10:143:16 | *command |
| test.cpp:142:31:142:33 | *str | test.cpp:142:11:142:17 | sprintf output argument |
| test.cpp:174:9:174:16 | fread output argument | test.cpp:177:20:177:27 | *filename |
| test.cpp:174:9:174:16 | fread output argument | test.cpp:180:22:180:29 | *filename |
| test.cpp:177:13:177:17 | strncat output argument | test.cpp:178:22:178:26 | *flags |
| test.cpp:177:13:177:17 | strncat output argument | test.cpp:178:22:178:26 | *flags |
| test.cpp:177:20:177:27 | *filename | test.cpp:177:13:177:17 | strncat output argument |
| test.cpp:177:20:177:27 | *filename | test.cpp:177:13:177:17 | strncat output argument |
| test.cpp:178:13:178:19 | strncat output argument | test.cpp:183:32:183:38 | *command |
| test.cpp:178:13:178:19 | strncat output argument | test.cpp:183:32:183:38 | *command |
| test.cpp:178:22:178:26 | *flags | test.cpp:178:13:178:19 | strncat output argument |
| test.cpp:178:22:178:26 | *flags | test.cpp:178:13:178:19 | strncat output argument |
| test.cpp:180:13:180:19 | strncat output argument | test.cpp:183:32:183:38 | *command |
| test.cpp:180:22:180:29 | *filename | test.cpp:180:13:180:19 | strncat output argument |
| test.cpp:186:47:186:54 | *filename | test.cpp:187:18:187:25 | *filename |
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | *flags |
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | *flags |
| test.cpp:187:18:187:25 | *filename | test.cpp:187:11:187:15 | strncat output argument |
| test.cpp:187:18:187:25 | *filename | test.cpp:187:11:187:15 | strncat output argument |
| test.cpp:188:20:188:24 | *flags | test.cpp:188:11:188:17 | strncat output argument |
| test.cpp:188:20:188:24 | *flags | test.cpp:188:11:188:17 | strncat output argument |
| 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 | *command |
| test.cpp:196:10:196:16 | concat output argument | test.cpp:198:32:198:38 | *command |
| 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:10:196:16 | concat output argument |
| test.cpp:218:9:218:16 | fread output argument | test.cpp:220:19:220:26 | *filename |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:220:10:220:16 | strncat output argument |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:220:10:220:16 | strncat output argument |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:220:10:220:16 | strncat output argument |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command |
| test.cpp:220:19:220:26 | *filename | test.cpp:220:10:220:16 | strncat output argument |
| test.cpp:220:19:220:26 | *filename | test.cpp:220:10:220:16 | strncat output argument |
| test.cpp:220:19:220:26 | *filename | test.cpp:220:19:220:26 | *filename |
| test.cpp:15:27:15:30 | **argv | test.cpp:22:45:22:52 | *userName | provenance | |
| test.cpp:22:13:22:20 | sprintf output argument | test.cpp:23:12:23:19 | *command1 | provenance | |
| test.cpp:22:45:22:52 | *userName | test.cpp:22:13:22:20 | sprintf output argument | provenance | |
| test.cpp:47:21:47:26 | *call to getenv | test.cpp:50:35:50:43 | *envCflags | provenance | |
| test.cpp:50:11:50:17 | sprintf output argument | test.cpp:51:10:51:16 | *command | provenance | |
| test.cpp:50:35:50:43 | *envCflags | test.cpp:50:11:50:17 | sprintf output argument | provenance | |
| test.cpp:62:9:62:16 | fread output argument | test.cpp:64:20:64:27 | *filename | provenance | |
| test.cpp:64:11:64:17 | strncat output argument | test.cpp:65:10:65:16 | *command | provenance | |
| test.cpp:64:20:64:27 | *filename | test.cpp:64:11:64:17 | strncat output argument | provenance | |
| test.cpp:82:9:82:16 | fread output argument | test.cpp:84:20:84:27 | *filename | provenance | |
| test.cpp:84:11:84:17 | strncat output argument | test.cpp:85:32:85:38 | *command | provenance | |
| test.cpp:84:20:84:27 | *filename | test.cpp:84:11:84:17 | strncat output argument | provenance | |
| test.cpp:91:9:91:16 | fread output argument | test.cpp:93:17:93:24 | *filename | provenance | |
| test.cpp:93:11:93:14 | strncat output argument | test.cpp:94:45:94:48 | *path | provenance | |
| test.cpp:93:17:93:24 | *filename | test.cpp:93:11:93:14 | strncat output argument | provenance | |
| test.cpp:106:20:106:38 | *call to getenv | test.cpp:107:33:107:36 | *path | provenance | |
| test.cpp:107:31:107:31 | call to operator+ | test.cpp:108:18:108:22 | *call to c_str | provenance | |
| test.cpp:107:33:107:36 | *path | test.cpp:107:31:107:31 | call to operator+ | provenance | |
| test.cpp:113:20:113:38 | *call to getenv | test.cpp:114:19:114:22 | *path | provenance | |
| test.cpp:114:10:114:23 | call to operator+ | test.cpp:114:25:114:29 | *call to c_str | provenance | |
| test.cpp:114:10:114:23 | call to operator+ | test.cpp:114:25:114:29 | *call to c_str | provenance | |
| test.cpp:114:17:114:17 | call to operator+ | test.cpp:114:10:114:23 | call to operator+ | provenance | |
| test.cpp:114:19:114:22 | *path | test.cpp:114:10:114:23 | call to operator+ | provenance | |
| test.cpp:114:19:114:22 | *path | test.cpp:114:17:114:17 | call to operator+ | provenance | |
| test.cpp:119:20:119:38 | *call to getenv | test.cpp:120:19:120:22 | *path | provenance | |
| test.cpp:120:17:120:17 | call to operator+ | test.cpp:120:10:120:30 | *call to data | provenance | |
| test.cpp:120:19:120:22 | *path | test.cpp:120:17:120:17 | call to operator+ | provenance | |
| test.cpp:140:9:140:11 | fread output argument | test.cpp:142:31:142:33 | *str | provenance | |
| test.cpp:142:11:142:17 | sprintf output argument | test.cpp:143:10:143:16 | *command | provenance | |
| test.cpp:142:31:142:33 | *str | test.cpp:142:11:142:17 | sprintf output argument | provenance | |
| test.cpp:174:9:174:16 | fread output argument | test.cpp:177:20:177:27 | *filename | provenance | |
| test.cpp:174:9:174:16 | fread output argument | test.cpp:180:22:180:29 | *filename | provenance | |
| test.cpp:177:13:177:17 | strncat output argument | test.cpp:178:22:178:26 | *flags | provenance | |
| test.cpp:177:13:177:17 | strncat output argument | test.cpp:178:22:178:26 | *flags | provenance | |
| test.cpp:177:20:177:27 | *filename | test.cpp:177:13:177:17 | strncat output argument | provenance | |
| test.cpp:177:20:177:27 | *filename | test.cpp:177:13:177:17 | strncat output argument | provenance | |
| test.cpp:178:13:178:19 | strncat output argument | test.cpp:183:32:183:38 | *command | provenance | |
| test.cpp:178:13:178:19 | strncat output argument | test.cpp:183:32:183:38 | *command | provenance | |
| test.cpp:178:22:178:26 | *flags | test.cpp:178:13:178:19 | strncat output argument | provenance | |
| test.cpp:178:22:178:26 | *flags | test.cpp:178:13:178:19 | strncat output argument | provenance | |
| test.cpp:180:13:180:19 | strncat output argument | test.cpp:183:32:183:38 | *command | provenance | |
| test.cpp:180:22:180:29 | *filename | test.cpp:180:13:180:19 | strncat output argument | provenance | |
| test.cpp:186:47:186:54 | *filename | test.cpp:187:18:187:25 | *filename | provenance | |
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | *flags | provenance | |
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | *flags | provenance | |
| test.cpp:187:18:187:25 | *filename | test.cpp:187:11:187:15 | strncat output argument | provenance | |
| test.cpp:187:18:187:25 | *filename | test.cpp:187:11:187:15 | strncat output argument | provenance | |
| test.cpp:188:20:188:24 | *flags | test.cpp:188:11:188:17 | strncat output argument | provenance | |
| test.cpp:188:20:188:24 | *flags | test.cpp:188:11:188:17 | strncat output argument | provenance | |
| test.cpp:194:9:194:16 | fread output argument | test.cpp:196:26:196:33 | *filename | provenance | |
| test.cpp:196:10:196:16 | concat output argument | test.cpp:198:32:198:38 | *command | provenance | |
| test.cpp:196:10:196:16 | concat output argument | test.cpp:198:32:198:38 | *command | provenance | |
| test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | provenance | |
| test.cpp:196:26:196:33 | *filename | test.cpp:196:10:196:16 | concat output argument | provenance | |
| test.cpp:196:26:196:33 | *filename | test.cpp:196:10:196:16 | concat output argument | provenance | |
| test.cpp:218:9:218:16 | fread output argument | test.cpp:220:19:220:26 | *filename | provenance | |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:220:10:220:16 | strncat output argument | provenance | |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:220:10:220:16 | strncat output argument | provenance | |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:220:10:220:16 | strncat output argument | provenance | |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command | provenance | |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command | provenance | |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command | provenance | |
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command | provenance | |
| test.cpp:220:19:220:26 | *filename | test.cpp:220:10:220:16 | strncat output argument | provenance | |
| test.cpp:220:19:220:26 | *filename | test.cpp:220:10:220:16 | strncat output argument | provenance | |
| test.cpp:220:19:220:26 | *filename | test.cpp:220:19:220:26 | *filename | provenance | |
nodes
| test.cpp:15:27:15:30 | **argv | semmle.label | **argv |
| test.cpp:22:13:22:20 | sprintf output argument | semmle.label | sprintf output argument |

View File

@@ -1,13 +1,13 @@
edges
| search.c:14:24:14:28 | *query | search.c:17:8:17:12 | *query |
| search.c:22:24:22:28 | *query | search.c:23:39:23:43 | *query |
| search.c:55:24:55:28 | *query | search.c:62:8:62:17 | *query_text |
| search.c:67:21:67:26 | *call to getenv | search.c:71:17:71:25 | *raw_query |
| search.c:67:21:67:26 | *call to getenv | search.c:73:17:73:25 | *raw_query |
| search.c:67:21:67:26 | *call to getenv | search.c:77:17:77:25 | *raw_query |
| search.c:71:17:71:25 | *raw_query | search.c:14:24:14:28 | *query |
| search.c:73:17:73:25 | *raw_query | search.c:22:24:22:28 | *query |
| search.c:77:17:77:25 | *raw_query | search.c:55:24:55:28 | *query |
| search.c:14:24:14:28 | *query | search.c:17:8:17:12 | *query | provenance | |
| search.c:22:24:22:28 | *query | search.c:23:39:23:43 | *query | provenance | |
| search.c:55:24:55:28 | *query | search.c:62:8:62:17 | *query_text | provenance | |
| search.c:67:21:67:26 | *call to getenv | search.c:71:17:71:25 | *raw_query | provenance | |
| search.c:67:21:67:26 | *call to getenv | search.c:73:17:73:25 | *raw_query | provenance | |
| search.c:67:21:67:26 | *call to getenv | search.c:77:17:77:25 | *raw_query | provenance | |
| search.c:71:17:71:25 | *raw_query | search.c:14:24:14:28 | *query | provenance | |
| search.c:73:17:73:25 | *raw_query | search.c:22:24:22:28 | *query | provenance | |
| search.c:77:17:77:25 | *raw_query | search.c:55:24:55:28 | *query | provenance | |
nodes
| search.c:14:24:14:28 | *query | semmle.label | *query |
| search.c:17:8:17:12 | *query | semmle.label | *query |

View File

@@ -1,12 +1,12 @@
edges
| test.c:14:27:14:30 | **argv | test.c:21:18:21:23 | *query1 |
| test.c:14:27:14:30 | **argv | test.c:35:16:35:23 | *userName |
| test.c:35:16:35:23 | *userName | test.c:40:25:40:32 | *username |
| test.c:38:7:38:20 | **globalUsername | test.c:51:18:51:23 | *query1 |
| test.c:40:25:40:32 | *username | test.c:38:7:38:20 | **globalUsername |
| test.c:75:8:75:16 | gets output argument | test.c:76:17:76:25 | *userInput |
| test.c:75:8:75:16 | gets output argument | test.c:77:20:77:28 | *userInput |
| test.cpp:39:27:39:30 | **argv | test.cpp:43:27:43:33 | *access to array |
| test.c:14:27:14:30 | **argv | test.c:21:18:21:23 | *query1 | provenance | |
| test.c:14:27:14:30 | **argv | test.c:35:16:35:23 | *userName | provenance | |
| test.c:35:16:35:23 | *userName | test.c:40:25:40:32 | *username | provenance | |
| test.c:38:7:38:20 | **globalUsername | test.c:51:18:51:23 | *query1 | provenance | |
| test.c:40:25:40:32 | *username | test.c:38:7:38:20 | **globalUsername | provenance | |
| test.c:75:8:75:16 | gets output argument | test.c:76:17:76:25 | *userInput | provenance | |
| test.c:75:8:75:16 | gets output argument | test.c:77:20:77:28 | *userInput | provenance | |
| test.cpp:39:27:39:30 | **argv | test.cpp:43:27:43:33 | *access to array | provenance | |
nodes
| test.c:14:27:14:30 | **argv | semmle.label | **argv |
| test.c:21:18:21:23 | *query1 | semmle.label | *query1 |

View File

@@ -1,7 +1,7 @@
edges
| test.cpp:37:73:37:76 | *data | test.cpp:43:32:43:35 | *data |
| test.cpp:64:30:64:35 | *call to getenv | test.cpp:73:24:73:27 | *data |
| test.cpp:73:24:73:27 | *data | test.cpp:37:73:37:76 | *data |
| test.cpp:37:73:37:76 | *data | test.cpp:43:32:43:35 | *data | provenance | |
| test.cpp:64:30:64:35 | *call to getenv | test.cpp:73:24:73:27 | *data | provenance | |
| test.cpp:73:24:73:27 | *data | test.cpp:37:73:37:76 | *data | provenance | |
nodes
| test.cpp:37:73:37:76 | *data | semmle.label | *data |
| test.cpp:43:32:43:35 | *data | semmle.label | *data |

View File

@@ -1,16 +1,16 @@
edges
| test.cpp:24:30:24:36 | *command | test.cpp:26:10:26:16 | *command |
| test.cpp:29:30:29:36 | *command | test.cpp:31:10:31:16 | *command |
| test.cpp:42:18:42:34 | *call to getenv | test.cpp:24:30:24:36 | *command |
| test.cpp:43:18:43:34 | *call to getenv | test.cpp:29:30:29:36 | *command |
| 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:64:10:64:16 | *dataref |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | *data2 |
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | *buffer |
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | *buffer |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | *buffer |
| test.cpp:113:8:113:12 | *call to fgets | test.cpp:114:9:114:11 | *ptr |
| test.cpp:24:30:24:36 | *command | test.cpp:26:10:26:16 | *command | provenance | |
| test.cpp:29:30:29:36 | *command | test.cpp:31:10:31:16 | *command | provenance | |
| test.cpp:42:18:42:34 | *call to getenv | test.cpp:24:30:24:36 | *command | provenance | |
| test.cpp:43:18:43:34 | *call to getenv | test.cpp:29:30:29:36 | *command | provenance | |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | *buffer | provenance | |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | *data | provenance | |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | *dataref | provenance | |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | *data2 | provenance | |
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | *buffer | provenance | |
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | *buffer | provenance | |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | *buffer | provenance | |
| test.cpp:113:8:113:12 | *call to fgets | test.cpp:114:9:114:11 | *ptr | provenance | |
nodes
| test.cpp:24:30:24:36 | *command | semmle.label | *command |
| test.cpp:26:10:26:16 | *command | semmle.label | *command |

View File

@@ -1,62 +1,62 @@
edges
| test.cpp:16:11:16:21 | **mk_string_t [string] | test.cpp:39:21:39:31 | *call to mk_string_t [string] |
| test.cpp:18:5:18:7 | *str [post update] [string] | test.cpp:19:5:19:7 | *str [string] |
| test.cpp:18:5:18:30 | ... = ... | test.cpp:18:5:18:7 | *str [post update] [string] |
| test.cpp:18:19:18:24 | call to malloc | test.cpp:18:5:18:30 | ... = ... |
| test.cpp:19:5:19:7 | *str [string] | test.cpp:16:11:16:21 | **mk_string_t [string] |
| test.cpp:39:21:39:31 | *call to mk_string_t [string] | test.cpp:42:13:42:15 | *str [string] |
| test.cpp:39:21:39:31 | *call to mk_string_t [string] | test.cpp:72:17:72:19 | *str [string] |
| test.cpp:39:21:39:31 | *call to mk_string_t [string] | test.cpp:80:17:80:19 | *str [string] |
| test.cpp:42:13:42:15 | *str [string] | test.cpp:42:18:42:23 | string |
| test.cpp:72:17:72:19 | *str [string] | test.cpp:72:22:72:27 | string |
| test.cpp:80:17:80:19 | *str [string] | test.cpp:80:22:80:27 | string |
| test.cpp:88:11:88:30 | **mk_string_t_plus_one [string] | test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] |
| test.cpp:90:5:90:7 | *str [post update] [string] | test.cpp:91:5:91:7 | *str [string] |
| test.cpp:90:5:90:34 | ... = ... | test.cpp:90:5:90:7 | *str [post update] [string] |
| test.cpp:90:19:90:24 | call to malloc | test.cpp:90:5:90:34 | ... = ... |
| test.cpp:91:5:91:7 | *str [string] | test.cpp:88:11:88:30 | **mk_string_t_plus_one [string] |
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:99:13:99:15 | *str [string] |
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:129:17:129:19 | *str [string] |
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:137:17:137:19 | *str [string] |
| test.cpp:99:13:99:15 | *str [string] | test.cpp:99:18:99:23 | string |
| test.cpp:129:17:129:19 | *str [string] | test.cpp:129:22:129:27 | string |
| test.cpp:137:17:137:19 | *str [string] | test.cpp:137:22:137:27 | string |
| test.cpp:147:5:147:7 | *str [post update] [string] | test.cpp:148:5:148:7 | *str [string] |
| test.cpp:147:5:147:34 | ... = ... | test.cpp:147:5:147:7 | *str [post update] [string] |
| test.cpp:147:19:147:24 | call to malloc | test.cpp:147:5:147:34 | ... = ... |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:152:13:152:15 | *str [string] |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:154:13:154:15 | *str [string] |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:156:13:156:15 | *str [string] |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:175:17:175:19 | *str [string] |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:187:17:187:19 | *str [string] |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:195:17:195:19 | *str [string] |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:199:17:199:19 | *str [string] |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:203:17:203:19 | *str [string] |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:207:17:207:19 | *str [string] |
| test.cpp:152:13:152:15 | *str [string] | test.cpp:152:18:152:23 | string |
| test.cpp:154:13:154:15 | *str [string] | test.cpp:154:18:154:23 | string |
| test.cpp:156:13:156:15 | *str [string] | test.cpp:156:18:156:23 | string |
| test.cpp:175:17:175:19 | *str [string] | test.cpp:175:22:175:27 | string |
| test.cpp:187:17:187:19 | *str [string] | test.cpp:187:22:187:27 | string |
| test.cpp:195:17:195:19 | *str [string] | test.cpp:195:22:195:27 | string |
| test.cpp:199:17:199:19 | *str [string] | test.cpp:199:22:199:27 | string |
| test.cpp:203:17:203:19 | *str [string] | test.cpp:203:22:203:27 | string |
| test.cpp:207:17:207:19 | *str [string] | test.cpp:207:22:207:27 | string |
| test.cpp:214:24:214:24 | p | test.cpp:216:10:216:10 | p |
| test.cpp:220:27:220:54 | call to malloc | test.cpp:222:15:222:20 | buffer |
| test.cpp:222:15:222:20 | buffer | test.cpp:214:24:214:24 | p |
| test.cpp:228:27:228:54 | call to malloc | test.cpp:232:10:232:15 | buffer |
| test.cpp:235:40:235:45 | buffer | test.cpp:236:5:236:26 | ... = ... |
| test.cpp:236:5:236:26 | ... = ... | test.cpp:236:5:236:9 | *p_str [post update] [string] |
| test.cpp:241:20:241:38 | call to malloc | test.cpp:242:22:242:27 | buffer |
| test.cpp:242:16:242:19 | set_string output argument [string] | test.cpp:243:12:243:14 | *str [string] |
| test.cpp:242:22:242:27 | buffer | test.cpp:235:40:235:45 | buffer |
| test.cpp:242:22:242:27 | buffer | test.cpp:242:16:242:19 | set_string output argument [string] |
| test.cpp:243:12:243:14 | *str [string] | test.cpp:243:12:243:21 | string |
| test.cpp:249:14:249:33 | call to my_alloc | test.cpp:250:12:250:12 | p |
| test.cpp:256:9:256:25 | call to malloc | test.cpp:257:12:257:12 | p |
| test.cpp:262:15:262:30 | call to malloc | test.cpp:266:12:266:12 | p |
| test.cpp:264:13:264:30 | call to malloc | test.cpp:266:12:266:12 | p |
| test.cpp:16:11:16:21 | **mk_string_t [string] | test.cpp:39:21:39:31 | *call to mk_string_t [string] | provenance | |
| test.cpp:18:5:18:7 | *str [post update] [string] | test.cpp:19:5:19:7 | *str [string] | provenance | |
| test.cpp:18:5:18:30 | ... = ... | test.cpp:18:5:18:7 | *str [post update] [string] | provenance | |
| test.cpp:18:19:18:24 | call to malloc | test.cpp:18:5:18:30 | ... = ... | provenance | |
| test.cpp:19:5:19:7 | *str [string] | test.cpp:16:11:16:21 | **mk_string_t [string] | provenance | |
| test.cpp:39:21:39:31 | *call to mk_string_t [string] | test.cpp:42:13:42:15 | *str [string] | provenance | |
| test.cpp:39:21:39:31 | *call to mk_string_t [string] | test.cpp:72:17:72:19 | *str [string] | provenance | |
| test.cpp:39:21:39:31 | *call to mk_string_t [string] | test.cpp:80:17:80:19 | *str [string] | provenance | |
| test.cpp:42:13:42:15 | *str [string] | test.cpp:42:18:42:23 | string | provenance | |
| test.cpp:72:17:72:19 | *str [string] | test.cpp:72:22:72:27 | string | provenance | |
| test.cpp:80:17:80:19 | *str [string] | test.cpp:80:22:80:27 | string | provenance | |
| test.cpp:88:11:88:30 | **mk_string_t_plus_one [string] | test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | provenance | |
| test.cpp:90:5:90:7 | *str [post update] [string] | test.cpp:91:5:91:7 | *str [string] | provenance | |
| test.cpp:90:5:90:34 | ... = ... | test.cpp:90:5:90:7 | *str [post update] [string] | provenance | |
| test.cpp:90:19:90:24 | call to malloc | test.cpp:90:5:90:34 | ... = ... | provenance | |
| test.cpp:91:5:91:7 | *str [string] | test.cpp:88:11:88:30 | **mk_string_t_plus_one [string] | provenance | |
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:99:13:99:15 | *str [string] | provenance | |
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:129:17:129:19 | *str [string] | provenance | |
| test.cpp:96:21:96:40 | *call to mk_string_t_plus_one [string] | test.cpp:137:17:137:19 | *str [string] | provenance | |
| test.cpp:99:13:99:15 | *str [string] | test.cpp:99:18:99:23 | string | provenance | |
| test.cpp:129:17:129:19 | *str [string] | test.cpp:129:22:129:27 | string | provenance | |
| test.cpp:137:17:137:19 | *str [string] | test.cpp:137:22:137:27 | string | provenance | |
| test.cpp:147:5:147:7 | *str [post update] [string] | test.cpp:148:5:148:7 | *str [string] | provenance | |
| test.cpp:147:5:147:34 | ... = ... | test.cpp:147:5:147:7 | *str [post update] [string] | provenance | |
| test.cpp:147:19:147:24 | call to malloc | test.cpp:147:5:147:34 | ... = ... | provenance | |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:152:13:152:15 | *str [string] | provenance | |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:154:13:154:15 | *str [string] | provenance | |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:156:13:156:15 | *str [string] | provenance | |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:175:17:175:19 | *str [string] | provenance | |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:187:17:187:19 | *str [string] | provenance | |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:195:17:195:19 | *str [string] | provenance | |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:199:17:199:19 | *str [string] | provenance | |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:203:17:203:19 | *str [string] | provenance | |
| test.cpp:148:5:148:7 | *str [string] | test.cpp:207:17:207:19 | *str [string] | provenance | |
| test.cpp:152:13:152:15 | *str [string] | test.cpp:152:18:152:23 | string | provenance | |
| test.cpp:154:13:154:15 | *str [string] | test.cpp:154:18:154:23 | string | provenance | |
| test.cpp:156:13:156:15 | *str [string] | test.cpp:156:18:156:23 | string | provenance | |
| test.cpp:175:17:175:19 | *str [string] | test.cpp:175:22:175:27 | string | provenance | |
| test.cpp:187:17:187:19 | *str [string] | test.cpp:187:22:187:27 | string | provenance | |
| test.cpp:195:17:195:19 | *str [string] | test.cpp:195:22:195:27 | string | provenance | |
| test.cpp:199:17:199:19 | *str [string] | test.cpp:199:22:199:27 | string | provenance | |
| test.cpp:203:17:203:19 | *str [string] | test.cpp:203:22:203:27 | string | provenance | |
| test.cpp:207:17:207:19 | *str [string] | test.cpp:207:22:207:27 | string | provenance | |
| test.cpp:214:24:214:24 | p | test.cpp:216:10:216:10 | p | provenance | |
| test.cpp:220:27:220:54 | call to malloc | test.cpp:222:15:222:20 | buffer | provenance | |
| test.cpp:222:15:222:20 | buffer | test.cpp:214:24:214:24 | p | provenance | |
| test.cpp:228:27:228:54 | call to malloc | test.cpp:232:10:232:15 | buffer | provenance | |
| test.cpp:235:40:235:45 | buffer | test.cpp:236:5:236:26 | ... = ... | provenance | |
| test.cpp:236:5:236:26 | ... = ... | test.cpp:236:5:236:9 | *p_str [post update] [string] | provenance | |
| test.cpp:241:20:241:38 | call to malloc | test.cpp:242:22:242:27 | buffer | provenance | |
| test.cpp:242:16:242:19 | set_string output argument [string] | test.cpp:243:12:243:14 | *str [string] | provenance | |
| test.cpp:242:22:242:27 | buffer | test.cpp:235:40:235:45 | buffer | provenance | |
| test.cpp:242:22:242:27 | buffer | test.cpp:242:16:242:19 | set_string output argument [string] | provenance | |
| test.cpp:243:12:243:14 | *str [string] | test.cpp:243:12:243:21 | string | provenance | |
| test.cpp:249:14:249:33 | call to my_alloc | test.cpp:250:12:250:12 | p | provenance | |
| test.cpp:256:9:256:25 | call to malloc | test.cpp:257:12:257:12 | p | provenance | |
| test.cpp:262:15:262:30 | call to malloc | test.cpp:266:12:266:12 | p | provenance | |
| test.cpp:264:13:264:30 | call to malloc | test.cpp:266:12:266:12 | p | provenance | |
nodes
| test.cpp:16:11:16:21 | **mk_string_t [string] | semmle.label | **mk_string_t [string] |
| test.cpp:18:5:18:7 | *str [post update] [string] | semmle.label | *str [post update] [string] |

View File

@@ -1,14 +1,14 @@
edges
| main.cpp:6:27:6:30 | **argv | main.cpp:7:33:7:36 | **argv |
| main.cpp:7:33:7:36 | **argv | overflowdestination.cpp:23:45:23:48 | **argv |
| overflowdestination.cpp:23:45:23:48 | **argv | 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:53:15:53:17 | *src |
| overflowdestination.cpp:57:52:57:54 | *src | overflowdestination.cpp:64:16:64:19 | *src2 |
| 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 | *src |
| overflowdestination.cpp:75:30:75:32 | *src | overflowdestination.cpp:50:52:50:54 | *src |
| overflowdestination.cpp:76:30:76:32 | *src | overflowdestination.cpp:57:52:57:54 | *src |
| main.cpp:6:27:6:30 | **argv | main.cpp:7:33:7:36 | **argv | provenance | |
| main.cpp:7:33:7:36 | **argv | overflowdestination.cpp:23:45:23:48 | **argv | provenance | |
| overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:30:17:30:20 | *arg1 | provenance | |
| overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | *src | provenance | |
| overflowdestination.cpp:50:52:50:54 | *src | overflowdestination.cpp:53:15:53:17 | *src | provenance | |
| overflowdestination.cpp:57:52:57:54 | *src | overflowdestination.cpp:64:16:64:19 | *src2 | provenance | |
| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:75:30:75:32 | *src | provenance | |
| overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:76:30:76:32 | *src | provenance | |
| overflowdestination.cpp:75:30:75:32 | *src | overflowdestination.cpp:50:52:50:54 | *src | provenance | |
| overflowdestination.cpp:76:30:76:32 | *src | overflowdestination.cpp:57:52:57:54 | *src | provenance | |
nodes
| main.cpp:6:27:6:30 | **argv | semmle.label | **argv |
| main.cpp:7:33:7:36 | **argv | semmle.label | **argv |

View File

@@ -1,17 +1,17 @@
edges
| main.cpp:6:27:6:30 | **argv | main.cpp:10:20:10:23 | **argv |
| main.cpp:10:20:10:23 | **argv | tests.cpp:657:32:657:35 | **argv |
| tests.cpp:613:19:613:24 | *source | tests.cpp:615:17:615:22 | *source |
| tests.cpp:622:19:622:24 | *source | tests.cpp:625:2:625:16 | *... = ... |
| tests.cpp:625:2:625:2 | *s [post update] [*home] | tests.cpp:628:14:628:14 | *s [*home] |
| tests.cpp:625:2:625:16 | *... = ... | tests.cpp:625:2:625:2 | *s [post update] [*home] |
| tests.cpp:628:14:628:14 | *s [*home] | tests.cpp:628:14:628:19 | *home |
| tests.cpp:628:14:628:14 | *s [*home] | tests.cpp:628:16:628:19 | *home |
| tests.cpp:628:16:628:19 | *home | tests.cpp:628:14:628:19 | *home |
| tests.cpp:657:32:657:35 | **argv | tests.cpp:682:9:682:15 | *access to array |
| tests.cpp:657:32:657:35 | **argv | tests.cpp:683:9:683:15 | *access to array |
| tests.cpp:682:9:682:15 | *access to array | tests.cpp:613:19:613:24 | *source |
| tests.cpp:683:9:683:15 | *access to array | tests.cpp:622:19:622:24 | *source |
| main.cpp:6:27:6:30 | **argv | main.cpp:10:20:10:23 | **argv | provenance | |
| main.cpp:10:20:10:23 | **argv | tests.cpp:657:32:657:35 | **argv | provenance | |
| tests.cpp:613:19:613:24 | *source | tests.cpp:615:17:615:22 | *source | provenance | |
| tests.cpp:622:19:622:24 | *source | tests.cpp:625:2:625:16 | *... = ... | provenance | |
| tests.cpp:625:2:625:2 | *s [post update] [*home] | tests.cpp:628:14:628:14 | *s [*home] | provenance | |
| tests.cpp:625:2:625:16 | *... = ... | tests.cpp:625:2:625:2 | *s [post update] [*home] | provenance | |
| tests.cpp:628:14:628:14 | *s [*home] | tests.cpp:628:14:628:19 | *home | provenance | |
| tests.cpp:628:14:628:14 | *s [*home] | tests.cpp:628:16:628:19 | *home | provenance | |
| tests.cpp:628:16:628:19 | *home | tests.cpp:628:14:628:19 | *home | provenance | |
| tests.cpp:657:32:657:35 | **argv | tests.cpp:682:9:682:15 | *access to array | provenance | |
| tests.cpp:657:32:657:35 | **argv | tests.cpp:683:9:683:15 | *access to array | provenance | |
| tests.cpp:682:9:682:15 | *access to array | tests.cpp:613:19:613:24 | *source | provenance | |
| tests.cpp:683:9:683:15 | *access to array | tests.cpp:622:19:622:24 | *source | provenance | |
nodes
| main.cpp:6:27:6:30 | **argv | semmle.label | **argv |
| main.cpp:10:20:10:23 | **argv | semmle.label | **argv |

View File

@@ -1,7 +1,7 @@
edges
| tests.c:16:26:16:29 | **argv | tests.c:28:22:28:28 | *access to array |
| tests.c:16:26:16:29 | **argv | tests.c:29:28:29:34 | *access to array |
| tests.c:16:26:16:29 | **argv | tests.c:34:10:34:16 | *access to array |
| tests.c:16:26:16:29 | **argv | tests.c:28:22:28:28 | *access to array | provenance | |
| tests.c:16:26:16:29 | **argv | tests.c:29:28:29:34 | *access to array | provenance | |
| tests.c:16:26:16:29 | **argv | tests.c:34:10:34:16 | *access to array | provenance | |
nodes
| tests.c:16:26:16:29 | **argv | semmle.label | **argv |
| tests.c:28:22:28:28 | *access to array | semmle.label | *access to array |

View File

@@ -1,5 +1,5 @@
edges
| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | fgets output argument | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data |
| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | fgets output argument | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data | provenance | |
nodes
| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | fgets output argument | semmle.label | fgets output argument |
| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data | semmle.label | data |

View File

@@ -1,13 +1,13 @@
edges
| test1.c:7:26:7:29 | **argv | test1.c:9:9:9:9 | i |
| test1.c:7:26:7:29 | **argv | test1.c:11:9:11:9 | i |
| test1.c:7:26:7:29 | **argv | test1.c:13:9:13:9 | i |
| test1.c:9:9:9:9 | i | test1.c:16:16:16:16 | i |
| test1.c:11:9:11:9 | i | test1.c:32:16:32:16 | i |
| test1.c:13:9:13:9 | i | test1.c:48:16:48:16 | i |
| test1.c:16:16:16:16 | i | test1.c:18:16:18:16 | i |
| test1.c:32:16:32:16 | i | test1.c:33:11:33:11 | i |
| test1.c:48:16:48:16 | i | test1.c:53:15:53:15 | j |
| test1.c:7:26:7:29 | **argv | test1.c:9:9:9:9 | i | provenance | |
| test1.c:7:26:7:29 | **argv | test1.c:11:9:11:9 | i | provenance | |
| test1.c:7:26:7:29 | **argv | test1.c:13:9:13:9 | i | provenance | |
| test1.c:9:9:9:9 | i | test1.c:16:16:16:16 | i | provenance | |
| test1.c:11:9:11:9 | i | test1.c:32:16:32:16 | i | provenance | |
| test1.c:13:9:13:9 | i | test1.c:48:16:48:16 | i | provenance | |
| test1.c:16:16:16:16 | i | test1.c:18:16:18:16 | i | provenance | |
| test1.c:32:16:32:16 | i | test1.c:33:11:33:11 | i | provenance | |
| test1.c:48:16:48:16 | i | test1.c:53:15:53:15 | j | provenance | |
nodes
| test1.c:7:26:7:29 | **argv | semmle.label | **argv |
| test1.c:9:9:9:9 | i | semmle.label | i |

View File

@@ -1,7 +1,7 @@
edges
| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data |
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | *data |
| char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | *data |
| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | provenance | |
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | *data | provenance | |
| char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | *data | provenance | |
nodes
| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | semmle.label | recv output argument |
| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | semmle.label | *data |

View File

@@ -1,28 +1,28 @@
edges
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:95:9:95:15 | *access to array |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:96:15:96:21 | *access to array |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:101:9:101:10 | *i1 |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:102:15:102:16 | *i1 |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:106:9:106:13 | *access to array |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:107:15:107:19 | *access to array |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:110:9:110:11 | ** ... |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:111:15:111:17 | ** ... |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:116:9:116:10 | *i3 |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:117:15:117:16 | *i3 |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:121:9:121:10 | *i4 |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:122:15:122:16 | *i4 |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:127:9:127:10 | *i5 |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:128:15:128:16 | *i5 |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:131:9:131:14 | *... + ... |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:132:15:132:20 | *... + ... |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:135:9:135:12 | *... ++ |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:136:15:136:18 | *-- ... |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:139:9:139:26 | *... ? ... : ... |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:140:15:140:32 | *... ? ... : ... |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:144:9:144:10 | *i7 |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:145:15:145:16 | *i7 |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:150:9:150:10 | *i8 |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:151:15:151:16 | *i8 |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:95:9:95:15 | *access to array | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:96:15:96:21 | *access to array | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:101:9:101:10 | *i1 | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:102:15:102:16 | *i1 | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:106:9:106:13 | *access to array | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:107:15:107:19 | *access to array | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:110:9:110:11 | ** ... | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:111:15:111:17 | ** ... | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:116:9:116:10 | *i3 | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:117:15:117:16 | *i3 | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:121:9:121:10 | *i4 | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:122:15:122:16 | *i4 | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:127:9:127:10 | *i5 | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:128:15:128:16 | *i5 | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:131:9:131:14 | *... + ... | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:132:15:132:20 | *... + ... | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:135:9:135:12 | *... ++ | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:136:15:136:18 | *-- ... | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:139:9:139:26 | *... ? ... : ... | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:140:15:140:32 | *... ? ... : ... | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:144:9:144:10 | *i7 | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:145:15:145:16 | *i7 | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:150:9:150:10 | *i8 | provenance | |
| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:151:15:151:16 | *i8 | provenance | |
nodes
| argvLocal.c:13:27:13:30 | **argv | semmle.label | **argv |
| argvLocal.c:95:9:95:15 | *access to array | semmle.label | *access to array |

View File

@@ -1,4 +1,3 @@
| consts.cpp:81:9:81:10 | c8 | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| consts.cpp:86:9:86:10 | v1 | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| consts.cpp:91:9:91:10 | v2 | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| consts.cpp:95:9:95:10 | v3 | The format string argument to printf should be constant to prevent security issues and other potential errors. |

View File

@@ -75,7 +75,7 @@ void a() {
// GOOD: constFuncToArray() always returns a value from gc1, which is always constant
printf(constFuncToArray(0));
// BAD: format string is not constant
// BAD: format string is not constant [NOT DETECTED]
char c8[10];
sprintf(c8, "%d", 1);
printf(c8);

View File

@@ -1,12 +1,12 @@
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:58:9:58:10 | *e1 |
| funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | *i3 |
| funcsLocal.c:31:13:31:17 | *call to fgets | 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:41:13:41:16 | *call to gets | funcsLocal.c:42:9:42:10 | *i6 |
| funcsLocal.c:46:7:46:9 | gets output argument | funcsLocal.c:47:9:47:11 | ** ... |
| funcsLocal.c:52:8:52:11 | *call to gets | funcsLocal.c:53:9:53:11 | ** ... |
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | *i1 | provenance | |
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | *e1 | provenance | |
| funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | *i3 | provenance | |
| funcsLocal.c:31:13:31:17 | *call to fgets | funcsLocal.c:32:9:32:10 | *i4 | provenance | |
| funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | *i5 | provenance | |
| funcsLocal.c:41:13:41:16 | *call to gets | funcsLocal.c:42:9:42:10 | *i6 | provenance | |
| funcsLocal.c:46:7:46:9 | gets output argument | funcsLocal.c:47:9:47:11 | ** ... | provenance | |
| funcsLocal.c:52:8:52:11 | *call to gets | funcsLocal.c:53:9:53:11 | ** ... | provenance | |
nodes
| funcsLocal.c:16:8:16:9 | fread output argument | semmle.label | fread output argument |
| funcsLocal.c:17:9:17:10 | *i1 | semmle.label | *i1 |

View File

@@ -1,15 +1,15 @@
edges
| globalVars.c:8:7:8:10 | **copy | globalVars.c:27:9:27:12 | *copy |
| globalVars.c:8:7:8:10 | **copy | globalVars.c:30:15:30:18 | *copy |
| globalVars.c:8:7:8:10 | **copy | globalVars.c:35:11:35:14 | *copy |
| globalVars.c:9:7:9:11 | **copy2 | globalVars.c:38:9:38:13 | *copy2 |
| globalVars.c:9:7:9:11 | **copy2 | globalVars.c:41:15:41:19 | *copy2 |
| globalVars.c:9:7:9:11 | **copy2 | globalVars.c:50:9:50:13 | *copy2 |
| globalVars.c:11:22:11:25 | **argv | globalVars.c:8:7:8:10 | **copy |
| globalVars.c:15:21:15:23 | *val | globalVars.c:9:7:9:11 | **copy2 |
| globalVars.c:23:27:23:30 | **argv | globalVars.c:24:11:24:14 | **argv |
| globalVars.c:24:11:24:14 | **argv | globalVars.c:11:22:11:25 | **argv |
| globalVars.c:35:11:35:14 | *copy | globalVars.c:15:21:15:23 | *val |
| globalVars.c:8:7:8:10 | **copy | globalVars.c:27:9:27:12 | *copy | provenance | |
| globalVars.c:8:7:8:10 | **copy | globalVars.c:30:15:30:18 | *copy | provenance | |
| globalVars.c:8:7:8:10 | **copy | globalVars.c:35:11:35:14 | *copy | provenance | |
| globalVars.c:9:7:9:11 | **copy2 | globalVars.c:38:9:38:13 | *copy2 | provenance | |
| globalVars.c:9:7:9:11 | **copy2 | globalVars.c:41:15:41:19 | *copy2 | provenance | |
| globalVars.c:9:7:9:11 | **copy2 | globalVars.c:50:9:50:13 | *copy2 | provenance | |
| globalVars.c:11:22:11:25 | **argv | globalVars.c:8:7:8:10 | **copy | provenance | |
| globalVars.c:15:21:15:23 | *val | globalVars.c:9:7:9:11 | **copy2 | provenance | |
| globalVars.c:23:27:23:30 | **argv | globalVars.c:24:11:24:14 | **argv | provenance | |
| globalVars.c:24:11:24:14 | **argv | globalVars.c:11:22:11:25 | **argv | provenance | |
| globalVars.c:35:11:35:14 | *copy | globalVars.c:15:21:15:23 | *val | provenance | |
nodes
| globalVars.c:8:7:8:10 | **copy | semmle.label | **copy |
| globalVars.c:9:7:9:11 | **copy2 | semmle.label | **copy2 |

View File

@@ -1,15 +1,15 @@
edges
| ifs.c:16:27:16:30 | **argv | ifs.c:62:9:62:10 | *c7 |
| ifs.c:16:27:16:30 | **argv | ifs.c:69:9:69:10 | *c8 |
| ifs.c:16:27:16:30 | **argv | ifs.c:75:9:75:10 | *i1 |
| ifs.c:16:27:16:30 | **argv | ifs.c:81:9:81:10 | *i2 |
| ifs.c:16:27:16:30 | **argv | ifs.c:87:9:87:10 | *i3 |
| ifs.c:16:27:16:30 | **argv | ifs.c:93:9:93:10 | *i4 |
| ifs.c:16:27:16:30 | **argv | ifs.c:99:9:99:10 | *i5 |
| ifs.c:16:27:16:30 | **argv | ifs.c:106:9:106:10 | *i6 |
| ifs.c:16:27:16:30 | **argv | ifs.c:112:9:112:10 | *i7 |
| ifs.c:16:27:16:30 | **argv | ifs.c:118:9:118:10 | *i8 |
| ifs.c:16:27:16:30 | **argv | ifs.c:124:9:124:10 | *i9 |
| ifs.c:16:27:16:30 | **argv | ifs.c:62:9:62:10 | *c7 | provenance | |
| ifs.c:16:27:16:30 | **argv | ifs.c:69:9:69:10 | *c8 | provenance | |
| ifs.c:16:27:16:30 | **argv | ifs.c:75:9:75:10 | *i1 | provenance | |
| ifs.c:16:27:16:30 | **argv | ifs.c:81:9:81:10 | *i2 | provenance | |
| ifs.c:16:27:16:30 | **argv | ifs.c:87:9:87:10 | *i3 | provenance | |
| ifs.c:16:27:16:30 | **argv | ifs.c:93:9:93:10 | *i4 | provenance | |
| ifs.c:16:27:16:30 | **argv | ifs.c:99:9:99:10 | *i5 | provenance | |
| ifs.c:16:27:16:30 | **argv | ifs.c:106:9:106:10 | *i6 | provenance | |
| ifs.c:16:27:16:30 | **argv | ifs.c:112:9:112:10 | *i7 | provenance | |
| ifs.c:16:27:16:30 | **argv | ifs.c:118:9:118:10 | *i8 | provenance | |
| ifs.c:16:27:16:30 | **argv | ifs.c:124:9:124:10 | *i9 | provenance | |
nodes
| ifs.c:16:27:16:30 | **argv | semmle.label | **argv |
| ifs.c:62:9:62:10 | *c7 | semmle.label | *c7 |

View File

@@ -1,5 +1,5 @@
edges
| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data |
| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data | provenance | |
nodes
| examples.cpp:63:26:63:30 | fscanf output argument | semmle.label | fscanf output argument |
| examples.cpp:66:11:66:14 | data | semmle.label | data |

View File

@@ -1,16 +1,16 @@
edges
| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data |
| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data |
| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data |
| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data |
| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data |
| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data |
| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data |
| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data |
| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data |
| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data |
| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data |
| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data |
| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | provenance | |
| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | provenance | |
| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | provenance | |
| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | provenance | |
| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | provenance | |
| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | provenance | |
| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | provenance | |
| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | provenance | |
| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | provenance | |
| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | provenance | |
| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | provenance | |
| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | provenance | |
nodes
| examples.cpp:22:26:22:33 | call to rand | semmle.label | call to rand |
| examples.cpp:22:26:22:33 | call to rand | semmle.label | call to rand |

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