Parcourir la source

[4025] Incorrect use of temporary object fixed in Exception::what()

Tomek Mrugalski il y a 9 ans
Parent
commit
f3f4b5a886
2 fichiers modifiés avec 30 ajouts et 14 suppressions
  1. 19 10
      src/lib/exceptions/exceptions.cc
  2. 11 4
      src/lib/exceptions/exceptions.h

+ 19 - 10
src/lib/exceptions/exceptions.cc

@@ -13,13 +13,27 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <string>
-
+#include <sstream>
 #include <exceptions/exceptions.h>
 
 using isc::Exception;
 
 namespace isc {
 
+Exception::Exception(const char* file, size_t line, const char* what)
+: file_(file), line_(line), what_(what) {
+    std::stringstream location;
+    location << what_ << "[" << file_ << ":" << line_ << "]";
+    verbose_what_ = location.str();
+}
+
+Exception::Exception(const char* file, size_t line, const std::string& what)
+    : file_(file), line_(line), what_(what) {
+    std::stringstream location;
+    location << what_ << "[" << file_ << ":" << line_ << "]";
+    verbose_what_ = location.str();
+}
+
 const char*
 Exception::what() const throw() {
     return (what(false));
@@ -28,25 +42,20 @@ Exception::what() const throw() {
 const char*
 Exception::what(bool verbose) const throw() {
 
-    const char* whatstr = "isc::Exception";
-
-    // XXX: Even though it's very unlikely that c_str() throws an exception,
+    // Even though it's very unlikely that c_str() throws an exception,
     // it's still not 100% guaranteed.  To meet the exception specification
     // of this function, we catch any unexpected exception and fall back to
     // the pre-defined constant.
     try {
         if (verbose) {
-            static std::stringstream location;
-            location.str("");
-            location << what_ << "[" << file_ << ":" << line_ << "]";
-            whatstr = location.str().c_str();
+            return (verbose_what_.c_str());
         } else {
-            whatstr = what_.c_str();
+            return (what_.c_str());
         }
     } catch (...) {
         // no exception handling is necessary.  just have to catch exceptions.
     }
-    return (whatstr);
+    return ("isc::Exception");
 }
 
 }

+ 11 - 4
src/lib/exceptions/exceptions.h

@@ -40,8 +40,7 @@ public:
     /// @param file the file name where the exception was thrown.
     /// @param line the line in \a file where the exception was thrown.
     /// @param what a description (type) of the exception.
-    Exception(const char* file, size_t line, const char* what) :
-        file_(file), line_(line), what_(what) {}
+    Exception(const char* file, size_t line, const char* what);
 
     /// \brief Constructor for a given type for exceptions with file name and
     /// file line number.
@@ -49,8 +48,7 @@ public:
     /// @param file the file name where the exception was thrown.
     /// @param line the line in \a file where the exception was thrown.
     /// @param what a description (type) of the exception.
-    Exception(const char* file, size_t line, const std::string& what) :
-        file_(file), line_(line), what_(what) {}
+    Exception(const char* file, size_t line, const std::string& what);
 
     /// The destructor
     virtual ~Exception() throw() {}
@@ -106,9 +104,18 @@ public:
     //@}
 
 private:
+
+    /// Specifies the filename where this exception was raised
     const char* const file_;
+
+    /// Specifies the line number where this exception was raised
     size_t line_;
+
+    /// Specifies actual content of the exception
     const std::string what_;
+
+    /// Specifies actual context of the exception (with file:line added)
+    std::string verbose_what_;
 };
 
 /// \brief A generic exception that is thrown if a parameter given