Skip to content

Commit f97b8ad

Browse files
authored
Merge pull request github#5961 from MathiasVP/fix-FPs-in-incorrect-allocation-error-handling
C++: Exclude custom `operator new` from `cpp/incorrect-allocation-error-handling`
2 parents 66d284e + 175fdbb commit f97b8ad

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,39 @@ predicate exprMayThrow(Expr e) {
153153
)
154154
}
155155

156+
/** The `std::nothrow_t` class and its `bsl` variant. */
157+
class NoThrowType extends Struct {
158+
NoThrowType() { this.hasGlobalOrStdOrBslName("nothrow_t") }
159+
}
160+
156161
/** An allocator that might throw an exception. */
157162
class ThrowingAllocator extends Function {
158163
ThrowingAllocator() {
159164
exists(NewOrNewArrayExpr newExpr |
160165
newExpr.getAllocator() = this and
161-
functionMayThrow(this)
166+
// Exclude custom overloads of `operator new`.
167+
// What we really want here is to only include the functions that satisfy `functionMayThrow`, but
168+
// there seems to be examples where `throw()` isn't extracted (which causes false positives).
169+
//
170+
// As noted in the QLDoc for `Function.getAllocatorCall`:
171+
//
172+
// "As a rule of thumb, there will be an allocator call precisely when the type
173+
// being allocated has a custom `operator new`, or when an argument list appears
174+
// after the `new` keyword and before the name of the type being allocated.
175+
//
176+
// In particular note that uses of placement-new and nothrow-new will have an
177+
// allocator call."
178+
//
179+
// So we say an allocator might throw if:
180+
// 1. It doesn't have a body
181+
// 2. there isn't a parameter with type `nothrow_t`
182+
// 3. the allocator isn't marked with `throw()` or `noexcept`.
183+
not exists(this.getBlock()) and
184+
not exists(Parameter p | p = this.getAParameter() |
185+
p.getUnspecifiedType() instanceof NoThrowType
186+
) and
187+
not this.isNoExcept() and
188+
not this.isNoThrow()
162189
)
163190
}
164191
}

0 commit comments

Comments
 (0)