diff options
author | rouslan@chromium.org <rouslan@chromium.org@38ededc0-08b8-5190-f2ac-b31f878777ad> | 2014-05-14 11:15:17 +0000 |
---|---|---|
committer | rouslan@chromium.org <rouslan@chromium.org@38ededc0-08b8-5190-f2ac-b31f878777ad> | 2014-05-14 11:15:17 +0000 |
commit | bc1209bf341b6bf948d06727dcb71accc166e98d (patch) | |
tree | 7389f683e8ce9961d0843dfa9d5d2e48f980a1f5 /cpp/src | |
parent | c7411fbc5c6df73a0fada83b560a906503347fe3 (diff) | |
download | src-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.cc | 15 |
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_); } } } |