Fix QueryParcelable to handle null char pointer 04/259804/9
authorIlho Kim <ilho159.kim@samsung.com>
Mon, 14 Jun 2021 09:31:14 +0000 (18:31 +0900)
committerIlho Kim <ilho159.kim@samsung.com>
Thu, 24 Jun 2021 04:10:36 +0000 (13:10 +0900)
Change-Id: I1c1c02487beebd0586ad4423226231cab93c5167
Signed-off-by: Ilho Kim <ilho159.kim@samsung.com>
12 files changed:
src/CMakeLists.txt
src/common/database/query_handler.cc
src/common/database/query_handler.hh
src/common/parcel/abstract_parcelable.cc
src/common/parcel/abstract_parcelable.hh
src/common/parcel/query_parcelable.cc
src/common/parcel/query_parcelable.hh
src/common/request_handler/query_request_handler.cc
src/manager/pkginfo_manager.cc
src/server/CMakeLists.txt
test/unit_tests/CMakeLists.txt
test/unit_tests/test_parcel.cc

index 0cb229c..7a180f0 100644 (file)
@@ -20,7 +20,7 @@ ADD_LIBRARY(pkgmgr-info SHARED
 )
 
 ## Compile flags
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fpic -std=c++14")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fpic -std=c++17")
 
 SET_TARGET_PROPERTIES(pkgmgr-info PROPERTIES SOVERSION ${MAJORVER})
 SET_TARGET_PROPERTIES(pkgmgr-info PROPERTIES VERSION ${FULLVER})
index a635459..a11f7cc 100644 (file)
@@ -204,7 +204,7 @@ QueryHandler::QueryHandler(uid_t uid, int pid)
 QueryHandler::~QueryHandler() {}
 
 void QueryHandler::SetQueryArgs(
-    std::vector<std::pair<int, std::vector<std::string>>> query_args) {
+    std::vector<parcel::QueryArgs> query_args) {
   query_args_ = std::move(query_args);
 }
 
@@ -241,8 +241,10 @@ int QueryHandler::Execute() {
       return PMINFO_R_ERROR;
     }
     arg->len = i.second.size();
-    for (auto& argument : i.second)
-      arg->argument = g_list_append(arg->argument, (gpointer)argument.c_str());
+    for (auto& argument : i.second) {
+      arg->argument = g_list_append(arg->argument,
+          gpointer(argument ? (*argument).c_str() : nullptr));
+    }
 
     args_list = g_list_append(args_list, arg);
   }
index 3cf692b..8f2e0de 100644 (file)
@@ -25,6 +25,7 @@
 #include "abstract_db_handler.hh"
 #include "pkgmgrinfo_basic.h"
 #include "pkgmgrinfo_private.h"
