Fixing conditional only issue.

I changed  to detect any logical operation usage (i.e. !, ==), but I kept usage in a conditional directly as a separate detection condition. I found no false positives on the projects you shared with me previously.
This commit is contained in:
Raul Garcia
2019-01-07 10:44:11 -08:00
parent 880306c621
commit 18bb6696e0
4 changed files with 63 additions and 32 deletions

View File

@@ -40,15 +40,11 @@ predicate isStringCopyCastedAsBoolean( FunctionCall func, Expr expr1, string msg
and msg = "Return Value of " + func.getTarget().getQualifiedName() + " used as boolean."
}
predicate isStringCopyUsedInCondition( FunctionCall func, Expr expr1, string msg ) {
exists( ConditionalStmt condstmt |
condstmt.getAChild() = expr1 |
predicate isStringCopyUsedInLogicalOperationOrCondition( FunctionCall func, Expr expr1, string msg ) {
isStringComparisonFunction( func.getTarget().getQualifiedName() )
and (
// The string copy function is used directly as the conditional expression
func = condstmt.getChild(0)
// ... or it is being used in an equality or logical operation
or exists( EqualityOperation eop |
and (((
// it is being used in an equality or logical operation
exists( EqualityOperation eop |
eop = expr1
and func = eop.getAChild()
)
@@ -61,14 +57,21 @@ predicate isStringCopyUsedInCondition( FunctionCall func, Expr expr1, string msg
and func = ble.getAChild()
)
)
and msg = "Return Value of " + func.getTarget().getQualifiedName() + " used in a conditional."
)
and msg = "Return Value of " + func.getTarget().getQualifiedName() + " used in a logical operation."
)
or
exists( ConditionalStmt condstmt |
condstmt.getAChild() = expr1 |
// or the string copy function is used directly as the conditional expression
func = condstmt.getChild(0)
and msg = "Return Value of " + func.getTarget().getQualifiedName() + " used directly in a conditional expression."
))
}
from FunctionCall func, Expr expr1, string msg
where
( isStringCopyCastedAsBoolean(func, expr1, msg) and
not isStringCopyUsedInCondition(func, expr1, _)
not isStringCopyUsedInLogicalOperationOrCondition(func, expr1, _)
)
or isStringCopyUsedInCondition(func, expr1, msg)
or isStringCopyUsedInLogicalOperationOrCondition(func, expr1, msg)
select expr1, msg

View File

@@ -1,24 +1,34 @@
| test.c:33:9:33:14 | call to strcpy | Return Value of strcpy used in a conditional. |
| test.c:37:9:37:31 | ! ... | Return Value of strcpy used in a conditional. |
| test.c:41:9:41:35 | ... == ... | Return Value of strcpy used in a conditional. |
| test.c:45:9:45:48 | ... && ... | Return Value of strcpy used in a conditional. |
| test.c:49:9:49:15 | call to strncpy | Return Value of strncpy used in a conditional. |
| test.c:53:6:53:34 | ! ... | Return Value of strncpy used in a conditional. |
| test.cpp:75:9:75:14 | call to strcpy | Return Value of strcpy used in a conditional. |
| test.cpp:79:9:79:31 | ! ... | Return Value of strcpy used in a conditional. |
| test.c:34:9:34:14 | call to strcpy | Return Value of strcpy used directly in a conditional expression. |
| test.c:38:9:38:31 | ! ... | Return Value of strcpy used in a logical operation. |
| test.c:42:9:42:35 | ... == ... | Return Value of strcpy used in a logical operation. |
| test.c:46:9:46:48 | ... && ... | Return Value of strcpy used in a logical operation. |
| test.c:50:9:50:15 | call to strncpy | Return Value of strncpy used directly in a conditional expression. |
| test.c:54:6:54:34 | ! ... | Return Value of strncpy used in a logical operation. |
| test.c:58:11:58:39 | ! ... | Return Value of strncpy used in a logical operation. |
| test.c:60:11:60:37 | ... && ... | Return Value of strcpy used in a logical operation. |
| test.c:62:11:62:37 | ... == ... | Return Value of strcpy used in a logical operation. |
| test.c:64:11:64:37 | ... != ... | Return Value of strcpy used in a logical operation. |
| test.cpp:75:9:75:14 | call to strcpy | Return Value of strcpy used directly in a conditional expression. |
| test.cpp:79:9:79:31 | ! ... | Return Value of strcpy used in a logical operation. |
| test.cpp:79:10:79:15 | call to strcpy | Return Value of strcpy used as boolean. |
| test.cpp:83:9:83:35 | ... == ... | Return Value of strcpy used in a conditional. |
| test.cpp:87:9:87:48 | ... && ... | Return Value of strcpy used in a conditional. |
| test.cpp:83:9:83:35 | ... == ... | Return Value of strcpy used in a logical operation. |
| test.cpp:87:9:87:48 | ... && ... | Return Value of strcpy used in a logical operation. |
| test.cpp:87:27:87:32 | call to strcpy | Return Value of strcpy used as boolean. |
| test.cpp:91:9:91:37 | call to wcscpy | Return Value of wcscpy used in a conditional. |
| test.cpp:95:9:95:14 | call to wcscpy | Return Value of wcscpy used in a conditional. |
| test.cpp:99:9:99:15 | call to _mbscpy | Return Value of _mbscpy used in a conditional. |
| test.cpp:103:9:103:15 | call to strncpy | Return Value of strncpy used in a conditional. |
| test.cpp:107:9:107:15 | call to wcsncpy | Return Value of wcsncpy used in a conditional. |
| test.cpp:111:9:111:16 | call to _mbsncpy | Return Value of _mbsncpy used in a conditional. |
| test.cpp:115:9:115:18 | call to _strncpy_l | Return Value of _strncpy_l used in a conditional. |
| test.cpp:119:9:119:18 | call to _wcsncpy_l | Return Value of _wcsncpy_l used in a conditional. |
| test.cpp:123:9:123:18 | call to _mbsncpy_l | Return Value of _mbsncpy_l used in a conditional. |
| test.cpp:127:6:127:34 | ! ... | Return Value of strncpy used in a conditional. |
| test.cpp:91:9:91:37 | call to wcscpy | Return Value of wcscpy used directly in a conditional expression. |
| test.cpp:95:9:95:14 | call to wcscpy | Return Value of wcscpy used directly in a conditional expression. |
| test.cpp:99:9:99:15 | call to _mbscpy | Return Value of _mbscpy used directly in a conditional expression. |
| test.cpp:103:9:103:15 | call to strncpy | Return Value of strncpy used directly in a conditional expression. |
| test.cpp:107:9:107:15 | call to wcsncpy | Return Value of wcsncpy used directly in a conditional expression. |
| test.cpp:111:9:111:16 | call to _mbsncpy | Return Value of _mbsncpy used directly in a conditional expression. |
| test.cpp:115:9:115:18 | call to _strncpy_l | Return Value of _strncpy_l used directly in a conditional expression. |
| test.cpp:119:9:119:18 | call to _wcsncpy_l | Return Value of _wcsncpy_l used directly in a conditional expression. |
| test.cpp:123:9:123:18 | call to _mbsncpy_l | Return Value of _mbsncpy_l used directly in a conditional expression. |
| test.cpp:127:6:127:34 | ! ... | Return Value of strncpy used in a logical operation. |
| test.cpp:127:7:127:13 | call to strncpy | Return Value of strncpy used as boolean. |
| test.cpp:131:11:131:17 | call to strncpy | Return Value of strncpy used as boolean. |
| test.cpp:133:16:133:44 | ! ... | Return Value of strncpy used in a logical operation. |
| test.cpp:133:17:133:23 | call to strncpy | Return Value of strncpy used as boolean. |
| test.cpp:135:11:135:16 | call to strcpy | Return Value of strcpy used as boolean. |
| test.cpp:135:11:135:37 | ... && ... | Return Value of strcpy used in a logical operation. |
| test.cpp:137:11:137:37 | ... == ... | Return Value of strcpy used in a logical operation. |
| test.cpp:139:11:139:37 | ... != ... | Return Value of strcpy used in a logical operation. |

View File

@@ -29,6 +29,7 @@ void PositiveCases()
{
char szbuf1[100];
char szbuf2[100];
int result;
if (strcpy(szbuf1, "test")) // Bug, direct usage
{
@@ -53,6 +54,14 @@ void PositiveCases()
if (!strncpy(szbuf1, "test", 100)) // Bug
{
}
result = !strncpy(szbuf1, "test", 100);
result = strcpy(szbuf1, "test") && 1;
result = strcpy(szbuf1, "test") == 0;
result = strcpy(szbuf1, "test") != 0;
}
void NegativeCases()

View File

@@ -129,6 +129,15 @@ void PositiveCases()
}
bool b = strncpy(szbuf1, "test", 100);
bool result = !strncpy(szbuf1, "test", 100);
result = strcpy(szbuf1, "test") && 1;
result = strcpy(szbuf1, "test") == 0;
result = strcpy(szbuf1, "test") != 0;
}
void NegativeCases()