Fix ResultParcelable to handle null char pointer 77/259877/5
authorIlho Kim <ilho159.kim@samsung.com>
Wed, 16 Jun 2021 02:05:13 +0000 (11:05 +0900)
committerIlho Kim <ilho159.kim@samsung.com>
Thu, 24 Jun 2021 04:10:37 +0000 (13:10 +0900)
Change-Id: Ia0370f48c59fc9a096396750993276092fdbcb71
Signed-off-by: Ilho Kim <ilho159.kim@samsung.com>
src/common/database/query_handler.cc
src/common/database/query_handler.hh
src/common/parcel/result_parcelable.cc
src/common/parcel/result_parcelable.hh
src/common/request_handler/command_request_handler.cc
src/common/request_handler/query_request_handler.cc
src/common/request_handler/set_cert_request_handler.cc
src/common/request_handler/set_pkginfo_request_handler.cc
src/manager/pkginfo_manager.cc
test/unit_tests/test_parcel.cc

index a11f7cc..4bf6c36 100644 (file)
@@ -212,7 +212,7 @@ std::string QueryHandler::GetString() { return std::string(); }
 int QueryHandler::GetInt() { return 0; }
 int QueryHandler::GetRecordCount() { return 0; }
 
-std::vector<std::vector<std::string>> QueryHandler::GetResult() {
+std::vector<parcel::StrArgs> QueryHandler::GetResult() {
   return std::move(result_);
 }
 
@@ -268,9 +268,12 @@ int QueryHandler::Execute() {
 
       GList* tmp = list;
       for (int i = 0; i < row; ++i) {
-        std::vector<std::string> vt;
+        parcel::StrArgs vt;
         for (int j = 0; j < col; ++j) {
-          vt.emplace_back(reinterpret_cast<char *>(tmp->data));
+          if (!tmp->data)
+            vt.emplace_back(std::nullopt);
+          else
+            vt.emplace_back(reinterpret_cast<char *>(tmp->data));
           tmp = tmp->next;
         }
         result_.emplace_back(std::move(vt));
index 8f2e0de..c741467 100644 (file)
@@ -45,13 +45,13 @@ class EXPORT_API QueryHandler : public AbstractDBHandler{
   int GetInt();
   int GetRecordCount();
   int Execute() override;
-  std::vector<std::vector<std::string>> GetResult();
+  std::vector<parcel::StrArgs> GetResult();
 
  private:
   uid_t uid_;
   std::vector<std::string> query_;
   std::vector<parcel::QueryArgs> query_args_;
-  std::vector<std::vector<std::string>> result_;
+  std::vector<parcel::StrArgs> result_;
 };
 
 }  // namespace database
index ac91faa..578df9e 100644 (file)
@@ -25,10 +25,9 @@ namespace parcel {
 ResultParcelable::ResultParcelable()
     : AbstractParcelable(0, ParcelableType::Result), row_(0), col_(0) {}
 
-ResultParcelable::ResultParcelable(int ret,
-    std::vector<std::vector<std::string>>&& results)
-        : AbstractParcelable(0, ParcelableType::Result, ret),
-            results_(std::move(results)) {
+ResultParcelable::ResultParcelable(int ret, std::vector<StrArgs> results)
+    : AbstractParcelable(0, ParcelableType::Result, ret),
+        results_(std::move(results)) {
   row_ = results_.size();
   if (row_ == 0) {
     col_ = 0;
@@ -53,7 +52,7 @@ void ResultParcelable::WriteToParcel(tizen_base::Parcel* parcel) const {
 
   for (const auto& cols : results_) {
     for (const auto& str : cols)
-      parcel->WriteString(str);
+      WriteString(parcel, str);
   }
 }
 
@@ -63,19 +62,19 @@ void ResultParcelable::ReadFromParcel(tizen_base::Parcel* parcel) {
   parcel->ReadUInt32(&col_);
 
   for (unsigned int i = 0; i < row_; ++i) {
-    std::vector<std::string> vt;
+    StrArgs vt;
     for (unsigned int j = 0; j < col_; ++j)
-      vt.emplace_back(parcel->ReadString());
+      vt.emplace_back(ReadString(parcel));
 
     results_.emplace_back(std::move(vt));
   }
 }
 
-const std::vector<std::vector<std::string>>& ResultParcelable::GetResult() {
+const std::vector<StrArgs>& ResultParcelable::GetResult() {
   return results_;
 }
 
-unsigned int ResultParcelable::GetRaw() {
+unsigned int ResultParcelable::GetRow() {
   return row_;
 }
 
index 1958564..3535cd4 100644 (file)
@@ -13,22 +13,24 @@ namespace parcel {
 #define EXPORT_API __attribute__((visibility("default")))
 #endif
 
+using StrArgs = std::vector<std::optional<std::string>>;
+
 class EXPORT_API ResultParcelable : public AbstractParcelable {
  public:
   ResultParcelable();
-  ResultParcelable(int ret, std::vector<std::vector<std::string>>&& results);
+  ResultParcelable(int ret, std::vector<StrArgs> results);
 
   void WriteToParcel(tizen_base::Parcel* parcel) const override;
   void ReadFromParcel(tizen_base::Parcel* parcel) override;
 
-  const std::vector<std::vector<std::string>>& GetResult();
-  unsigned int GetRaw();
+  const std::vector<StrArgs>& GetResult();
+  unsigned int GetRow();
   unsigned int GetCol();
 
  private:
   unsigned int row_;
   unsigned int col_;
-  std::vector<std::vector<std::string>> results_;
+  std::vector<StrArgs> results_;
 };
 
 }  // namespace parcel
index f10fcd1..09e87c4 100644 (file)
@@ -27,7 +27,7 @@ bool CommandRequestHandler::HandleRequest(unsigned char* data, int size,
       abstract_parcel->GetType() != pcp::ParcelableType::Command) {
     _LOGE("Invalid parcel or type");
     result_ = std::make_shared<pcp::ResultParcelable>(
-        PMINFO_R_ERROR, std::vector<std::vector<std::string>>{});
+        PMINFO_R_ERROR, std::vector<pcp::StrArgs>{});
     return false;
   }
 
@@ -35,7 +35,7 @@ bool CommandRequestHandler::HandleRequest(unsigned char* data, int size,
   if (parcel == nullptr) {
     _LOGE("Parcel is empty");
     result_ = std::make_shared<pcp::ResultParcelable>(
-        PMINFO_R_ERROR, std::vector<std::vector<std::string>>{});
+        PMINFO_R_ERROR, std::vector<pcp::StrArgs>{});
     return false;
   }
 
@@ -43,7 +43,7 @@ bool CommandRequestHandler::HandleRequest(unsigned char* data, int size,
     pkgmgr_common::DBHandleProvider::GetInst(
         parcel->GetUid()).SetMemoryMode(GetPID(), false);
     result_ = std::make_shared<pcp::ResultParcelable>(
-        PMINFO_R_OK, std::vector<std::vector<std::string>>{});
+        PMINFO_R_OK, std::vector<pcp::StrArgs>{});
     return true;
   }
 
index 10a99f1..eccd59c 100644 (file)
@@ -27,7 +27,7 @@ bool QueryRequestHandler::HandleRequest(unsigned char* data, int size,
       abstract_parcel->GetType() != pcp::ParcelableType::Query) {
     _LOGE("Invalid parcel or type");
     result_ = std::make_shared<pcp::ResultParcelable>(
-        PMINFO_R_ERROR, std::vector<std::vector<std::string>>{});
+        PMINFO_R_ERROR, std::vector<pcp::StrArgs>{});
     return false;
   }
 
@@ -35,7 +35,7 @@ bool QueryRequestHandler::HandleRequest(unsigned char* data, int size,
   if (parcel == nullptr) {
     _LOGE("Parcel is empty");
     result_ = std::make_shared<pcp::ResultParcelable>(
-        PMINFO_R_ERROR, std::vector<std::vector<std::string>>{});
+        PMINFO_R_ERROR, std::vector<pcp::StrArgs>{});
     return false;
   }
 
index 82fe6e4..1d97982 100644 (file)
@@ -27,7 +27,7 @@ bool SetCertRequestHandler::HandleRequest(unsigned char* data, int size,
       abstract_parcel->GetType() != pcp::ParcelableType::CertInfo) {
     _LOGE("Invalid parcel");
     result_ = std::make_shared<pcp::ResultParcelable>(
-        PMINFO_R_ERROR, std::vector<std::vector<std::string>>{});
+        PMINFO_R_ERROR, std::vector<pcp::StrArgs>{});
     return false;
   }
 
@@ -35,7 +35,7 @@ bool SetCertRequestHandler::HandleRequest(unsigned char* data, int size,
   if (parcel == nullptr) {
     _LOGE("Parcel is empty");
     result_ = std::make_shared<pcp::ResultParcelable>(
-        PMINFO_R_ERROR, std::vector<std::vector<std::string>>{});
+        PMINFO_R_ERROR, std::vector<pcp::StrArgs>{});
     return false;
   }
 
@@ -45,7 +45,7 @@ bool SetCertRequestHandler::HandleRequest(unsigned char* data, int size,
 
   int ret = db.Execute();
   result_ = std::make_shared<pcp::ResultParcelable>(
-      ret, std::vector<std::vector<std::string>>{});
+      ret, std::vector<pcp::StrArgs>{});
 
   return true;
 }
index cf04ccf..9c3d236 100644 (file)
@@ -29,7 +29,7 @@ bool SetPkginfoRequestHandler::HandleRequest(unsigned char* data, int size,
       abstract_parcel->GetType() != pcp::ParcelableType::PkgInfo) {
     _LOGE("Invalid parcel or type");
     result_ = std::make_shared<pcp::ResultParcelable>(
-        PM_PARSER_R_ERROR, std::vector<std::vector<std::string>>{});
+        PM_PARSER_R_ERROR, std::vector<pcp::StrArgs>{});
     return false;
   }
 
@@ -37,7 +37,7 @@ bool SetPkginfoRequestHandler::HandleRequest(unsigned char* data, int size,
   if (parcel == nullptr) {
     _LOGE("Parcel is empty");
     result_ = std::make_shared<pcp::ResultParcelable>(
-        PM_PARSER_R_ERROR, std::vector<std::vector<std::string>>{});
+        PM_PARSER_R_ERROR, std::vector<pcp::StrArgs>{});
     return false;
   }
 
@@ -57,7 +57,7 @@ bool SetPkginfoRequestHandler::HandleRequest(unsigned char* data, int size,
   }
 
   result_ = std::make_shared<pcp::ResultParcelable>(
-      ret, std::vector<std::vector<std::string>>{});
+      ret, std::vector<pcp::StrArgs>{});
 
   return true;
 }