+#include "query_parcelable.hh"
 
 namespace pkgmgr_common {
 namespace database {
@@ -37,7 +38,7 @@ class EXPORT_API QueryHandler : public AbstractDBHandler{
  public:
   QueryHandler(uid_t uid, int pid);
   ~QueryHandler();
-  void SetQueryArgs(std::vector<std::pair<int, std::vector<std::string>>> query_args);
+  void SetQueryArgs(std::vector<parcel::QueryArgs> query_args);
   bool BindString(std::string value);
   bool BindInt(int value);
   std::string GetString();
@@ -49,7 +50,7 @@ class EXPORT_API QueryHandler : public AbstractDBHandler{
  private:
   uid_t uid_;
   std::vector<std::string> query_;
-  std::vector<std::pair<int, std::vector<std::string>>> query_args_;
+  std::vector<parcel::QueryArgs> query_args_;
   std::vector<std::vector<std::string>> result_;
 };
 
index 23b7479..6b648a4 100644 (file)
@@ -28,7 +28,7 @@ bool AbstractParcelable::ReadInt(tizen_base::Parcel* parcel, int *val) {
 }
 
 bool AbstractParcelable::ReadString(tizen_base::Parcel* parcel, char **val) {
-  bool is_null = false;
+  bool is_null;
   if (parcel->ReadBool(&is_null) != TIZEN_ERROR_NONE)
     return false;
 
@@ -40,6 +40,18 @@ bool AbstractParcelable::ReadString(tizen_base::Parcel* parcel, char **val) {
   return parcel->ReadCString(val);
 }
 
+std::optional<std::string> AbstractParcelable::ReadString(
+    tizen_base::Parcel* parcel) {
+  bool is_null;
+  if (parcel->ReadBool(&is_null) != TIZEN_ERROR_NONE)
+    return std::nullopt;
+
+  if (is_null)
+    return std::nullopt;
+
+  return parcel->ReadString();
+}
+
 void AbstractParcelable::WriteInt(tizen_base::Parcel* parcel, int i) const {
   parcel->WriteInt32(i);
 }
@@ -54,6 +66,16 @@ void AbstractParcelable::WriteString(tizen_base::Parcel* parcel,
   parcel->WriteCString(str);
 }
 
+void AbstractParcelable::WriteString(tizen_base::Parcel* parcel,
+    const std::optional<std::string>& str) const {
+  if (!str) {
+    parcel->WriteBool(true);
+    return;
+  }
+  parcel->WriteBool(false);
+  parcel->WriteString(*str);
+}
+
 void AbstractParcelable::WriteToParcel(tizen_base::Parcel* parcel) const {
   WriteInt(parcel, type_);
   WriteInt(parcel, uid_);
index 6ab6fc5..a8f0296 100644 (file)
@@ -1,10 +1,11 @@
 #ifndef ABSTRACT_PARCELABLE_HH_
 #define ABSTRACT_PARCELABLE_HH_
 
-#include<memory>
-#include<vector>
+#include <memory>
+#include <optional>
+#include <vector>
 
-#include<parcel.hh>
+#include <parcel.hh>
 
 #include "request_type.hh"
 
@@ -43,8 +44,11 @@ class EXPORT_API AbstractParcelable : public tizen_base::Parcelable {
 
  protected:
   bool ReadString(tizen_base::Parcel* parcel, char **val);
+  std::optional<std::string> ReadString(tizen_base::Parcel* parcel);
   bool ReadInt(tizen_base::Parcel* parcel, int *val);
   void WriteString(tizen_base::Parcel* parcel, const char* str) const;
+  void WriteString(tizen_base::Parcel* parcel,
+      const std::optional<std::string>& str) const;
   void WriteInt(tizen_base::Parcel* parcel, int i) const;
 
  private:
index 4d47811..0d5265d 100644 (file)
@@ -31,19 +31,35 @@ QueryParcelable::QueryParcelable()
     op_type_(AbstractDBHandler::OperationType::OPERATION_TYPE_NONE) {}
 
 QueryParcelable::QueryParcelable(uid_t uid,
-    QueryArgs query_args,
+    const std::pair<int, std::vector<const char*>>& query_args,
     AbstractDBHandler::DBType db_type,
     AbstractDBHandler::OperationType op_type)
     : AbstractParcelable(0, ParcelableType::Query),
-    query_args_(std::vector<QueryArgs>{query_args}),
-    db_type_(db_type), op_type_(op_type) {}
+    db_type_(db_type), op_type_(op_type) {
+  query_args_.emplace_back(CreateQueryArgs(query_args));
+}
 
 QueryParcelable::QueryParcelable(uid_t uid,
-    std::vector<QueryArgs> query_args,
+    const std::vector<std::pair<int, std::vector<const char*>>>& query_args,
     AbstractDBHandler::DBType db_type,
     AbstractDBHandler::OperationType op_type)
     : AbstractParcelable(uid, ParcelableType::Query),
-    query_args_(std::move(query_args)), db_type_(db_type), op_type_(op_type) {}
+    db_type_(db_type), op_type_(op_type) {
+  for (const auto& arg : query_args)
+    query_args_.emplace_back(CreateQueryArgs(arg));
+}
+
+QueryArgs QueryParcelable::CreateQueryArgs(
+    const std::pair<int, std::vector<const char*>>& args) {
+  StrArgs vt;
+  for (const char* param : args.second) {
+      if (param)
+        vt.emplace_back(param);
+      else
+        vt.emplace_back(std::nullopt);
+  }
+  return std::make_pair(args.first, std::move(vt));
+}
 
 void QueryParcelable::WriteToParcel(tizen_base::Parcel* parcel) const {
   AbstractParcelable::WriteToParcel(parcel);
@@ -52,7 +68,7 @@ void QueryParcelable::WriteToParcel(tizen_base::Parcel* parcel) const {
     WriteInt(parcel, query_info.first);
     WriteInt(parcel, query_info.second.size());
     for (const auto& args : query_info.second)
-      parcel->WriteString(args);
+      WriteString(parcel, args);
   }
   WriteInt(parcel, db_type_);
   WriteInt(parcel, op_type_);
@@ -66,14 +82,14 @@ void QueryParcelable::ReadFromParcel(tizen_base::Parcel* parcel) {
   AbstractParcelable::ReadFromParcel(parcel);
   ReadInt(parcel, &query_size);
   for (int i = 0; i < query_size; ++i) {
-    std::vector<std::string> args;
+    StrArgs args;
     int index = -1;
     int arg_cnt = 0;
     ReadInt(parcel, &index);
     ReadInt(parcel, &arg_cnt);
 
     for (int j = 0; j < arg_cnt; ++j)
-      args.push_back(parcel->ReadString());
+      args.emplace_back(ReadString(parcel));
 
     query_args_.push_back(QueryArgs(index, std::move(args)));
   }
@@ -83,8 +99,8 @@ void QueryParcelable::ReadFromParcel(tizen_base::Parcel* parcel) {
   op_type_ = static_cast<AbstractDBHandler::OperationType>(op_type);
 }
 
-const std::vector<QueryArgs>& QueryParcelable::GetQueryArgs() {
-  return query_args_;
+std::vector<QueryArgs> QueryParcelable::ExtractQueryArgs() {
+  return std::move(query_args_);
 }
 
 AbstractDBHandler::DBType QueryParcelable::GetDBType() {
index 7ef9e58..c1a4b79 100644 (file)
@@ -4,6 +4,7 @@
 #include "abstract_parcelable.hh"
 #include "abstract_db_handler.hh"
 
+#include <optional>
 #include <vector>
 
 #include "pkgmgrinfo_private.h"
@@ -17,18 +18,21 @@ namespace parcel {
 #define EXPORT_API __attribute__((visibility("default")))
 #endif
 
-using QueryArgs = std::pair<int, std::vector<std::string>>;
+using StrArgs = std::vector<std::optional<std::string>>;
+using QueryArgs = std::pair<int, StrArgs>;
 
 class EXPORT_API QueryParcelable : public AbstractParcelable {
  public:
   QueryParcelable();
-  QueryParcelable(uid_t uid, QueryArgs query_args,
+  QueryParcelable(uid_t uid,
+      const std::pair<int, std::vector<const char*>>& query_args,
       AbstractDBHandler::DBType db_type,
       AbstractDBHandler::OperationType op_type);
-  QueryParcelable(uid_t uid, std::vector<QueryArgs> query_args,
+  QueryParcelable(uid_t uid,
+      const std::vector<std::pair<int, std::vector<const char*>>>& query_args,
       AbstractDBHandler::DBType db_type,
       AbstractDBHandler::OperationType op_type);
-  const std::vector<QueryArgs>& GetQueryArgs();
+  std::vector<QueryArgs> ExtractQueryArgs();
   AbstractDBHandler::DBType GetDBType();
   AbstractDBHandler::OperationType GetOpType();
 
@@ -36,6 +40,9 @@ class EXPORT_API QueryParcelable : public AbstractParcelable {
   void ReadFromParcel(tizen_base::Parcel* parcel) override;
 
  private:
+  QueryArgs CreateQueryArgs(
+      const std::pair<int, std::vector<const char*>>& args);
+
   std::vector<QueryArgs> query_args_;
   AbstractDBHandler::DBType db_type_;
   AbstractDBHandler::OperationType op_type_;
index 7e5769a..10a99f1 100644 (file)
@@ -41,7 +41,7 @@ bool QueryRequestHandler::HandleRequest(unsigned char* data, int size,
 
   pcd::QueryHandler db(parcel->GetUid(), GetPID());
   db.SetLocale(locale);
-  db.SetQueryArgs(parcel->GetQueryArgs());
+  db.SetQueryArgs(parcel->ExtractQueryArgs());
   db.SetDBType(parcel->GetDBType());
   db.SetOpType(parcel->GetOpType());
   int ret = db.Execute();
index ee1d5eb..421f284 100644 (file)
@@ -600,13 +600,13 @@ extern "C" EXPORT_API int _get_pkg_updateinfo(const char* pkgid,
     GSList** update_info_list, uid_t uid) {
   int ret;
 
-  std::pair<int, std::vector<std::string>> info;
+  std::pair<int, std::vector<const char*>> info;
 
   if (pkgid == nullptr) {
-    info = std::pair<int, std::vector<std::string>>(
+    info = std::pair<int, std::vector<const char*>>(
               QUERY_INDEX_GET_PKG_UPDATEINFO_1, {});
   } else {
-    info = std::pair<int, std::vector<std::string>>(
+    info = std::pair<int, std::vector<const char*>>(
               QUERY_INDEX_GET_PKG_UPDATEINFO_2, { pkgid });
   }
 
@@ -847,14 +847,10 @@ extern "C" EXPORT_API int _certinfo_compare_app_certinfo(uid_t uid,
 
 extern "C" EXPORT_API int _parser_execute_write_query(
     int query_index, const char** query_args, unsigned int arg_cnt, uid_t uid) {
-  std::vector<std::string> args;
+  std::vector<const char*> args;
 
-  for (unsigned int i = 0; i < arg_cnt; i++) {
-    if (query_args[i])
-      args.push_back(query_args[i]);
-    else
-      args.push_back("");
-  }
+  for (unsigned int i = 0; i < arg_cnt; i++)
+    args.push_back(query_args[i]);
 
   std::shared_ptr<pcp::AbstractParcelable> parcelable(
       new pcp::QueryParcelable(uid, { query_index, std::move(args) },
@@ -887,16 +883,12 @@ extern "C" EXPORT_API int _parser_execute_write_query(
 extern "C" EXPORT_API int _parser_execute_write_queries(
     int query_index, const char*** query_args, unsigned int arg_cnt,
     unsigned int query_cnt, uid_t uid) {
-  std::vector<std::pair<int, std::vector<std::string>>> queries;
+  std::vector<std::pair<int, std::vector<const char*>>> queries;
 
   for (unsigned int i = 0; i < query_cnt; i++) {
-    std::vector<std::string> args;
-    for (unsigned int j = 0; j < arg_cnt; j++) {
-      if (query_args[i][j])
-        args.push_back(query_args[i][j]);
-      else
-        args.push_back("");
-    }
+    std::vector<const char*> args;
+    for (unsigned int j = 0; j < arg_cnt; j++)
+      args.push_back(query_args[i][j]);
     queries.push_back({ query_index, std::move(args) });
   }
 
index 7ba15db..45e62e9 100644 (file)
@@ -12,7 +12,7 @@ INCLUDE_DIRECTORIES(
 )
 
 ADD_EXECUTABLE(${PKGINFO_SERVER} ${PKGINFO_SERVER_SRCS})
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fpic -std=c++14 -pthread -fPIE")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fpic -std=c++17 -pthread -fPIE")
 SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie")
 
 TARGET_LINK_LIBRARIES(${PKGINFO_SERVER} PRIVATE ${libpkgs_LDFLAGS})
index 9a400cc..27b2ab3 100644 (file)
@@ -17,7 +17,7 @@ FOREACH(flag ${unit_test_pkgs_CFLAGS})
 ENDFOREACH(flag)
 
 ## Compile flags
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fpic -std=c++14")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fpic -std=c++17")
 
 TARGET_LINK_LIBRARIES(${TARGET_PKGMGR_INFO_UNIT_TEST} PRIVATE ${libpkgs_LDFLAGS})
 TARGET_LINK_LIBRARIES(${TARGET_PKGMGR_INFO_UNIT_TEST} PRIVATE ${libpkgmgr-parser_LDFLAGS})
index 7816e1a..c5cbf07 100644 (file)
@@ -179,24 +179,23 @@ TEST_F(ParcelTest, ResultParcelable) {
 
 TEST_F(ParcelTest, QueryParcelable) {
   tizen_base::Parcel parcel;
-  std::vector<std::pair<int, std::vector<std::string>>> query_args = {
+  std::vector<std::pair<int, std::vector<const char*>>> query_args = {
     { 0, { "arg1", "arg2" } },
-    { 1, { "arg1" } }
+    { 1, { "arg1" } },
+    { 2, { nullptr, "arg2" } }
   };
 
-  pp::QueryParcelable origin_parcelable(0, query_args,
+  pp::QueryParcelable origin_parcelable(0, std::move(query_args),
       pcb::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
       pcb::AbstractDBHandler::OperationType::OPERATION_TYPE_READ);
   pp::QueryParcelable new_parcelable;
   parcel.WriteParcelable(origin_parcelable);
   parcel.ReadParcelable(&new_parcelable);
 
-  EXPECT_EQ(origin_parcelable.GetQueryArgs().size(), new_parcelable.GetQueryArgs().size());
-  EXPECT_EQ(origin_parcelable.GetQueryArgs()[0].first, new_parcelable.GetQueryArgs()[0].first);
-  EXPECT_EQ(origin_parcelable.GetQueryArgs()[1].first, new_parcelable.GetQueryArgs()[1].first);
-  EXPECT_EQ(origin_parcelable.GetQueryArgs()[0].second[0], new_parcelable.GetQueryArgs()[0].second[0]);
-  EXPECT_EQ(origin_parcelable.GetQueryArgs()[0].second[1], new_parcelable.GetQueryArgs()[0].second[1]);
-  EXPECT_EQ(origin_parcelable.GetQueryArgs()[1].second[0], new_parcelable.GetQueryArgs()[1].second[0]);
+  auto origin_args = origin_parcelable.ExtractQueryArgs();
+  auto new_args = new_parcelable.ExtractQueryArgs();
+
+  EXPECT_EQ(origin_args, new_args);
   EXPECT_EQ(origin_parcelable.GetDBType(), new_parcelable.GetDBType());
   EXPECT_EQ(origin_parcelable.GetOpType(), new_parcelable.GetOpType());
 }