diff options
| author | Tobias Markmann <tm@ayena.de> | 2014-08-15 13:33:59 (GMT) |
|---|---|---|
| committer | Swift Review <review@swift.im> | 2014-09-18 06:23:03 (GMT) |
| commit | dbdd30aa0d94c79742a602908890548030088bc9 (patch) | |
| tree | 1e80c718167538fabf39c340f2e4a4d43773910e | |
| parent | d33e0a18e51ce35b967398a7b6d22a26082de0e9 (diff) | |
| download | swift-contrib-dbdd30aa0d94c79742a602908890548030088bc9.zip swift-contrib-dbdd30aa0d94c79742a602908890548030088bc9.tar.bz2 | |
Only allocate BlockResponder and UnblockResponder once. Fixes ASAN
heap-used-after-free report.
Tested via ASAN, report gone after applying this change. It previously occured
during machine sleep/resume or logout/login.
Change-Id: I8af6a3c290457a4a98f94486a225f9dfb92ca885
License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details.
| -rw-r--r-- | Swiften/Client/ClientBlockListManager.cpp | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/Swiften/Client/ClientBlockListManager.cpp b/Swiften/Client/ClientBlockListManager.cpp index d446315..de43631 100644 --- a/Swiften/Client/ClientBlockListManager.cpp +++ b/Swiften/Client/ClientBlockListManager.cpp @@ -1,134 +1,138 @@ /* * Copyright (c) 2011 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include <Swiften/Client/ClientBlockListManager.h> #include <boost/bind.hpp> #include <boost/smart_ptr/make_shared.hpp> #include <cassert> #include <Swiften/Client/BlockListImpl.h> using namespace Swift; namespace { class BlockResponder : public SetResponder<BlockPayload> { public: BlockResponder(boost::shared_ptr<BlockListImpl> blockList, IQRouter* iqRouter) : SetResponder<BlockPayload>(iqRouter), blockList(blockList) { } virtual bool handleSetRequest(const JID& from, const JID&, const std::string& id, boost::shared_ptr<BlockPayload> payload) { if (getIQRouter()->isAccountJID(from)) { if (payload) { blockList->addItems(payload->getItems()); } sendResponse(from, id, boost::shared_ptr<BlockPayload>()); } else { sendError(from, id, ErrorPayload::NotAuthorized, ErrorPayload::Cancel); } return true; } private: boost::shared_ptr<BlockListImpl> blockList; }; class UnblockResponder : public SetResponder<UnblockPayload> { public: UnblockResponder(boost::shared_ptr<BlockListImpl> blockList, IQRouter* iqRouter) : SetResponder<UnblockPayload>(iqRouter), blockList(blockList) { } virtual bool handleSetRequest(const JID& from, const JID&, const std::string& id, boost::shared_ptr<UnblockPayload> payload) { if (getIQRouter()->isAccountJID(from)) { if (payload) { if (payload->getItems().empty()) { blockList->removeAllItems(); } else { blockList->removeItems(payload->getItems()); } } sendResponse(from, id, boost::shared_ptr<UnblockPayload>()); } else { sendError(from, id, ErrorPayload::NotAuthorized, ErrorPayload::Cancel); } return true; } private: boost::shared_ptr<BlockListImpl> blockList; }; } ClientBlockListManager::ClientBlockListManager(IQRouter* iqRouter) : iqRouter(iqRouter) { } ClientBlockListManager::~ClientBlockListManager() { if (blockList && blockList->getState() == BlockList::Available) { unblockResponder->stop(); blockResponder->stop(); } } boost::shared_ptr<BlockList> ClientBlockListManager::getBlockList() { if (!blockList) { blockList = boost::make_shared<BlockListImpl>(); blockList->setState(BlockList::Init); } return blockList; } boost::shared_ptr<BlockList> ClientBlockListManager::requestBlockList() { if (!blockList) { blockList = boost::make_shared<BlockListImpl>(); } blockList->setState(BlockList::Requesting); boost::shared_ptr<GenericRequest<BlockListPayload> > getRequest = boost::make_shared< GenericRequest<BlockListPayload> >(IQ::Get, JID(), boost::make_shared<BlockListPayload>(), iqRouter); getRequest->onResponse.connect(boost::bind(&ClientBlockListManager::handleBlockListReceived, this, _1, _2)); getRequest->send(); return blockList; } GenericRequest<BlockPayload>::ref ClientBlockListManager::createBlockJIDRequest(const JID& jid) { return createBlockJIDsRequest(std::vector<JID>(1, jid)); } GenericRequest<BlockPayload>::ref ClientBlockListManager::createBlockJIDsRequest(const std::vector<JID>& jids) { boost::shared_ptr<BlockPayload> payload = boost::make_shared<BlockPayload>(jids); return boost::make_shared< GenericRequest<BlockPayload> >(IQ::Set, JID(), payload, iqRouter); } GenericRequest<UnblockPayload>::ref ClientBlockListManager::createUnblockJIDRequest(const JID& jid) { return createUnblockJIDsRequest(std::vector<JID>(1, jid)); } GenericRequest<UnblockPayload>::ref ClientBlockListManager::createUnblockJIDsRequest(const std::vector<JID>& jids) { boost::shared_ptr<UnblockPayload> payload = boost::make_shared<UnblockPayload>(jids); return boost::make_shared< GenericRequest<UnblockPayload> >(IQ::Set, JID(), payload, iqRouter); } GenericRequest<UnblockPayload>::ref ClientBlockListManager::createUnblockAllRequest() { return createUnblockJIDsRequest(std::vector<JID>()); } void ClientBlockListManager::handleBlockListReceived(boost::shared_ptr<BlockListPayload> payload, ErrorPayload::ref error) { if (error || !payload) { blockList->setState(BlockList::Error); } else { blockList->setItems(payload->getItems()); blockList->setState(BlockList::Available); - blockResponder = boost::make_shared<BlockResponder>(blockList, iqRouter); - blockResponder->start(); - unblockResponder = boost::make_shared<UnblockResponder>(blockList, iqRouter); - unblockResponder->start(); + if (!blockResponder) { + blockResponder = boost::make_shared<BlockResponder>(blockList, iqRouter); + blockResponder->start(); + } + if (!unblockResponder) { + unblockResponder = boost::make_shared<UnblockResponder>(blockList, iqRouter); + unblockResponder->start(); + } } } |
Swift