зеркало из https://github.com/github/codeql.git
Merge pull request #744 from geoffw0/format
CPP: Autoformat some untidy files
This commit is contained in:
Коммит
08db4cd959
|
@ -7,51 +7,64 @@
|
|||
* @tags reliability
|
||||
* external/cwe/cwe-561
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
predicate testAndBranch(Expr e, Stmt branch)
|
||||
{
|
||||
exists(IfStmt ifstmt | ifstmt.getCondition() = e and
|
||||
(ifstmt.getThen() = branch or ifstmt.getElse() = branch))
|
||||
predicate testAndBranch(Expr e, Stmt branch) {
|
||||
exists(IfStmt ifstmt |
|
||||
ifstmt.getCondition() = e and
|
||||
(ifstmt.getThen() = branch or ifstmt.getElse() = branch)
|
||||
)
|
||||
or
|
||||
exists(WhileStmt while | while.getCondition() = e and
|
||||
while.getStmt() = branch)
|
||||
exists(WhileStmt while |
|
||||
while.getCondition() = e and
|
||||
while.getStmt() = branch
|
||||
)
|
||||
}
|
||||
|
||||
predicate choice(LocalScopeVariable v, Stmt branch, string value)
|
||||
{
|
||||
predicate choice(LocalScopeVariable v, Stmt branch, string value) {
|
||||
exists(AnalysedExpr e |
|
||||
testAndBranch(e, branch) and
|
||||
(
|
||||
(e.getNullSuccessor(v) = branch and value = "null")
|
||||
or
|
||||
(e.getNonNullSuccessor(v) = branch and value = "non-null")
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
predicate guarded(LocalScopeVariable v, Stmt loopstart, AnalysedExpr child)
|
||||
{
|
||||
predicate guarded(LocalScopeVariable v, Stmt loopstart, AnalysedExpr child) {
|
||||
choice(v, loopstart, _) and
|
||||
loopstart.getChildStmt*() = child.getEnclosingStmt() and
|
||||
(definition(v, child) or exists(child.getNullSuccessor(v)))
|
||||
}
|
||||
|
||||
predicate addressLeak(Variable v, Stmt leak)
|
||||
{
|
||||
predicate addressLeak(Variable v, Stmt leak) {
|
||||
exists(VariableAccess access |
|
||||
v.getAnAccess() = access and
|
||||
access.getEnclosingStmt() = leak and
|
||||
access.isAddressOfAccess())
|
||||
access.isAddressOfAccess()
|
||||
)
|
||||
}
|
||||
|
||||
from LocalScopeVariable v, Stmt branch, AnalysedExpr cond, string context, string test, string testresult
|
||||
where choice(v, branch, context)
|
||||
and forall(ControlFlowNode def | definition(v, def) and definitionReaches(def, cond) | not guarded(v, branch, def))
|
||||
and not cond.isDef(v)
|
||||
and guarded(v, branch, cond)
|
||||
and exists(cond.getNullSuccessor(v))
|
||||
and not addressLeak(v, branch.getChildStmt*())
|
||||
and ((cond.isNullCheck(v) and test = "null") or (cond.isValidCheck(v) and test = "non-null"))
|
||||
and (if context = test then testresult = "succeed" else testresult = "fail")
|
||||
select cond, "Variable '" + v.getName() + "' is always " + context + " here, this check will always " + testresult + "."
|
||||
from
|
||||
LocalScopeVariable v, Stmt branch, AnalysedExpr cond, string context, string test,
|
||||
string testresult
|
||||
where
|
||||
choice(v, branch, context) and
|
||||
forall(ControlFlowNode def | definition(v, def) and definitionReaches(def, cond) |
|
||||
not guarded(v, branch, def)
|
||||
) and
|
||||
not cond.isDef(v) and
|
||||
guarded(v, branch, cond) and
|
||||
exists(cond.getNullSuccessor(v)) and
|
||||
not addressLeak(v, branch.getChildStmt*()) and
|
||||
(
|
||||
(cond.isNullCheck(v) and test = "null")
|
||||
or
|
||||
(cond.isValidCheck(v) and test = "non-null")
|
||||
) and
|
||||
(if context = test then testresult = "succeed" else testresult = "fail")
|
||||
select cond,
|
||||
"Variable '" + v.getName() + "' is always " + context + " here, this check will always " +
|
||||
testresult + "."
|
||||
|
|
|
@ -7,34 +7,46 @@
|
|||
* @tags reliability
|
||||
* external/cwe/cwe-457
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
// See also InitialisationNotRun.ql and GlobalUseBeforeInit.ql
|
||||
|
||||
// Holds if s defines variable v (conservative)
|
||||
/**
|
||||
* Holds if `s` defines variable `v` (conservative).
|
||||
*/
|
||||
predicate defines(ControlFlowNode s, Variable lv) {
|
||||
exists(VariableAccess va | va = s and va.getTarget() = lv and va.isUsedAsLValue())
|
||||
}
|
||||
|
||||
// Holds if s uses variable v (conservative)
|
||||
/**
|
||||
* Holds if `s` uses variable `v` (conservative).
|
||||
*/
|
||||
predicate uses(ControlFlowNode s, Variable lv) {
|
||||
exists(VariableAccess va | va = s and va.getTarget() = lv and va.isRValue()
|
||||
and not va.getParent+() instanceof SizeofOperator)
|
||||
exists(VariableAccess va |
|
||||
va = s and
|
||||
va.getTarget() = lv and
|
||||
va.isRValue() and
|
||||
not va.getParent+() instanceof SizeofOperator
|
||||
)
|
||||
}
|
||||
|
||||
// Holds if there is a path from the declaration of lv to n such that lv is
|
||||
// definitely not defined before n
|
||||
/**
|
||||
* Holds if there is a path from the declaration of `lv` to `n` such that `lv` is
|
||||
* definitely not defined before `n`.
|
||||
*/
|
||||
predicate noDefPath(LocalVariable lv, ControlFlowNode n) {
|
||||
n.(DeclStmt).getADeclaration() = lv and not exists(lv.getInitializer())
|
||||
or exists(ControlFlowNode p | noDefPath(lv, p) and n = p.getASuccessor() and not defines(p, lv))
|
||||
n.(DeclStmt).getADeclaration() = lv and not exists(lv.getInitializer())
|
||||
or
|
||||
exists(ControlFlowNode p | noDefPath(lv, p) and n = p.getASuccessor() and not defines(p, lv))
|
||||
}
|
||||
|
||||
predicate isAggregateType(Type t) {
|
||||
t instanceof Class or t instanceof ArrayType
|
||||
}
|
||||
predicate isAggregateType(Type t) { t instanceof Class or t instanceof ArrayType }
|
||||
|
||||
// Holds if va is a use of a local variable that has not been previously
|
||||
// defined
|
||||
/**
|
||||
* Holds if `va` is a use of a local variable that has not been previously
|
||||
* defined.
|
||||
*/
|
||||
predicate undefinedLocalUse(VariableAccess va) {
|
||||
exists(LocalVariable lv |
|
||||
// it is hard to tell when a struct or array has been initialized, so we
|
||||
|
@ -43,17 +55,21 @@ predicate undefinedLocalUse(VariableAccess va) {
|
|||
not lv.getType().hasName("va_list") and
|
||||
va = lv.getAnAccess() and
|
||||
noDefPath(lv, va) and
|
||||
uses(va, lv))
|
||||
uses(va, lv)
|
||||
)
|
||||
}
|
||||
|
||||
// Holds if gv is a potentially uninitialized global variable
|
||||
/**
|
||||
* Holds if `gv` is a potentially uninitialized global variable.
|
||||
*/
|
||||
predicate uninitialisedGlobal(GlobalVariable gv) {
|
||||
exists(VariableAccess va |
|
||||
not isAggregateType(gv.getUnderlyingType()) and
|
||||
va = gv.getAnAccess() and
|
||||
va.isRValue() and
|
||||
not gv.hasInitializer() and
|
||||
not gv.hasSpecifier("extern"))
|
||||
not gv.hasSpecifier("extern")
|
||||
)
|
||||
}
|
||||
|
||||
from Element elt
|
||||
|
|
|
@ -11,56 +11,61 @@
|
|||
* external/cwe/cwe-131
|
||||
* external/cwe/cwe-122
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
class Allocation extends FunctionCall
|
||||
{
|
||||
class Allocation extends FunctionCall {
|
||||
Allocation() {
|
||||
exists(string name |
|
||||
this.getTarget().hasQualifiedName(name) and
|
||||
(name = "malloc" or name = "calloc" or name = "realloc"))
|
||||
(name = "malloc" or name = "calloc" or name = "realloc")
|
||||
)
|
||||
}
|
||||
|
||||
string getName() { result = this.getTarget().getQualifiedName() }
|
||||
|
||||
int getSize() {
|
||||
(this.getName() = "malloc" and
|
||||
this.getArgument(0).getValue().toInt() = result)
|
||||
(
|
||||
this.getName() = "malloc" and
|
||||
this.getArgument(0).getValue().toInt() = result
|
||||
)
|
||||
or
|
||||
(this.getName() = "realloc" and
|
||||
this.getArgument(1).getValue().toInt() = result)
|
||||
(
|
||||
this.getName() = "realloc" and
|
||||
this.getArgument(1).getValue().toInt() = result
|
||||
)
|
||||
or
|
||||
(this.getName() = "calloc" and
|
||||
result =
|
||||
this.getArgument(0).getValue().toInt() *
|
||||
this.getArgument(1).getValue().toInt())
|
||||
(
|
||||
this.getName() = "calloc" and
|
||||
result = this.getArgument(0).getValue().toInt() * this.getArgument(1).getValue().toInt()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
predicate baseType(Allocation alloc, Type base)
|
||||
{
|
||||
predicate baseType(Allocation alloc, Type base) {
|
||||
exists(PointerType pointer |
|
||||
pointer.getBaseType() = base and
|
||||
(
|
||||
exists(AssignExpr assign |
|
||||
assign.getRValue() = alloc and assign.getLValue().getType() = pointer)
|
||||
assign.getRValue() = alloc and assign.getLValue().getType() = pointer
|
||||
)
|
||||
or
|
||||
exists(Variable v |
|
||||
v.getInitializer().getExpr() = alloc and v.getType() = pointer)
|
||||
exists(Variable v | v.getInitializer().getExpr() = alloc and v.getType() = pointer)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
predicate decideOnSize(Type t, int size)
|
||||
{
|
||||
predicate decideOnSize(Type t, int size) {
|
||||
// If the codebase has more than one type with the same name, it can have more than one size.
|
||||
size = min(t.getSize())
|
||||
}
|
||||
|
||||
from Allocation alloc, Type base, int basesize, int allocated
|
||||
where baseType(alloc, base)
|
||||
and allocated = alloc.getSize()
|
||||
and decideOnSize(base, basesize)
|
||||
and basesize > allocated
|
||||
select alloc, "Type '" + base.getName() + "' is " + basesize.toString() +
|
||||
" bytes, but only " + allocated.toString() + " bytes are allocated."
|
||||
where
|
||||
baseType(alloc, base) and
|
||||
allocated = alloc.getSize() and
|
||||
decideOnSize(base, basesize) and
|
||||
basesize > allocated
|
||||
select alloc,
|
||||
"Type '" + base.getName() + "' is " + basesize.toString() + " bytes, but only " +
|
||||
allocated.toString() + " bytes are allocated."
|
||||
|
|
|
@ -11,54 +11,60 @@
|
|||
* external/cwe/cwe-131
|
||||
* external/cwe/cwe-122
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
class Allocation extends FunctionCall
|
||||
{
|
||||
class Allocation extends FunctionCall {
|
||||
Allocation() {
|
||||
exists(string name |
|
||||
this.getTarget().hasQualifiedName(name) and
|
||||
(name = "malloc" or name = "calloc" or name = "realloc"))
|
||||
(name = "malloc" or name = "calloc" or name = "realloc")
|
||||
)
|
||||
}
|
||||
|
||||
string getName() { result = this.getTarget().getQualifiedName() }
|
||||
|
||||
int getSize() {
|
||||
(this.getName() = "malloc" and
|
||||
this.getArgument(0).getValue().toInt() = result)
|
||||
(
|
||||
this.getName() = "malloc" and
|
||||
this.getArgument(0).getValue().toInt() = result
|
||||
)
|
||||
or
|
||||
(this.getName() = "realloc" and
|
||||
this.getArgument(1).getValue().toInt() = result)
|
||||
(
|
||||
this.getName() = "realloc" and
|
||||
this.getArgument(1).getValue().toInt() = result
|
||||
)
|
||||
or
|
||||
(this.getName() = "calloc" and
|
||||
result =
|
||||
this.getArgument(0).getValue().toInt() *
|
||||
this.getArgument(1).getValue().toInt())
|
||||
(
|
||||
this.getName() = "calloc" and
|
||||
result = this.getArgument(0).getValue().toInt() * this.getArgument(1).getValue().toInt()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
predicate baseType(Allocation alloc, Type base)
|
||||
{
|
||||
predicate baseType(Allocation alloc, Type base) {
|
||||
exists(PointerType pointer |
|
||||
pointer.getBaseType() = base and
|
||||
(
|
||||
exists(AssignExpr assign |
|
||||
assign.getRValue() = alloc and assign.getLValue().getType() = pointer)
|
||||
assign.getRValue() = alloc and assign.getLValue().getType() = pointer
|
||||
)
|
||||
or
|
||||
exists(Variable v |
|
||||
v.getInitializer().getExpr() = alloc and v.getType() = pointer)
|
||||
exists(Variable v | v.getInitializer().getExpr() = alloc and v.getType() = pointer)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
from Allocation alloc, Type base, int basesize, int allocated
|
||||
where baseType(alloc, base)
|
||||
and allocated = alloc.getSize()
|
||||
where
|
||||
baseType(alloc, base) and
|
||||
allocated = alloc.getSize() and
|
||||
// If the codebase has more than one type with the same name, check if any matches
|
||||
and not exists(int size | base.getSize() = size |
|
||||
size = 0
|
||||
or (allocated / size) * size = allocated)
|
||||
and basesize = min(base.getSize())
|
||||
select alloc, "Allocated memory (" + allocated.toString() +
|
||||
" bytes) is not a multiple of the size of '" +
|
||||
base.getName() + "' (" + basesize.toString() + " bytes)."
|
||||
not exists(int size | base.getSize() = size |
|
||||
size = 0 or
|
||||
(allocated / size) * size = allocated
|
||||
) and
|
||||
basesize = min(base.getSize())
|
||||
select alloc,
|
||||
"Allocated memory (" + allocated.toString() + " bytes) is not a multiple of the size of '" +
|
||||
base.getName() + "' (" + basesize.toString() + " bytes)."
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* maintainability
|
||||
* modularity
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.headers.MultipleInclusion
|
||||
|
||||
|
@ -20,9 +21,15 @@ import semmle.code.cpp.headers.MultipleInclusion
|
|||
* However one case must be a correctIncludeGuard to prove that this macro really is intended
|
||||
* to be an include guard.
|
||||
*/
|
||||
|
||||
from HeaderFile hf, PreprocessorDirective ifndef, string macroName, int num
|
||||
where hasIncludeGuard(hf, ifndef, _, macroName)
|
||||
and exists(HeaderFile other | hasIncludeGuard(other, _, _, macroName) and hf.getShortName() != other.getShortName())
|
||||
and num = strictcount(HeaderFile other | hasIncludeGuard(other, _, _, macroName))
|
||||
and correctIncludeGuard(_, _, _, _, macroName)
|
||||
select ifndef, "The macro name '" + macroName + "' of this include guard is used in " + num + " different header files."
|
||||
where
|
||||
hasIncludeGuard(hf, ifndef, _, macroName) and
|
||||
exists(HeaderFile other |
|
||||
hasIncludeGuard(other, _, _, macroName) and hf.getShortName() != other.getShortName()
|
||||
) and
|
||||
num = strictcount(HeaderFile other | hasIncludeGuard(other, _, _, macroName)) and
|
||||
correctIncludeGuard(_, _, _, _, macroName)
|
||||
select ifndef,
|
||||
"The macro name '" + macroName + "' of this include guard is used in " + num +
|
||||
" different header files."
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/**
|
||||
* @name Potentially overflowing call to snprintf
|
||||
* @description Using the return value from snprintf without proper checks can cause overflow.
|
||||
*
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @precision high
|
||||
|
@ -20,44 +19,44 @@ import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
|||
* true if there is an arithmetic operation on the path that
|
||||
* might overflow.
|
||||
*/
|
||||
predicate flowsToExpr(
|
||||
Expr source, Expr sink, boolean pathMightOverflow) {
|
||||
predicate flowsToExpr(Expr source, Expr sink, boolean pathMightOverflow) {
|
||||
// Might the current expression overflow?
|
||||
exists (boolean otherMightOverflow
|
||||
| flowsToExprImpl(source, sink, otherMightOverflow)
|
||||
| if convertedExprMightOverflow(sink)
|
||||
then pathMightOverflow = true
|
||||
else pathMightOverflow = otherMightOverflow)
|
||||
exists(boolean otherMightOverflow | flowsToExprImpl(source, sink, otherMightOverflow) |
|
||||
if convertedExprMightOverflow(sink)
|
||||
then pathMightOverflow = true
|
||||
else pathMightOverflow = otherMightOverflow
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of `flowsToExpr`. Does everything except
|
||||
* checking whether the current expression might overflow.
|
||||
*/
|
||||
predicate flowsToExprImpl(
|
||||
Expr source, Expr sink, boolean pathMightOverflow) {
|
||||
(source = sink and pathMightOverflow = false and
|
||||
source.(FunctionCall).getTarget().(Snprintf).returnsFullFormatLength())
|
||||
predicate flowsToExprImpl(Expr source, Expr sink, boolean pathMightOverflow) {
|
||||
(
|
||||
source = sink and
|
||||
pathMightOverflow = false and
|
||||
source.(FunctionCall).getTarget().(Snprintf).returnsFullFormatLength()
|
||||
)
|
||||
or
|
||||
exists (RangeSsaDefinition def, LocalScopeVariable v
|
||||
| flowsToDef(source, def, v, pathMightOverflow) and
|
||||
sink = def.getAUse(v))
|
||||
exists(RangeSsaDefinition def, LocalScopeVariable v |
|
||||
flowsToDef(source, def, v, pathMightOverflow) and
|
||||
sink = def.getAUse(v)
|
||||
)
|
||||
or
|
||||
flowsToExpr(
|
||||
source, sink.(UnaryArithmeticOperation).getOperand(), pathMightOverflow)
|
||||
flowsToExpr(source, sink.(UnaryArithmeticOperation).getOperand(), pathMightOverflow)
|
||||
or
|
||||
flowsToExpr(
|
||||
source, sink.(BinaryArithmeticOperation).getAnOperand(), pathMightOverflow)
|
||||
flowsToExpr(source, sink.(BinaryArithmeticOperation).getAnOperand(), pathMightOverflow)
|
||||
or
|
||||
flowsToExpr(
|
||||
source, sink.(Assignment).getRValue(), pathMightOverflow)
|
||||
flowsToExpr(source, sink.(Assignment).getRValue(), pathMightOverflow)
|
||||
or
|
||||
flowsToExpr(
|
||||
source, sink.(AssignOperation).getLValue(), pathMightOverflow)
|
||||
flowsToExpr(source, sink.(AssignOperation).getLValue(), pathMightOverflow)
|
||||
or
|
||||
exists (FormattingFunctionCall call
|
||||
| sink = call and
|
||||
flowsToExpr(source, call.getArgument(call.getTarget().getSizeParameterIndex()), pathMightOverflow))
|
||||
exists(FormattingFunctionCall call |
|
||||
sink = call and
|
||||
flowsToExpr(source, call.getArgument(call.getTarget().getSizeParameterIndex()),
|
||||
pathMightOverflow)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,14 +66,14 @@ predicate flowsToExprImpl(
|
|||
* on the path that might overflow.
|
||||
*/
|
||||
predicate flowsToDef(
|
||||
Expr source, RangeSsaDefinition def, LocalScopeVariable v,
|
||||
boolean pathMightOverflow) {
|
||||
Expr source, RangeSsaDefinition def, LocalScopeVariable v, boolean pathMightOverflow
|
||||
) {
|
||||
// Might the current definition overflow?
|
||||
exists (boolean otherMightOverflow
|
||||
| flowsToDefImpl(source, def, v, otherMightOverflow)
|
||||
| if defMightOverflow(def, v)
|
||||
then pathMightOverflow = true
|
||||
else pathMightOverflow = otherMightOverflow)
|
||||
exists(boolean otherMightOverflow | flowsToDefImpl(source, def, v, otherMightOverflow) |
|
||||
if defMightOverflow(def, v)
|
||||
then pathMightOverflow = true
|
||||
else pathMightOverflow = otherMightOverflow
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,26 +88,29 @@ predicate flowsToDef(
|
|||
* the path. But it is a good way to reduce the number of false positives.
|
||||
*/
|
||||
predicate flowsToDefImpl(
|
||||
Expr source, RangeSsaDefinition def, LocalScopeVariable v,
|
||||
boolean pathMightOverflow) {
|
||||
Expr source, RangeSsaDefinition def, LocalScopeVariable v, boolean pathMightOverflow
|
||||
) {
|
||||
// Assignment or initialization: `e = v;`
|
||||
exists (Expr e
|
||||
| e = def.getDefiningValue(v) and
|
||||
flowsToExpr(source, e, pathMightOverflow))
|
||||
exists(Expr e |
|
||||
e = def.getDefiningValue(v) and
|
||||
flowsToExpr(source, e, pathMightOverflow)
|
||||
)
|
||||
or
|
||||
// `x++`
|
||||
exists (CrementOperation crem
|
||||
| def = crem and
|
||||
exists(CrementOperation crem |
|
||||
def = crem and
|
||||
crem.getOperand() = v.getAnAccess() and
|
||||
flowsToExpr(source, crem.getOperand(), pathMightOverflow))
|
||||
flowsToExpr(source, crem.getOperand(), pathMightOverflow)
|
||||
)
|
||||
or
|
||||
// Phi definition.
|
||||
flowsToDef(source, def.getAPhiInput(v), v, pathMightOverflow)
|
||||
}
|
||||
|
||||
from FormattingFunctionCall call, Expr sink
|
||||
where flowsToExpr(call, sink, true)
|
||||
and sink = call.getArgument(call.getTarget().getSizeParameterIndex())
|
||||
select
|
||||
call, "The $@ of this snprintf call is derived from its return value, which may exceed the size of the buffer and overflow.",
|
||||
where
|
||||
flowsToExpr(call, sink, true) and
|
||||
sink = call.getArgument(call.getTarget().getSizeParameterIndex())
|
||||
select call,
|
||||
"The $@ of this snprintf call is derived from its return value, which may exceed the size of the buffer and overflow.",
|
||||
sink, "size argument"
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* @problem.severity warning
|
||||
* @tags maintainability
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
/**
|
||||
|
@ -15,15 +16,15 @@ import cpp
|
|||
* or template argument).
|
||||
*/
|
||||
predicate simple(Literal l) {
|
||||
l instanceof OctalLiteral or
|
||||
l instanceof HexLiteral or
|
||||
l instanceof CharLiteral or
|
||||
l.getValueText() = "true" or
|
||||
l.getValueText() = "false" or
|
||||
// Parsing doubles is too slow...
|
||||
//exists(l.getValueText().toFloat())
|
||||
// Instead, check whether the literal starts with a letter.
|
||||
not l.getValueText().regexpMatch("[a-zA-Z_].*")
|
||||
l instanceof OctalLiteral or
|
||||
l instanceof HexLiteral or
|
||||
l instanceof CharLiteral or
|
||||
l.getValueText() = "true" or
|
||||
l.getValueText() = "false" or
|
||||
// Parsing doubles is too slow...
|
||||
//exists(l.getValueText().toFloat())
|
||||
// Instead, check whether the literal starts with a letter.
|
||||
not l.getValueText().regexpMatch("[a-zA-Z_].*")
|
||||
}
|
||||
|
||||
predicate booleanLiteral(Literal l) {
|
||||
|
@ -32,18 +33,23 @@ predicate booleanLiteral(Literal l) {
|
|||
}
|
||||
|
||||
string boolLiteralInLogicalOp(Literal literal) {
|
||||
booleanLiteral(literal) and literal.getParent() instanceof BinaryLogicalOperation and
|
||||
result = "Literal value " + literal.getValueText() + " is used in a logical expression; simplify or use a constant."
|
||||
booleanLiteral(literal) and
|
||||
literal.getParent() instanceof BinaryLogicalOperation and
|
||||
result = "Literal value " + literal.getValueText() +
|
||||
" is used in a logical expression; simplify or use a constant."
|
||||
}
|
||||
|
||||
string comparisonOnLiterals(ComparisonOperation op) {
|
||||
simple(op.getLeftOperand()) and simple(op.getRightOperand()) and
|
||||
simple(op.getLeftOperand()) and
|
||||
simple(op.getRightOperand()) and
|
||||
not op.getAnOperand().isInMacroExpansion() and
|
||||
if op.isConstant() then result = "This comparison involves two literals and is always " + op.getValue() + "."
|
||||
if op.isConstant()
|
||||
then result = "This comparison involves two literals and is always " + op.getValue() + "."
|
||||
else result = "This comparison involves two literals and should be simplified."
|
||||
}
|
||||
|
||||
from Expr e, string msg
|
||||
where (msg = boolLiteralInLogicalOp(e) or msg = comparisonOnLiterals(e)) and
|
||||
not e.isInMacroExpansion()
|
||||
where
|
||||
(msg = boolLiteralInLogicalOp(e) or msg = comparisonOnLiterals(e)) and
|
||||
not e.isInMacroExpansion()
|
||||
select e, msg
|
||||
|
|
|
@ -11,8 +11,11 @@ import cpp
|
|||
class ForbiddenFunction extends Function {
|
||||
ForbiddenFunction() {
|
||||
exists(string name | name = this.getName() |
|
||||
name = "setjmp" or name = "longjmp" or
|
||||
name = "sigsetjmp" or name = "siglongjmp")
|
||||
name = "setjmp" or
|
||||
name = "longjmp" or
|
||||
name = "sigsetjmp" or
|
||||
name = "siglongjmp"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,13 +10,15 @@ import cpp
|
|||
|
||||
Stmt exitFrom(Loop l) {
|
||||
l.getAChild+() = result and
|
||||
(result instanceof ReturnStmt or
|
||||
exists(BreakStmt break | break = result |
|
||||
not l.getAChild*() = break.getTarget())
|
||||
(
|
||||
result instanceof ReturnStmt
|
||||
or
|
||||
exists(BreakStmt break | break = result | not l.getAChild*() = break.getTarget())
|
||||
)
|
||||
}
|
||||
|
||||
from Loop l, Stmt exit
|
||||
where l.getControllingExpr().getValue().toInt() != 0 and
|
||||
exit = exitFrom(l)
|
||||
where
|
||||
l.getControllingExpr().getValue().toInt() != 0 and
|
||||
exit = exitFrom(l)
|
||||
select exit, "$@ should not be exited.", l, "This permanent loop"
|
||||
|
|
|
@ -9,16 +9,17 @@
|
|||
import cpp
|
||||
|
||||
predicate flow(Parameter p, ControlFlowNode n) {
|
||||
(exists(p.getAnAccess()) and n = p.getFunction().getBlock()) or
|
||||
exists(ControlFlowNode mid | flow(p, mid) and not mid = p.getAnAccess() and n = mid.getASuccessor())
|
||||
(exists(p.getAnAccess()) and n = p.getFunction().getBlock())
|
||||
or
|
||||
exists(ControlFlowNode mid |
|
||||
flow(p, mid) and not mid = p.getAnAccess() and n = mid.getASuccessor()
|
||||
)
|
||||
}
|
||||
|
||||
VariableAccess firstAccess(Parameter p) {
|
||||
flow(p, result) and result = p.getAnAccess()
|
||||
}
|
||||
VariableAccess firstAccess(Parameter p) { flow(p, result) and result = p.getAnAccess() }
|
||||
|
||||
from Parameter p, VariableAccess va
|
||||
where va = firstAccess(p) and
|
||||
not exists(Expr e | e.isCondition() | e.getAChild*() = va)
|
||||
where
|
||||
va = firstAccess(p) and
|
||||
not exists(Expr e | e.isCondition() | e.getAChild*() = va)
|
||||
select va, "This use of parameter " + p.getName() + " has not been checked."
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче