Using the guards library in C and C++¶
You can use the CodeQL guards library to identify conditional expressions that control the execution of other parts of a program in C and C++ codebases.
About the guards library¶
The guards library (defined in semmle.code.cpp.controlflow.Guards
) provides a class GuardCondition representing Boolean values that are used to make control flow decisions.
A GuardCondition
is considered to guard a basic block if the block can only be reached if the GuardCondition
is evaluated a certain way. For instance, in the following code, x < 10
is a GuardCondition
, and it guards all the code before the return statement.
if(x < 10) {
f(x);
} else if (x < 20) {
g(x);
} else {
h(x);
}
return 0;
The controls
predicate¶
The controls
predicate helps determine which blocks are only run when the GuardCondition
evaluates a certain way. guard.controls(block, testIsTrue)
holds if block
is only entered if the value of this condition is testIsTrue
.
In the following code sample, the call to isValid
controls the calls to performAction
and logFailure
but not the return statement.
if(isValid(accessToken)) {
performAction();
succeeded = 1;
} else {
logFailure();
succeeded = 0;
}
return succeeded;
In the following code sample, the call to isValid
controls the body of the
if
statement, and also the code after the if
.
if(!isValid(accessToken)) {
logFailure();
return 0;
}
performAction();
return succeeded;
The ensuresEq
and ensuresLt
predicates¶
The ensuresEq
and ensuresLt
predicates are the main way of determining what, if any, guarantees the GuardCondition
provides for a given basic block.
The ensuresEq
predicate¶
When ensuresEq(left, right, k, block, true)
holds, then block
is only executed if left
was equal to right + k
at their last evaluation. When ensuresEq(left, right, k, block, false)
holds, then block
is only executed if left
was not equal to right + k
at their last evaluation.
The ensuresLt
predicate¶
When ensuresLt(left, right, k, block, true)
holds, then block
is only executed if left
was strictly less than right + k
at their last evaluation. When ensuresLt(left, right, k, block, false)
holds, then block
is only executed if left
was greater than or equal to right + k
at their last evaluation.
In the following code sample, the comparison on the first line ensures that index
is less than size
in the “then” block, and that index
is greater than or equal to size
in the “else” block.
if(index < size) {
ret = array[index];
} else {
ret = nullptr
}
return ret;
The comparesEq
and comparesLt
predicates¶
The comparesEq
and comparesLt
predicates help determine if the GuardCondition
evaluates to true.
The comparesEq
predicate¶
comparesEq(left, right, k, true, testIsTrue)
holds if left
equals right + k
when the expression evaluates to testIsTrue
.
The comparesLt
predicate¶
comparesLt(left, right, k, isLessThan, testIsTrue)
holds if left < right + k
evaluates to isLessThan
when the expression evaluates to testIsTrue
.