Skip to content

Commit 23ba7dc

Browse files
authored
Merge pull request github#6141 from ihsinme/ihsinme-patch-276
CPP: Add a query to find incorrectly used exceptions. 2
2 parents 7fb1e15 + 2d5a263 commit 23ba7dc

File tree

6 files changed

+130
-0
lines changed

6 files changed

+130
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
...
2+
throw ("my exception!",546); // BAD
3+
...
4+
throw errorFunc("my exception!",546); // GOOD
5+
...
6+
std::runtime_error("msg error"); // BAD
7+
...
8+
throw std::runtime_error("msg error"); // GOOD
9+
...
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>Finding places for the dangerous use of exceptions.</p>
7+
8+
</overview>
9+
10+
<example>
11+
<p>The following example demonstrates erroneous and fixed methods for using exceptions.</p>
12+
<sample src="FindIncorrectlyUsedExceptions.cpp" />
13+
14+
</example>
15+
<references>
16+
17+
<li>
18+
CERT CPP Coding Standard:
19+
<a href="https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL57-CPP.+Do+not+let+exceptions+escape+from+destructors+or+deallocation+functions">DCL57-CPP. Do not let exceptions escape from destructors or deallocation functions</a>.
20+
</li>
21+
22+
</references>
23+
</qhelp>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* @name Operator Find Incorrectly Used Exceptions
3+
* @description --Finding places for the dangerous use of exceptions.
4+
* @kind problem
5+
* @id cpp/operator-find-incorrectly-used-exceptions
6+
* @problem.severity warning
7+
* @precision medium
8+
* @tags correctness
9+
* security
10+
* external/cwe/cwe-703
11+
* external/cwe/cwe-248
12+
* external/cwe/cwe-390
13+
*/
14+
15+
import cpp
16+
17+
from FunctionCall fc, string msg
18+
where
19+
exists(ThrowExpr texp |
20+
texp.getEnclosingFunction() = fc.getTarget() and
21+
(
22+
fc.getTarget().hasGlobalOrStdName("DllMain") and
23+
not exists(TryStmt ts |
24+
texp.getEnclosingStmt().getParentStmt*() = ts.getStmt() and
25+
not ts.getACatchClause().isEmpty()
26+
) and
27+
msg = "DllMain contains an exeption not wrapped in a try..catch block."
28+
or
29+
texp.getExpr().isParenthesised() and
30+
texp.getExpr().(CommaExpr).getLeftOperand().isConstant() and
31+
texp.getExpr().(CommaExpr).getRightOperand().isConstant() and
32+
msg = "There is an exception in the function that requires your attention."
33+
)
34+
)
35+
or
36+
fc.getTarget() instanceof Constructor and
37+
(
38+
fc.getTargetType().(Class).getABaseClass+().hasGlobalOrStdName("exception") or
39+
fc.getTargetType().(Class).getABaseClass+().hasGlobalOrStdName("CException")
40+
) and
41+
not fc.isInMacroExpansion() and
42+
not exists(ThrowExpr texp | fc.getEnclosingStmt() = texp.getEnclosingStmt()) and
43+
not exists(FunctionCall fctmp | fctmp.getAnArgument() = fc) and
44+
not fc instanceof ConstructorDirectInit and
45+
not fc.getEnclosingStmt() instanceof DeclStmt and
46+
not fc instanceof ConstructorDelegationInit and
47+
not fc.getParent() instanceof Initializer and
48+
not fc.getParent() instanceof AllocationExpr and
49+
msg = "This object does not generate an exception."
50+
select fc, msg
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| test.cpp:35:3:35:33 | call to runtime_error | This object does not generate an exception. |
2+
| test.cpp:41:3:41:11 | call to funcTest1 | There is an exception in the function that requires your attention. |
3+
| test.cpp:42:3:42:9 | call to DllMain | DllMain contains an exeption not wrapped in a try..catch block. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
experimental/Security/CWE/CWE-703/FindIncorrectlyUsedExceptions.ql
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
namespace std
2+
{
3+
class exception {
4+
};
5+
6+
class runtime_error : public exception {
7+
public:
8+
runtime_error(const char *msg);
9+
};
10+
}
11+
12+
typedef unsigned int size_t;
13+
void clean();
14+
15+
16+
void funcTest1()
17+
{
18+
throw ("my exception!",546); // BAD
19+
}
20+
21+
void DllMain()
22+
{
23+
try { throw "my exception!"; } // BAD
24+
catch (...) { }
25+
}
26+
27+
void funcTest2()
28+
{
29+
try { throw "my exception!"; } // GOOD
30+
catch (...) { clean(); }
31+
}
32+
33+
void funcTest3()
34+
{
35+
std::runtime_error("msg error"); // BAD
36+
throw std::runtime_error("msg error"); // GOOD
37+
}
38+
39+
void TestFunc()
40+
{
41+
funcTest1();
42+
DllMain();
43+
funcTest2();
44+
}

0 commit comments

Comments
 (0)