index 421f284..edf3e62 100644 (file)
@@ -214,13 +214,13 @@ extern "C" EXPORT_API char* _appinfo_get_localed_label(
 
   // result_list is vector of string vector
   char* label = nullptr;
-  auto result_list = return_parcel->GetResult();
+  auto& result_list = return_parcel->GetResult();
   for (auto& result : result_list) {
     // result is string vector
     // it only has one string or not.
-    if (result.front().empty())
+    if (!result.front() || (*result.front()).empty())
       return nullptr;
-    label = strdup(result.front().c_str());
+    label = strdup((*result.front()).c_str());
     if (label == nullptr) {
       LOG(ERROR) << "Out of memory";
       return nullptr;
@@ -264,19 +264,20 @@ extern "C" EXPORT_API int _appinfo_get_datacontrol_info(
   std::shared_ptr<pcp::ResultParcelable> return_parcel(
       std::static_pointer_cast<pcp::ResultParcelable>(ptr));
 
-  auto result_list = return_parcel->GetResult();
+  auto& result_list = return_parcel->GetResult();
   if (result_list.size() == 0)
     return PMINFO_R_ENOENT;
   for (auto& result : result_list) {
-    if (result.size() != 2 || result.front().empty() || result.back().empty())
+    if (result.size() != 2 || !result.front() || !result.back() ||
+        (*result.front()).empty() || (*result.back()).empty())
       return PMINFO_R_ERROR;
 
-    char* tmp_appid = strdup(result.front().c_str());
+    char* tmp_appid = strdup((*result.front()).c_str());
     if (tmp_appid == nullptr) {
       LOG(ERROR) << "Out of memory";
       return PMINFO_R_ERROR;
     }
-    char* tmp_access = strdup(result.back().c_str());
+    char* tmp_access = strdup((*result.back()).c_str());
     if (tmp_access == nullptr) {
       LOG(ERROR) << "Out of memory";
       free(tmp_appid);
@@ -323,13 +324,13 @@ extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
       std::static_pointer_cast<pcp::ResultParcelable>(ptr));
 
   // result_list is vector of string vector
-  auto result_list = return_parcel->GetResult();
+  auto& result_list = return_parcel->GetResult();
   if (result_list.size() == 0)
     return PMINFO_R_ENOENT;
   for (auto& result : result_list) {
-    if (result.size() != 1 || result.front().empty())
+    if (result.size() != 1 || !result.front() || (*result.front()).empty())
       return PMINFO_R_ERROR;
-    *appid = strdup(result.front().c_str());
+    *appid = strdup((*result.front()).c_str());
     if (*appid == nullptr) {
       LOG(ERROR) << "Out of memory";
       return PMINFO_R_ERROR;
@@ -374,19 +375,20 @@ extern "C" EXPORT_API int _appinfo_get_datacontrol_trusted_info(
       std::static_pointer_cast<pcp::ResultParcelable>(ptr));
 
   // result_list is vector of string vector
-  auto result_list = return_parcel->GetResult();
+  auto& result_list = return_parcel->GetResult();
   if (result_list.size() == 0)
     return PMINFO_R_ENOENT;
   for (auto& result : result_list) {
-    if (result.size() != 2 || result.front().empty() || result.back().empty())
+    if (result.size() != 2 || !result.front() || !result.back() ||
+        (*result.front()).empty() || (*result.back()).empty())
       return PMINFO_R_ERROR;
 
-    char* tmp_appid = strdup(result.front().c_str());
+    char* tmp_appid = strdup((*result.front()).c_str());
     if (tmp_appid == nullptr) {
       LOG(ERROR) << "Out of memory";
       return PMINFO_R_ERROR;
     }
-    char* tmp_trusted = strdup(result.back().c_str());
+    char* tmp_trusted = strdup((*result.back()).c_str());
     if (tmp_trusted == nullptr) {
       LOG(ERROR) << "Out of memory";
       free(tmp_appid);
@@ -434,14 +436,14 @@ extern "C" EXPORT_API int _appinfo_get_datacontrol_privileges(
       std::static_pointer_cast<pcp::ResultParcelable>(ptr));
 
   // result_list is vector of string vector
-  auto result_list = return_parcel->GetResult();
+  auto& result_list = return_parcel->GetResult();
   if (result_list.size() == 0)
     return PMINFO_R_ENOENT;
 
   for (auto& result : result_list) {
-    if (result.size() != 1 || result.front().empty())
+    if (result.size() != 1 || !result.front() || (*result.front()).empty())
       return PMINFO_R_ERROR;
-    char* privilege = strdup(result.front().c_str());
+    char* privilege = strdup((*result.front()).c_str());
     if (privilege == nullptr) {
       LOG(ERROR) << "Out of memory";
       return PMINFO_R_ERROR;
@@ -485,18 +487,19 @@ extern "C" EXPORT_API int _appinfo_get_appcontrol_privileges(
       std::static_pointer_cast<pcp::ResultParcelable>(ptr));
 
   // result_list is vector of string vector
-  auto result_list = return_parcel->GetResult();
+  auto& result_list = return_parcel->GetResult();
   if (result_list.size() == 0)
     return PMINFO_R_ENOENT;
 
   for (auto& result : result_list) {
-    if (result.size() != 2 || result.front().empty() || result.back().empty())
+    if (result.size() != 2 || !result.front() || !result.back() ||
+        (*result.front()).empty() || (*result.back()).empty())
       return PMINFO_R_ERROR;
-    std::stringstream ss(result.front());
+    std::stringstream ss((*result.front()));
     std::string token;
     while (std::getline(ss, token, '|')) {
       if (token.compare(std::string(operation))) {
-        char* privilege = strdup(result.back().c_str());
+        char* privilege = strdup((*result.back()).c_str());
         if (privilege == nullptr) {
           LOG(ERROR) << "Out of memory";
           return PMINFO_R_ERROR;
@@ -552,7 +555,7 @@ extern "C" EXPORT_API int _plugininfo_get_appids(
     return PMINFO_R_ERROR;
   }
   // result_list is vector of string vector
-  auto &result_list = return_parcel->GetResult();
+  autoresult_list = return_parcel->GetResult();
   if (result_list.size() == 0)
     return PMINFO_R_ENOENT;
 
@@ -562,7 +565,7 @@ extern "C" EXPORT_API int _plugininfo_get_appids(
       g_list_free_full(*list, free);
       return PMINFO_R_ERROR;
     }
-    *list = g_list_append(*list, strdup(result[0].c_str()));
+    *list = g_list_append(*list, strdup((*result[0]).c_str()));
   }
 
   return PMINFO_R_OK;
@@ -644,7 +647,7 @@ extern "C" EXPORT_API int _get_pkg_updateinfo(const char* pkgid,
     return PMINFO_R_ERROR;
   }
 
-  auto result_list = return_parcel->GetResult();
+  auto& result_list = return_parcel->GetResult();
   if (result_list.size() == 0)
     return PMINFO_R_ENOENT;
 
@@ -662,10 +665,10 @@ extern "C" EXPORT_API int _get_pkg_updateinfo(const char* pkgid,
       g_slist_free_full(tmp_list, __free_update_info);
       return PMINFO_R_ERROR;
     }
-    update_info->pkgid = strdup(result[0].c_str());
-    update_info->version = strdup(result[1].c_str());
+    update_info->pkgid = strdup((*result[0]).c_str());
+    update_info->version = strdup((*result[1]).c_str());
     pkgmgrinfo_updateinfo_update_type convert_type;
-    ret = __convert_update_type(result[2].c_str(), &convert_type);
+    ret = __convert_update_type((*result[2]).c_str(), &convert_type);
     if (ret != 0) {
       __free_update_info(update_info);
       g_slist_free_full(tmp_list, __free_update_info);
@@ -764,14 +767,14 @@ extern "C" EXPORT_API int _certinfo_compare_pkg_certinfo(const char* l_pkgid,
       std::static_pointer_cast<pcp::ResultParcelable>(
           ptr));
 
-  auto certinfo_list = return_parcel->GetResult();
+  auto& certinfo_list = return_parcel->GetResult();
 
   std::map<std::string, std::string> result_map;
   result_map.insert(make_pair(std::string(l_pkgid), "-1"));
   result_map.insert(make_pair(std::string(r_pkgid), "-1"));
 
   for (auto& certinfo : certinfo_list)
-    result_map[certinfo.front()] = certinfo.back();
+    result_map[*certinfo.front()] = *certinfo.back();
 
   auto l_iter = result_map.find(l_pkgid);
   auto r_iter = result_map.find(r_pkgid);
@@ -821,10 +824,10 @@ extern "C" EXPORT_API int _certinfo_compare_app_certinfo(uid_t uid,
   std::shared_ptr<pcp::ResultParcelable> return_parcel(
       std::static_pointer_cast<pcp::ResultParcelable>(ptr));
 
-  auto pkgid_list = return_parcel->GetResult();
+  auto& pkgid_list = return_parcel->GetResult();
   std::map<std::string, std::string> result_map;
   for (auto& pkgid : pkgid_list)
-    result_map.insert(make_pair(pkgid.front(), pkgid.back()));
+    result_map.insert(make_pair(*pkgid.front(), *pkgid.back()));
 
   auto l_iter = result_map.find(l_appid);
   if (l_iter == result_map.end()) {
index c5cbf07..e1e913e 100644 (file)
@@ -167,13 +167,31 @@ TEST_F(ParcelTest, CertInfoParcelable) {
 
 TEST_F(ParcelTest, ResultParcelable) {
   tizen_base::Parcel parcel;
-  std::vector<std::vector<std::string>> vt{{"a1", "a2"}, {"b1", "b2"}};
+  std::vector<std::vector<const char*>> raw_result{
+    {"a1", "a2"},
+    {"b1", "b2"},
+    {"c1", nullptr}
+  };
+  EXPECT_NE(raw_result.size(), 0);
+
+  std::vector<pp::StrArgs> vt(raw_result.size());
+  for (unsigned int i = 0; i < raw_result.size(); i++) {
+    vt[i].resize(raw_result[i].size());
+    for (unsigned int j = 0; j < raw_result[i].size(); j++) {
+      if (raw_result[i][j])
+        vt[i][j] = raw_result[i][j];
+      else
+        vt[i][j] = std::nullopt;
+    }
+  }
 
   pp::ResultParcelable origin_parcelable(0, std::move(vt));
   pp::ResultParcelable new_parcelable;
   parcel.WriteParcelable(origin_parcelable);
   parcel.ReadParcelable(&new_parcelable);
 
+  EXPECT_EQ(origin_parcelable.GetRow(), new_parcelable.GetRow());
+  EXPECT_EQ(origin_parcelable.GetCol(), new_parcelable.GetCol());
   EXPECT_EQ(origin_parcelable.GetResult(), new_parcelable.GetResult());
 }