Browse Source

[2426] Fix leak of GenericImpl object when an exception is thrown

Mukund Sivaraman 11 years ago
parent
commit
659fb323f0
2 changed files with 16 additions and 7 deletions
  1. 15 6
      src/lib/dns/rdata.cc
  2. 1 1
      src/lib/dns/rdata.h

+ 15 - 6
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<GenericImpl> 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() {

+ 1 - 1
src/lib/dns/rdata.h

@@ -378,7 +378,7 @@ public:
     //@}
 
 private:
-    void constructFromLexer(MasterLexer& lexer);
+    GenericImpl* constructFromLexer(MasterLexer& lexer);
 
     GenericImpl* impl_;
 };