aboutsummaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorrouslan@chromium.org <rouslan@chromium.org@38ededc0-08b8-5190-f2ac-b31f878777ad>2014-05-14 11:15:17 +0000
committerrouslan@chromium.org <rouslan@chromium.org@38ededc0-08b8-5190-f2ac-b31f878777ad>2014-05-14 11:15:17 +0000
commitbc1209bf341b6bf948d06727dcb71accc166e98d (patch)
tree7389f683e8ce9961d0843dfa9d5d2e48f980a1f5 /cpp/src
parentc7411fbc5c6df73a0fada83b560a906503347fe3 (diff)
downloadsrc-bc1209bf341b6bf948d06727dcb71accc166e98d.tar.gz
Fix a use after free in Chromium tests in Debug mode with clang.
git-svn-id: http://libaddressinput.googlecode.com/svn/trunk@210 38ededc0-08b8-5190-f2ac-b31f878777ad
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/metadata_loader.cc15
1 files changed, 13 insertions, 2 deletions
diff --git a/cpp/src/metadata_loader.cc b/cpp/src/metadata_loader.cc
index 50e6de3..2831c17 100644
--- a/cpp/src/metadata_loader.cc
+++ b/cpp/src/metadata_loader.cc
@@ -97,9 +97,20 @@ void MetadataLoader::RuleHierarchy::Retrieve(const Retriever& retriever) {
if (pending_.empty()) {
loaded_(true, lookup_key_, *this);
} else {
+ // When the final pending rule has been retrieved, the retrieved_ callback
+ // will finish by calling the loaded_ callback, which when finished will
+ // delete this RuleHierarchy object. So after the final call to
+ // retriever.Retrieve() no attributes of this object can be accessed (as the
+ // object then no longer exists), and the condition statement of the loop
+ // must therefore not use the otherwise obvious it != pending_.end() but
+ // instead test a local variable that isn't affected by the object being
+ // deleted.
+ bool done = false;
for (std::set<std::string>::const_iterator
- it = pending_.begin(); it != pending_.end(); ) {
- retriever.Retrieve(*it++, *retrieved_);
+ it = pending_.begin(); !done; ) {
+ const std::string& key = *it++;
+ done = it == pending_.end();
+ retriever.Retrieve(key, *retrieved_);
}
}
}