Fix memory leak 66/246266/2
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 27 Oct 2020 10:28:35 +0000 (19:28 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 27 Oct 2020 11:07:21 +0000 (20:07 +0900)
Change-Id: I64962cb9633c6f9d774723c443e402e4fcf82d57
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
include/bundle_cpp.h
src/bundle_cpp.cc
src/bundle_cpp_implementation.h

index a02c439..3b71501 100644 (file)
@@ -65,8 +65,9 @@ class EXPORT_API Bundle final {
      * @since_tizen 5.5
      * @param[in] handle The handle for type bundle_keyval_t
      * @param[in] name The key string
+     * @param[in] own True if this object owns the handle
      */
-    KeyInfo(const bundle_keyval_t* handle,  std::string name);
+    KeyInfo(const bundle_keyval_t* handle,  std::string name, bool own = false);
 
     /**
      * @brief Destructor.
index 617aecc..4cc9808 100644 (file)
@@ -82,18 +82,23 @@ Bundle::Bundle(const Bundle& b)
     throw std::bad_alloc();
 }
 
-Bundle::KeyInfo::KeyInfo(const bundle_keyval_t* handle, std::string name)
-  : impl_(new Impl(this, handle, std::move(name))) {
+Bundle::KeyInfo::KeyInfo(const bundle_keyval_t* handle, std::string name,
+                         bool own)
+  : impl_(new Impl(this, handle, std::move(name), own)) {
 }
 
 Bundle::KeyInfo::~KeyInfo() {
+  if (impl_ && impl_->handle_ && impl_->own_)
+    bundle_keyval_free(const_cast<bundle_keyval_t*>(impl_->handle_));
 }
 
 Bundle::KeyInfo::Impl::~Impl() = default;
+
 Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent,
                             const bundle_keyval_t* handle,
-                            std::string name)
-  : handle_(handle), name_(name), parent_(parent) {
+                            std::string name,
+                            bool own)
+  : handle_(handle), name_(name), parent_(parent), own_(own) {
 }
 
 Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent) : parent_(parent) {
@@ -109,28 +114,35 @@ Bundle::KeyInfo::KeyInfo(const KeyInfo& k)
 
 Bundle::KeyInfo& Bundle::KeyInfo::operator = (const Bundle::KeyInfo& k) {
   if (this != &k) {
+    if (impl_->handle_ && impl_->own_)
+      bundle_keyval_free(const_cast<bundle_keyval_t*>(impl_->handle_));
+
     impl_->handle_ = bundle_keyval_dup(k.impl_->handle_);
     impl_->name_ = k.impl_->name_;
     if (impl_->handle_ == nullptr)
       throw std::bad_alloc();
+
+    impl_->own_ = true;
   }
   return *this;
 }
 
 Bundle::KeyInfo::KeyInfo(Bundle::KeyInfo&& k) noexcept {
-  impl_ = std::unique_ptr<Impl>(new Impl(this));
-  impl_->handle_ = k.impl_->handle_;
-  impl_->name_ = k.impl_->name_;
-  k.impl_->handle_ = nullptr;
-  k.impl_->name_ = "";
+  impl_ = std::move(k.impl_);
+  impl_->parent_ = this;
 }
 
 Bundle::KeyInfo& Bundle::KeyInfo::operator = (Bundle::KeyInfo&& k) noexcept {
   if (this != &k) {
+    if (impl_->handle_ && impl_->own_)
+      bundle_keyval_free(const_cast<bundle_keyval_t*>(impl_->handle_));
+
     impl_->handle_ = k.impl_->handle_;
     impl_->name_ = k.impl_->name_;
+    impl_->own_ = k.impl_->own_;
     k.impl_->handle_ = nullptr;
     k.impl_->name_ = "";
+    k.impl_->own_ = false;
   }
   return *this;
 }
@@ -177,7 +189,9 @@ Bundle& Bundle::operator = (Bundle&& b) noexcept {
     impl_->handle_ = b.impl_->handle_;
     b.impl_->handle_ = nullptr;
     impl_->own_ = b.impl_->own_;
+    b.impl_->own_ = false;
     impl_->copy_ = b.impl_->copy_;
+    b.impl_->copy_ = false;
   }
   return *this;
 }
@@ -192,7 +206,7 @@ std::vector<Bundle::KeyInfo> Bundle::GetKeys() {
   bundle_foreach(impl_->handle_, [](const char *key, const int type,
       const bundle_keyval_t *kv, void *user_data) {
         auto* v = static_cast<std::vector<KeyInfo>*>(user_data);
-        v->emplace_back(kv, key);
+        v->emplace_back(kv, key, false);
       }, &v);
 
   return v;
index 907b9de..bf7c38c 100644 (file)
@@ -31,16 +31,17 @@ class Bundle::KeyInfo::Impl {
 
  private:
   Impl(Bundle::KeyInfo* parent, const bundle_keyval_t* handle,
-       std::string name);
+       std::string name, bool own);
   explicit Impl(Bundle::KeyInfo* parent);
 
  private:
   friend class Bundle::KeyInfo;
 
  private:
-  const bundle_keyval_t* handle_;
+  const bundle_keyval_t* handle_ = nullptr;
   std::string name_;
   Bundle::KeyInfo* parent_;
+  bool own_ = false;
 };
 
 class Bundle::Impl {