Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
| test.cpp:2:3:2:7 | re-throw exception | As there is no current exception, this rethrow expression will terminate the program. |
| test.cpp:6:3:6:7 | re-throw exception | As there is no current exception, this rethrow expression will terminate the program. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
query: Best Practices/Exceptions/AccidentalRethrow.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
void rethrowOutsideCatch() {
throw; // $ Alert
}

void helperRethrow() {
throw; // $ Alert
}

void safeRethrowInCatch() {
try {
} catch (...) {
throw;
}
}

// The function name matches "%exception%", so a rethrow here is assumed to
// be intentional even though it is lexically and dynamically outside any
// catch block.
void rethrowException() {
throw;
}

// Not lexically inside a catch block, but every call to this function is
// made from within a catch block, so the rethrow is assumed to be safe.
void calledFromCatch() {
throw;
}

void triggersFromCatch() {
try {
} catch (...) {
calledFromCatch();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
| test.cpp:12:32:12:34 | { ... } | This should catch a DerivedException by (const) reference rather than by value. |
| test.cpp:16:29:16:31 | { ... } | This should catch a BaseException by (const) reference rather than by value. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
query: Best Practices/Exceptions/CatchingByValue.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
class BaseException {
public:
virtual ~BaseException() {}
};

class DerivedException : public BaseException {
};

void catchByValueDerived() {
try {
throw DerivedException();
} catch (DerivedException e) { } // $ Alert

try {
throw BaseException();
} catch (BaseException e) { } // $ Alert

try {
throw DerivedException();
} catch (DerivedException &e) { }

try {
throw DerivedException();
} catch (BaseException &e) { }

try {
throw new BaseException();
} catch (BaseException *e) { }

try {
throw DerivedException();
} catch (...) { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
| test.cpp:21:28:21:30 | { ... } | This catch block does not free the caught exception, thereby leaking memory. |
| test.cpp:27:31:27:51 | { ... } | This catch block does not free the caught exception, thereby leaking memory. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
query: Best Practices/Exceptions/LeakyCatch.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// --- definitions ---

class MyException {
public:
void ReportError() {}
void Delete() {}
};

class OtherException {
public:
void ReportError() {}
};

void handle(OtherException *e) {}

// --- test cases ---

void leakyCatchEmpty() {
try {
// ...
} catch (MyException *e) { } // $ Alert
}

void leakyCatchNoDelete() {
try {
// ...
} catch (OtherException *e) { e->ReportError(); } // $ Alert
}

void catchWithDeleteMethodCall() {
try {
// ...
} catch (MyException *e) {
e->ReportError();
e->Delete();
}
}

void catchWithOperatorDelete() {
try {
// ...
} catch (MyException *e) {
e->ReportError();
delete e;
}
}

void catchWithPassToFunction() {
try {
// ...
} catch (OtherException *e) {
handle(e);
}
}

void catchByValueNotPointer() {
try {
// ...
} catch (MyException e) { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
| test.cpp:5:3:5:25 | throw ... | This should throw a MyException rather than a pointer to one. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
query: Best Practices/Exceptions/ThrowingPointers.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class MyException {
};

void throwsPointer1() {
throw new MyException(); // $ Alert
}

void throwsPointer2() {
MyException *e = new MyException();

throw e; // $ MISSING: Alert
}

void throwsByValue() {
throw MyException();
}

// Microsoft MFC's CException hierarchy is intended to be thrown (and
// caught) as a pointer, so it should not be flagged.
class CException {
};

class CMyFrameworkException : public CException {
};

void throwsFrameworkExceptionPointer() {
throw new CMyFrameworkException();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
| test.cpp:4:5:4:8 | call to init | Call to virtual function $@ which is overridden in $@. If you intend to statically call this virtual function, it should be qualified with Base::. | test.cpp:18:16:18:19 | init | init | test.cpp:38:8:38:11 | init | Derived |
| test.cpp:5:11:5:14 | call to init | Call to virtual function $@ which is overridden in $@. If you intend to statically call this virtual function, it should be qualified with Base::. | test.cpp:18:16:18:19 | init | init | test.cpp:38:8:38:11 | init | Derived |
| test.cpp:6:13:6:16 | call to init | Call to virtual function $@ which is overridden in $@. If you intend to statically call this virtual function, it should be qualified with Base::. | test.cpp:18:16:18:19 | init | init | test.cpp:38:8:38:11 | init | Derived |
| test.cpp:7:5:7:10 | call to helper | Call to function helper that calls virtual function $@ (overridden in $@). | test.cpp:18:16:18:19 | init | init | test.cpp:38:8:38:11 | init | Derived |
| test.cpp:14:5:14:11 | call to cleanup | Call to virtual function $@ which is overridden in $@. If you intend to statically call this virtual function, it should be qualified with Base::. | test.cpp:19:16:19:22 | cleanup | cleanup | test.cpp:39:8:39:14 | cleanup | Derived |
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
query: jsf/4.10 Classes/AV Rule 71.1.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
47 changes: 47 additions & 0 deletions cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 71.1/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
class Base {
public:
Base() {
init(); // $ Alert
this->init(); // $ Alert
(*this).init(); // $ Alert
helper(); // $ Alert (indirectly calls a virtual function)
Base::init(); // GOOD: explicitly qualified, so statically bound
notOverridden(); // GOOD: not overridden in any derived class
nonVirtual(); // GOOD: not virtual
}

~Base() {
cleanup(); // $ Alert
Base::cleanup(); // GOOD: explicitly qualified
}

virtual void init() {}
virtual void cleanup() {}
virtual void notOverridden() {}
void nonVirtual() {}

void helper() {
init();
}

void other() {
init(); // GOOD: not in a constructor or destructor
}
};

class Derived : public Base {
public:
Derived() {
init(); // GOOD: not overridden in a class derived from Derived
}

void init() override {}
void cleanup() override {}
};

class Unrelated {
public:
Unrelated(Base &b) {
b.init(); // GOOD: not a call on `this`
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
| test.cpp:5:14:5:14 | f | Floating point variables should not be used as loop counters. |
| test.cpp:10:15:10:15 | d | Floating point variables should not be used as loop counters. |
| test.cpp:15:15:15:16 | ld | Floating point variables should not be used as loop counters. |
| test.cpp:36:13:36:13 | r | Floating point variables should not be used as loop counters. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
query: jsf/4.24 Control Flow Structures/AV Rule 197.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
void use(double);

void test()
{
for (float f = 0.0f; f < 1.0f; f = f + 0.1f) // $ Alert
{
use(f);
}

for (double d = 0.0; d < 10.0; d++) // $ Alert
{
use(d);
}

long double ld; // $ Alert
for (ld = 10.0; ld > 0.0; ld--)
{
use(ld);
}

for (double c = 0.0; c < 1.0; c += 0.1) // $ MISSING: Alert (compound assignment updates are not recognized)
{
use(c);
}

for (int i = 0; i < 10; i++) // GOOD: integer loop counter
{
use(i * 0.1);
}
}

typedef float real;

void test_typedef()
{
for (real r = 0.0f; r < 1.0f; r = r + 0.5f) // $ Alert
{
use(r);
}
}
Loading