[Content] Prevent crash for null-uuid listener native call
authorPiotr Kosko <p.kosko@samsung.com>
Wed, 16 Sep 2015 12:14:06 +0000 (14:14 +0200)
committerHyunjin Park <hj.na.park@samsung.com>
Thu, 17 Sep 2015 07:39:03 +0000 (16:39 +0900)
[Feature] Added check for not-null-uuid. If null listener native call is ignored.
  Changed way of holding listener data to properly free alocated memory.

[Verification] Code compiles without errors.
  Checked listener  calls when creating new directory via MTP.
  TCT passrate is didn't change.

Change-Id: I3860f731cf84f11ae4e7a6ad2098f94f88662b63
Signed-off-by: Piotr Kosko <p.kosko@samsung.com>
src/content/content_instance.cc
src/content/content_instance.h

index 12a384aa7ab8209d4241f5c8a2ef8d1276cf838b..06630282ea3884de2d38854d8c42d14b4673bc76 100755 (executable)
@@ -36,7 +36,9 @@ namespace content {
 using common::tools::ReportSuccess;
 using common::tools::ReportError;
 
-ContentInstance::ContentInstance() : noti_handle_(nullptr) {
+ContentInstance::ContentInstance() :
+    noti_handle_(nullptr),
+    listener_data_(nullptr) {
   using std::placeholders::_1;
   using std::placeholders::_2;
 
@@ -78,6 +80,10 @@ ContentInstance::~ContentInstance() {
     media_content_unset_db_updated_cb_v2(noti_handle_);
     noti_handle_ = nullptr;
   }
+  if (listener_data_) {
+    delete listener_data_;
+    listener_data_ = nullptr;
+  }
 }
 
 static gboolean CompletedCallback(const std::shared_ptr<ReplyCallbackData>& user_data) {
@@ -214,9 +220,13 @@ static void changedContentCallback(media_content_error_e error,
 
   ReplyCallbackData* cbData = static_cast<ReplyCallbackData*>(user_data);
 
+  if (!uuid) {
+    LOGGER(ERROR) << "Provided uuid is NULL, ignoring";
+    return;
+  }
+
   if (error != MEDIA_CONTENT_ERROR_NONE) {
     LOGGER(ERROR) << "Media content changed callback error: " << error;
-    delete cbData;
     return;
   }
 
@@ -270,7 +280,6 @@ static void changedContentCallback(media_content_error_e error,
     }
   } else {
     LOGGER(DEBUG) << "Media item is not a file and not directory, skipping.";
-    delete cbData;
     return;
   }
 
@@ -411,19 +420,21 @@ void ContentInstance::ContentManagerSetchangelistener(const picojson::value& arg
   LoggerD("entered");
   CHECK_EXIST(args, "listenerId", out)
 
-  ReplyCallbackData* cbData = new ReplyCallbackData();
+  if (!listener_data_) {
+    listener_data_ = new ReplyCallbackData();
+  }
 
-  cbData->instance = this;
-  cbData->args = args;
+  listener_data_->instance = this;
+  listener_data_->args = args;
   if (ContentManager::getInstance()->isConnected()) {
-    cbData->cbType = ContentManagerSetchangelistenerCallback;
+    listener_data_->cbType = ContentManagerSetchangelistenerCallback;
   } else {
-    cbData->cbType = ContentManagerErrorCallback;
+    listener_data_->cbType = ContentManagerErrorCallback;
   }
 
   if (ContentManager::getInstance()->setChangeListener(&noti_handle_,
                                                        changedContentCallback,
-                                                       static_cast<void*>(cbData)).IsError()) {
+                                                       static_cast<void*>(listener_data_)).IsError()) {
     ReportError(common::PlatformResult(common::ErrorCode::UNKNOWN_ERR, "The callback did not register properly"), &out);
   }
 }
index 2a3b6b37a884fc7b6e47e31ffb13e672a79d8b74..0025d2bbf9951cf792dd017fdec68ff084e88368 100755 (executable)
@@ -41,6 +41,22 @@ enum ContentCallbacks {
   ContentManagerErrorCallback
 };
 
+class ContentInstance;
+
+typedef struct _ReplyCallbackData {
+  _ReplyCallbackData()
+      : instance(nullptr),
+        cbType(ContentManagerFindCallback),
+        callbackId(-1.0),
+        isSuccess(common::ErrorCode::NO_ERROR) {
+  }
+  ContentInstance* instance;
+  ContentCallbacks cbType;
+  double callbackId;
+  picojson::value args;
+  picojson::value result;
+  common::PlatformResult isSuccess;
+} ReplyCallbackData;
 
 class ContentInstance : public common::ParsedInstance {
  public:
@@ -76,23 +92,9 @@ class ContentInstance : public common::ParsedInstance {
   void PlaylistGetNumberOfTracks(const picojson::value& args, picojson::object& out);
 
   media_content_noti_h noti_handle_;
+  ReplyCallbackData* listener_data_;
 };
 
-typedef struct _ReplyCallbackData {
-  _ReplyCallbackData()
-      : instance(nullptr),
-        cbType(ContentManagerFindCallback),
-        callbackId(-1.0),
-        isSuccess(common::ErrorCode::NO_ERROR) {
-  }
-  ContentInstance* instance;
-  ContentCallbacks cbType;
-  double callbackId;
-  picojson::value args;
-  picojson::value result;
-  common::PlatformResult isSuccess;
-} ReplyCallbackData;
-
 
 } // namespace content
 } // namespace extension