[NFC] Fix memory management problems 78/169978/4
authorPawel Wasowski <p.wasowski2@partner.samsung.com>
Mon, 12 Feb 2018 11:14:15 +0000 (12:14 +0100)
committerPiotr Kosko <p.kosko@samsung.com>
Fri, 23 Feb 2018 13:49:41 +0000 (14:49 +0100)
This commit prevents crashes, fixing 2 memory management problems:
1. user_data passed to nfc_tag_transceive was deleted twice
2. buffer argument of tagTransceiveCb was deleted inside the function;
   according to Native NFC API reference: "buffer will be automatically
   destroyed when the callback function returns. (Do not release buffer.)"

[Verification] NFCTag.transceive() function was tested in Chrome
               DevTools console and worked fine.

Change-Id: I509c368d817b6663373ba0614af73402f8ad47a6
Signed-off-by: Pawel Wasowski <p.wasowski2@partner.samsung.com>
src/nfc/nfc_adapter.cc
src/nfc/nfc_util.cc

index d29aa70fca9fd850405e7120037028de16fe376f..874fa6ef5966137c677cf931808c2a74cf79157e 100644 (file)
@@ -1133,8 +1133,6 @@ PlatformResult NFCAdapter::TagWriteNDEF(int tag_id, const picojson::value& args)
 
 static void tagTransceiveCb(nfc_error_e err, unsigned char* buffer, int buffer_size, void* data) {
   ScopeLogger();
-  std::unique_ptr<unsigned char> buffer_ptr(buffer);
-  buffer = nullptr;
 
   if (!data) {
     // no callback id - unable to report success, neither error
@@ -1161,7 +1159,10 @@ static void tagTransceiveCb(nfc_error_e err, unsigned char* buffer, int buffer_s
   picojson::value response = createEventSuccess(callback_id);
   picojson::object& response_obj = response.get<picojson::object>();
   tools::ReportSuccess(response_obj);
-  response_obj[JSON_DATA] = picojson::value(NFCUtil::FromUCharArray(buffer_ptr.get(), buffer_size));
+  /* buffer contains response to the sent message
+   * According to the native API reference, it must not be freed
+   */
+  response_obj[JSON_DATA] = picojson::value(NFCUtil::FromUCharArray(buffer, buffer_size));
 
   NFCAdapter::GetInstance()->RespondAsync(response.serialize().c_str());
 }
@@ -1188,17 +1189,17 @@ PlatformResult NFCAdapter::TagTransceive(int tag_id, const picojson::value& args
   const picojson::array& data_array =
       FromJson<picojson::array>(args.get<picojson::object>(), JSON_DATA);
 
-  unsigned char* buffer = NFCUtil::DoubleArrayToUCharArray(data_array);
+  // this buffer contains the message to be sent; it may be deleted just after nfc_tag_transceive
+  // call
+  std::unique_ptr<unsigned char[]> buffer(NFCUtil::DoubleArrayToUCharArray(data_array));
   double* callback_id_pointer = new double(callback_id);
 
-  int ret = nfc_tag_transceive(m_last_tag_handle, buffer, data_array.size(), tagTransceiveCb,
+  int ret = nfc_tag_transceive(m_last_tag_handle, buffer.get(), data_array.size(), tagTransceiveCb,
                                (void*)callback_id_pointer);
 
   if (NFC_ERROR_NONE != ret) {
     delete callback_id_pointer;
     callback_id_pointer = nullptr;
-    delete[] buffer;
-    buffer = nullptr;
 
     // for permission related error throw exception
     if (NFC_ERROR_SECURITY_RESTRICTED == ret || NFC_ERROR_PERMISSION_DENIED == ret) {
@@ -1215,10 +1216,6 @@ PlatformResult NFCAdapter::TagTransceive(int tag_id, const picojson::value& args
     picojson::value event = CreateEventError(callback_id, result);
     NFCAdapter::GetInstance()->RespondAsync(event.serialize().c_str());
   }
-  delete callback_id_pointer;
-  callback_id_pointer = nullptr;
-  delete[] buffer;
-  buffer = nullptr;
 
   return PlatformResult(ErrorCode::NO_ERROR);
 }
index 8a5928fe3e23320962a9eb3d600560e2c0b44382..fcfb13ee368004dc29ac3a5900de5d383af1d310 100644 (file)
@@ -336,7 +336,7 @@ unsigned char* NFCUtil::DoubleArrayToUCharArray(const picojson::array& array_in)
   ScopeLogger();
   unsigned char* result_array = new unsigned char[array_in.size()];
   for (std::size_t i = 0; i < array_in.size(); ++i) {
-    result_array[i] = (int) array_in.at(i).get<double>();
+    result_array[i] = (int)array_in.at(i).get<double>();
   }
   return result_array;
 }