-
Notifications
You must be signed in to change notification settings - Fork 1.8k
C++: Improve documentation for cpp/iterator-to-expired-container
#16367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C++: Improve documentation for cpp/iterator-to-expired-container
#16367
Conversation
QHelp previews: cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelpIterator to expired containerUsing an iterator owned by a container after the lifetime of the container has expired can lead to undefined behavior. This is because the iterator may be invalidated when the container is destroyed, and dereferencing an invalidated iterator is undefined behavior. These problems can be hard to spot due to C++'s complex rules for temporary object lifetimes and their extensions. RecommendationNever create an iterator to a temporary container when the iterator is expected to be used after the container's lifetime has expired. ExampleThe rules for lifetime extension ensures that the code in #include <vector>
std::vector<int> get_vector();
void use(int);
void lifetime_of_temp_extended() {
for(auto x : get_vector()) {
use(x); // GOOD: The lifetime of the vector returned by `get_vector()` is extended until the end of the loop.
}
}
// Writes the the values of `v` to an external log and returns it unchanged.
const std::vector<int>& log_and_return_argument(const std::vector<int>& v);
void lifetime_of_temp_not_extended() {
for(auto x : log_and_return_argument(get_vector())) {
use(x); // BAD: The lifetime of the vector returned by `get_vector()` is not extended, and the behavior is undefined.
}
}
To fix void fixed_lifetime_of_temp_not_extended() {
auto&& v = get_vector();
for(auto x : log_and_return_argument(v)) {
use(x); // GOOD: The lifetime of the container returned by `get_vector()` has been extended to the lifetime of `v`.
}
}
References
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes LGTM.
Is it worth getting a docs review for this small change? Come to think of it, did the .qhelp
for this new query get a full review at some point?
Hm, yeah. That may be a good idea. I'll add a ready-for-docs-review label to this PR
It did get a review when we merged it into experimental, yes: #15939 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM ✨
Two very minor suggestions from a Docs perspective.
cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp
Outdated
Show resolved
Hide resolved
cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelp
Outdated
Show resolved
Hide resolved
Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com>
Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com>
Thanks @mchammer01 🙇 All comments addressed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This PR does two things that should hopefully make the results from the new
cpp/iterator-to-expired-container
query easier to understand:Note that, because of the first fix, we only get half the number of alerts since we no longer include the call to begin in the alert message. Previously, we'd often get an alert on the same location with two alert messages such as:
call to begin
is called.call to end
is called.Other than the alert being wrong, it was also quite annoying to have two alerts on the same element explaining the same problem.