Skip to content

Commit 640de0c

Browse files
authored
Merge pull request #304 from geoffw0/resource-released
CPP: Fix false positive in AV Rule 79.ql
2 parents 1f390f2 + dda7069 commit 640de0c

File tree

5 files changed

+67
-1
lines changed

5 files changed

+67
-1
lines changed

change-notes/1.19/analysis-cpp.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
| **Query** | **Expected impact** | **Change** |
1717
|----------------------------|------------------------|------------------------------------------------------------------|
18-
| Resource not released in destructor | Fewer false positive results | Placement new is now excluded from the query. |
18+
| Resource not released in destructor | Fewer false positive results | Placement new is now excluded from the query. Also fixed an issue where false positives could occur if the destructor body was not in the snapshot. |
1919
| Missing return statement (`cpp/missing-return`) | Visible by default | The precision of this query has been increased from 'medium' to 'high', which makes it visible by default in LGTM. It was 'medium' in release 1.17 and 1.18 because it had false positives due to an extractor bug that was fixed in 1.18. |
2020
| Call to memory access function may overflow buffer | More correct results | Array indexing with a negative index is now detected by this query. |
2121
| Suspicious add with sizeof | Fewer false positive results | Arithmetic with void pointers (where allowed) is now excluded from this query. |

cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,17 @@ predicate unreleasedResource(Resource r, Expr acquire, File f, int acquireLine)
159159
)
160160
and f = acquire.getFile()
161161
and acquireLine = acquire.getLocation().getStartLine()
162+
163+
// check that any destructor for this class has a block; if it doesn't,
164+
// we must be missing information.
165+
and forall(Class c, Destructor d |
166+
r.getDeclaringType().isConstructedFrom*(c) and
167+
d = c.getAMember() and
168+
not d.isCompilerGenerated() and
169+
not d.isDefaulted() and
170+
not d.isDeleted() |
171+
exists(d.getBlock())
172+
)
162173
}
163174

164175
predicate freedInSameMethod(Resource r, Expr acquire) {

cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,5 @@
1717
| Variants.cpp:65:3:65:17 | ... = ... | Resource a is acquired by class MyClass6 but not released anywhere in this class. |
1818
| Variants.cpp:66:3:66:36 | ... = ... | Resource b is acquired by class MyClass6 but not released anywhere in this class. |
1919
| Variants.cpp:67:3:67:41 | ... = ... | Resource c is acquired by class MyClass6 but not released anywhere in this class. |
20+
| Wrapped.cpp:46:3:46:22 | ... = ... | Resource ptr2 is acquired by class Wrapped2 but not released anywhere in this class. |
21+
| Wrapped.cpp:59:3:59:22 | ... = ... | Resource ptr4 is acquired by class Wrapped2 but not released anywhere in this class. |

cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/NoDestructor.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,25 @@ class MyClass7 : public MyClass7Base
6666
n = new MyNumber(200); // GOOD: deleted in base class
6767
}
6868
};
69+
70+
template<class T>
71+
class TemplateWithDestructor
72+
{
73+
public:
74+
TemplateWithDestructor(int len) {
75+
ptr = new char[len]; // GOOD
76+
}
77+
78+
~TemplateWithDestructor()
79+
{
80+
delete [] ptr;
81+
}
82+
83+
private:
84+
char *ptr;
85+
};
86+
87+
void test() {
88+
TemplateWithDestructor<int *> *t_ptr = new TemplateWithDestructor<int *>(10);
89+
//delete t_ptr; --- destructor never used
90+
}

cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/Wrapped.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,34 @@ class Wrapped
3737
private:
3838
char *ptr1, *ptr2, *ptr3;
3939
};
40+
41+
class Wrapped2
42+
{
43+
public:
44+
Wrapped2(int len) {
45+
ptr1 = new char[len]; // GOOD
46+
ptr2 = new char[len]; // BAD: not released in destructor
47+
48+
Init(len);
49+
}
50+
51+
~Wrapped2()
52+
{
53+
Shutdown();
54+
}
55+
56+
void Init(int len)
57+
{
58+
ptr3 = new char[len]; // GOOD
59+
ptr4 = new char[len]; // BAD: not released in destructor
60+
}
61+
62+
void Shutdown()
63+
{
64+
delete [] ptr1;
65+
delete [] ptr3;
66+
}
67+
68+
private:
69+
char *ptr1, *ptr2, *ptr3, *ptr4;
70+
};

0 commit comments

Comments
 (0)