From: Mukund Sivaraman Date: Tue, 14 Jan 2014 12:10:46 +0000 (+0530) Subject: [2426] Fix leak of GenericImpl object when an exception is thrown X-Git-Tag: bind10-1.2.0beta1-release~43^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=659fb323f0b7fdd279cc1c36b0f5fe6526a0994e;p=thirdparty%2Fkea.git [2426] Fix leak of GenericImpl object when an exception is thrown --- diff --git a/src/lib/dns/rdata.cc b/src/lib/dns/rdata.cc index cdd03c155c..4f7962c162 100644 --- a/src/lib/dns/rdata.cc +++ b/src/lib/dns/rdata.cc @@ -212,7 +212,7 @@ Generic::Generic(isc::util::InputBuffer& buffer, size_t rdata_len) { impl_ = new GenericImpl(data); } -void +GenericImpl* Generic::constructFromLexer(MasterLexer& lexer) { const MasterToken& token = lexer.getNextToken(MasterToken::STRING); if (token.getString() != "\\#") { @@ -268,16 +268,23 @@ Generic::constructFromLexer(MasterLexer& lexer) { << data.size() << " vs. " << rdlen); } - impl_ = new GenericImpl(data); + return (new GenericImpl(data)); } -Generic::Generic(const std::string& rdata_string) { +Generic::Generic(const std::string& rdata_string) : + impl_(NULL) +{ + // We use auto_ptr here because if there is an exception in this + // constructor, the destructor is not called and there could be a + // leak of the GenericImpl that constructFromLexer() returns. + std::auto_ptr impl_ptr(NULL); + try { std::istringstream ss(rdata_string); MasterLexer lexer; lexer.pushSource(ss); - constructFromLexer(lexer); + impl_ptr.reset(constructFromLexer(lexer)); if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) { isc_throw(InvalidRdataText, "extra input text for unknown RDATA: " @@ -287,13 +294,15 @@ Generic::Generic(const std::string& rdata_string) { isc_throw(InvalidRdataText, "Failed to construct unknown RDATA " "from '" << rdata_string << "': " << ex.what()); } + + impl_ = impl_ptr.release(); } Generic::Generic(MasterLexer& lexer, const Name*, MasterLoader::Options, - MasterLoaderCallbacks&) + MasterLoaderCallbacks&) : + impl_(constructFromLexer(lexer)) { - constructFromLexer(lexer); } Generic::~Generic() { diff --git a/src/lib/dns/rdata.h b/src/lib/dns/rdata.h index 01ce7b3026..5468e2698c 100644 --- a/src/lib/dns/rdata.h +++ b/src/lib/dns/rdata.h @@ -378,7 +378,7 @@ public: //@} private: - void constructFromLexer(MasterLexer& lexer); + GenericImpl* constructFromLexer(MasterLexer& lexer); GenericImpl* impl_; };