在 C 和 C++ 中使用 guards 库¶
您可以使用 CodeQL guards 库来识别条件表达式,这些表达式控制 C 和 C++ 代码库中程序其他部分的执行。
关于 guards 库¶
guards 库(在 semmle.code.cpp.controlflow.Guards 中定义)提供了一个类 GuardCondition,表示用于进行控制流决策的布尔值。如果一个基本块只能在 GuardCondition 以特定方式计算时才能到达,则认为该 GuardCondition 保护该基本块。例如,在以下代码中,x < 10 是一个 GuardCondition,它保护返回语句之前的所有代码。
if(x < 10) {
f(x);
} else if (x < 20) {
g(x);
} else {
h(x);
}
return 0;
controls 谓词¶
controls 谓词有助于确定哪些块仅在 GuardCondition 以特定方式计算时才会运行。 guard.controls(block, testIsTrue) 成立,如果 block 仅在该条件的值为 testIsTrue 时才会进入。
在以下代码示例中,对 isValid 的调用控制对 performAction 和 logFailure 的调用,但不控制 return 语句。
if(isValid(accessToken)) {
performAction();
succeeded = 1;
} else {
logFailure();
succeeded = 0;
}
return succeeded;
在以下代码示例中,对 isValid 的调用控制 if 语句的主体,以及 if 之后的代码。
if(!isValid(accessToken)) {
logFailure();
return 0;
}
performAction();
return succeeded;
ensuresEq 和 ensuresLt 谓词¶
ensuresEq 和 ensuresLt 谓词是确定 GuardCondition 为给定基本块提供哪些保证(如果有)的主要方法。
ensuresEq 谓词¶
当 ensuresEq(left, right, k, block, true) 成立时,则仅在 left 在其最后一次计算时等于 right + k 时才会执行 block。当 ensuresEq(left, right, k, block, false) 成立时,则仅在 left 在其最后一次计算时不等于 right + k 时才会执行 block。
ensuresLt 谓词¶
当 ensuresLt(left, right, k, block, true) 成立时,则仅在 left 在其最后一次计算时严格小于 right + k 时才会执行 block。当 ensuresLt(left, right, k, block, false) 成立时,则仅在 left 在其最后一次计算时大于或等于 right + k 时才会执行 block。
在以下代码示例中,第一行上的比较确保 index 在“then”块中小于 size,并且 index 在“else”块中大于或等于 size。
if(index < size) {
ret = array[index];
} else {
ret = nullptr
}
return ret;
comparesEq 和 comparesLt 谓词¶
comparesEq 和 comparesLt 谓词有助于确定 GuardCondition 是否计算为真。
comparesEq 谓词¶
comparesEq(left, right, k, true, testIsTrue) 成立,如果 left 等于 right + k,当表达式计算为 testIsTrue 时。
comparesLt 谓词¶
comparesLt(left, right, k, isLessThan, testIsTrue) 成立,如果 left < right + k 计算为 isLessThan,当表达式计算为 testIsTrue 时。