Add OOM exception handler 48/142448/12
authorSeungha Son <seungha.son@samsung.com>
Fri, 4 Aug 2017 01:16:49 +0000 (10:16 +0900)
committerSeungha Son <seungha.son@samsung.com>
Fri, 11 Aug 2017 05:10:16 +0000 (14:10 +0900)
Signed-off-by: Seungha Son <seungha.son@samsung.com>
Change-Id: Ib23567136a901d8a9a833b23db3292abeaef2177

src/common/external_storage.cc
src/common/plugins/types/category_plugin.cc
src/common/plugins/types/metadata_plugin.cc
src/common/privileges.cc
src/common/step/configuration/step_parse_manifest.cc
src/common/step/security/step_privilege_compatibility.cc

index 4c67eab..9117e17 100644 (file)
@@ -28,6 +28,14 @@ int64_t SizeInMB(int64_t size) {
   return (size + 1_MB - 1) / 1_MB;
 }
 
+void ClearApp2ExtDirDetail(gpointer data) {
+  app2ext_dir_details* dir_detail =
+      reinterpret_cast<app2ext_dir_details*>(data);
+  if (dir_detail->name)
+    free(dir_detail->name);
+  free(dir_detail);
+}
+
 }  // namespace
 
 namespace common_installer {
@@ -158,7 +166,18 @@ bool ExternalStorage::Initialize(
   for (auto& dir : external_dirs_) {
     app2ext_dir_details* dir_detail = reinterpret_cast<app2ext_dir_details*>(
         calloc(1, sizeof(app2ext_dir_details)));
+    if (!dir_detail) {
+      LOG(ERROR) << "Out of memory";
+      g_list_free_full(glist, &ClearApp2ExtDirDetail);
+      return false;
+    }
     dir_detail->name = strdup(dir.c_str());
+    if (!dir_detail->name) {
+      LOG(ERROR) << "Out of memory";
+      free(dir_detail);
+      g_list_free_full(glist, &ClearApp2ExtDirDetail);
+      return false;
+    }
     dir_detail->type = APP2EXT_DIR_RO;
     glist = g_list_append(glist, dir_detail);
   }
@@ -213,12 +232,7 @@ bool ExternalStorage::Initialize(
     assert(false && "Invalid installation mode");
   }
 
-  g_list_free_full(glist, [](gpointer data) {
-      app2ext_dir_details* dir_detail =
-          reinterpret_cast<app2ext_dir_details*>(data);
-      free(dir_detail->name);
-      free(dir_detail);
-    });
+  g_list_free_full(glist, &ClearApp2ExtDirDetail);
   return ret == 0;
 }
 
index f53b7dd..d6c7a18 100644 (file)
@@ -68,7 +68,18 @@ bool CategoryPlugin::Run(xmlDocPtr /*doc_ptr*/, manifest_x* manifest,
       if (std::string(category).find(sub_key_prefix) == 0) {
         __category_t* c = reinterpret_cast<__category_t*>(
             calloc(1, sizeof(__category_t)));
+        if (!c) {
+          LOG(ERROR) << "Out of memory";
+          g_list_free_full(category_list, &ClearCategoryDetail);
+          return false;
+        }
         c->name = strdup(category);
+        if (!c->name) {
+          LOG(ERROR) << "Out of memory";
+          free(c);
+          g_list_free_full(category_list, &ClearCategoryDetail);
+          return false;
+        }
         category_list = g_list_append(category_list, c);
       }
     }
index 25e495d..1ea1699 100644 (file)
@@ -18,8 +18,10 @@ std::string GetMetadataTag(const std::string& url) {
 
 void ClearMetadataDetail(gpointer data) {
   __metadata_t* meta = reinterpret_cast<__metadata_t*>(data);
-  free(const_cast<char*>(meta->key));
-  free(const_cast<char*>(meta->value));
+  if (meta->key)
+    free(const_cast<char*>(meta->key));
+  if (meta->value)
+    free(const_cast<char*>(meta->value));
   free(meta);
 }
 
@@ -70,8 +72,25 @@ bool MetadataPlugin::Run(xmlDocPtr /*doc_ptr*/, manifest_x* manifest,
           std::string(meta->key).find(sub_key_prefix) == 0) {
         __metadata_t* md = reinterpret_cast<__metadata_t*>(
             calloc(1, sizeof(__metadata_t)));
+        if (!md) {
+          LOG(ERROR) << "Out of memory";
+          g_list_free_full(md_list, &ClearMetadataDetail);
+          return false;
+        }
         md->key = strdup(meta->key);
+        if (!md->key) {
+          LOG(ERROR) << "Out of memory";
+          free(md);
+          g_list_free_full(md_list, &ClearMetadataDetail);
+          return false;
+        }
         md->value = strdup(meta->value);
+        if (!md->value) {
+          LOG(ERROR) << "Out of memory";
+          ClearMetadataDetail(md);
+          g_list_free_full(md_list, &ClearMetadataDetail);
+          return false;
+        }
         md_list = g_list_append(md_list, md);
       }
     }
index 16aee1a..4c0b0a8 100644 (file)
@@ -4,6 +4,8 @@
 
 #include "common/privileges.h"
 
+#include <manifest_parser/utils/logging.h>
+
 #include <cstdlib>
 #include <cstring>
 
@@ -46,8 +48,25 @@ GList* PrivilegeToPrivilegeX(GList* privileges, const std::string& type) {
   for (auto& r : GListRange<char*>(privileges)) {
     privilege_x* privilege =
         reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
+    if (!privilege) {
+      LOG(ERROR) << "Out of memory";
+      g_list_free_full(result, &FreePrivilegeX);
+      return nullptr;
+    }
     privilege->type = strdup(type.c_str());
+    if (!privilege->type) {
+      LOG(ERROR) << "Out of memory";
+      FreePrivilegeX(privilege);
+      g_list_free_full(result, &FreePrivilegeX);
+      return nullptr;
+    }
     privilege->value = strdup(r);
+    if (!privilege->value) {
+      LOG(ERROR) << "Out of memory";
+      FreePrivilegeX(privilege);
+      g_list_free_full(result, &FreePrivilegeX);
+      return nullptr;
+    }
     result = g_list_append(result, privilege);
   }
   return result;
index 8f2a9d2..a445b39 100644 (file)
@@ -248,6 +248,10 @@ bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
 
   for (auto& pair : pkg_info->labels()) {
     label_x* label = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
+    if (!label) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     if (!pair.first.empty())
       label->lang = strdup(pair.first.c_str());
     else
@@ -295,6 +299,10 @@ bool StepParseManifest::FillAuthorInfo(manifest_x* manifest) {
     return true;
 
   author_x* author = reinterpret_cast<author_x*>(calloc(1, sizeof(author_x)));
+  if (!author) {
+    LOG(ERROR) << "Out of memory";
+    return false;
+  }
   author->text = strdup(author_info->name().c_str());
   author->email = strdup(author_info->email().c_str());
   author->href = strdup(author_info->href().c_str());
@@ -314,6 +322,10 @@ bool StepParseManifest::FillDescriptionInfo(manifest_x* manifest) {
   for (auto& desc : description_info->descriptions) {
     description_x* description = reinterpret_cast<description_x*>
         (calloc(1, sizeof(description_x)));
+    if (!description) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     description->text = strdup(desc.description().c_str());
     description->lang = !desc.xml_lang().empty() ?
         strdup(desc.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
@@ -333,6 +345,10 @@ bool StepParseManifest::FillPrivileges(manifest_x* manifest) {
   for (auto& priv : privileges) {
     privilege_x* privilege =
         reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
+    if (!privilege) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     privilege->value = strdup(priv.first.c_str());
     privilege->type = strdup(priv.second.c_str());
     manifest->privileges = g_list_append(manifest->privileges, privilege);
@@ -415,6 +431,10 @@ bool StepParseManifest::FillWidgetApplication(manifest_x* manifest) {
 
     application_x* widget_app =
         static_cast<application_x*>(calloc(1, sizeof(application_x)));
+    if (!widget_app) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     widget_app->appid = strdup(application.app_info.appid().c_str());
     widget_app->launch_mode =
         strdup(application.app_info.launch_mode().c_str());
@@ -480,6 +500,10 @@ bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
 
     application_x* service_app =
         static_cast<application_x*>(calloc(1, sizeof(application_x)));
+    if (!service_app) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     service_app->appid = strdup(application.app_info.appid().c_str());
     service_app->multiple = strdup(application.app_info.multiple().c_str());
     service_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
@@ -549,6 +573,10 @@ bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
 
     application_x* ui_app =
         static_cast<application_x*>(calloc(1, sizeof(application_x)));
+    if (!ui_app) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     ui_app->appid = strdup(application.app_info.appid().c_str());
     ui_app->launch_mode = strdup(application.app_info.launch_mode().c_str());
     ui_app->multiple = strdup(application.app_info.multiple().c_str());
@@ -643,6 +671,10 @@ bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
 
     application_x* watch_app =
              static_cast<application_x*>(calloc(1, sizeof(application_x)));
+    if (!watch_app) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     watch_app->appid = strdup(watch_application.app_info.appid().c_str());
 
     if (bf::path(watch_application.app_info.exec().c_str()).is_absolute())
@@ -746,6 +778,10 @@ bool StepParseManifest::FillAppControl(application_x* app,
   for (const auto& control : app_control_list) {
     appcontrol_x* app_control =
           static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
+    if (!app_control) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     app_control->operation = strdup(control.operation().c_str());
     if (!control.mime().empty())
       app_control->mime = strdup(control.mime().c_str());
@@ -769,6 +805,10 @@ bool StepParseManifest::FillDataControl(application_x* app,
   for (const auto& control : data_control_list) {
     datacontrol_x* data_control =
           static_cast<datacontrol_x*>(calloc(1, sizeof(datacontrol_x)));
+    if (!data_control) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     data_control->access = strdup(control.access().c_str());
     data_control->providerid = strdup(control.providerid().c_str());
     data_control->type = strdup(control.type().c_str());
@@ -789,7 +829,11 @@ template <typename T>
 bool StepParseManifest::FillApplicationIconPaths(application_x* app,
                                          const T& icons_info) {
   for (auto& application_icon : icons_info.icons()) {
-    icon_x* icon = reinterpret_cast<icon_x*> (calloc(1, sizeof(icon_x)));
+    icon_x* icon = reinterpret_cast<icon_x*>(calloc(1, sizeof(icon_x)));
+    if (!icon) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     bf::path text;
     if (bf::path(application_icon.path()).is_absolute()) {
       text = application_icon.path();
@@ -821,6 +865,10 @@ bool StepParseManifest::FillLabel(application_x* app, const T& label_list) {
   for (const auto& control : label_list) {
     label_x* label =
           static_cast<label_x*>(calloc(1, sizeof(label_x)));
+    if (!label) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     // NOTE: name is an attribute, but the xml writer uses it as text.
     // This must be fixed in whole app-installer modules, including wgt.
     // Current implementation is just for compatibility.
@@ -842,6 +890,10 @@ bool StepParseManifest::FillMetadata(application_x* app,
   for (auto& meta : meta_data_list) {
     metadata_x* metadata =
         static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
+    if (!metadata) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     metadata->key = strdup(meta.key().c_str());
     metadata->value = strdup(meta.val().c_str());
     app->metadata = g_list_append(app->metadata, metadata);
@@ -867,6 +919,10 @@ void StepParseManifest::AppendSplashScreen(application_x* app,
     const std::string& operation, const std::string& color_depth) {
   splashscreen_x* splashscreen =
       static_cast<splashscreen_x*>(calloc(1, sizeof(splashscreen_x)));
+  if (!splashscreen) {
+    LOG(ERROR) << "Out of memory";
+    return;
+  }
   if (bf::path(src).is_absolute()) {
     splashscreen->src = strdup(src.c_str());
   } else {
@@ -965,6 +1021,10 @@ bool StepParseManifest::FillImage(application_x* app,
   for (auto& app_image : image_list.images) {
     image_x* image =
         static_cast<image_x*>(calloc(1, sizeof(image_x)));
+    if (!image) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     const std::string& lang = app_image.lang();
     if (!lang.empty())
       image->lang = strdup(lang.c_str());
@@ -1093,6 +1153,10 @@ Step::Status StepParseManifest::process() {
 
   manifest_x* manifest =
       static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
+  if (!manifest) {
+    LOG(ERROR) << "Out of memory";
+    return Step::Status::ERROR;
+  }
 
   if (!FillManifestX(const_cast<manifest_x*>(manifest))) {
     LOG(ERROR) << "[Parse] Storing manifest_x failed. "
index 7748edd..3a2029a 100644 (file)
@@ -130,6 +130,10 @@ Step::Status StepPrivilegeCompatibility::process() {
       internal_priv_type_ == InternalPrivType::BOTH) {
     privilege_x* privilege =
         reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
+    if (!privilege) {
+      LOG(ERROR) << "Out of memory";
+      return Step::Status::ERROR;
+    }
     privilege->type = strdup(kNativePrivilegeType);
     privilege->value = strdup(internal_priv.c_str());
     context_->manifest_data.get()->privileges =
@@ -140,6 +144,10 @@ Step::Status StepPrivilegeCompatibility::process() {
       internal_priv_type_ == InternalPrivType::BOTH) {
     privilege_x* privilege =
         reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
+    if (!privilege) {
+      LOG(ERROR) << "Out of memory";
+      return Step::Status::ERROR;
+    }
     privilege->type = strdup(kWebPrivilegeType);
     privilege->value = strdup(internal_priv.c_str());
     context_->manifest_data.get()->privileges =
@@ -149,6 +157,10 @@ Step::Status StepPrivilegeCompatibility::process() {
   if (context_->debug_mode.get()) {
     privilege_x* privilege =
         reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
+    if (!privilege) {
+      LOG(ERROR) << "Out of memory";
+      return Step::Status::ERROR;
+    }
     privilege->type = internal_priv_type_ == InternalPrivType::TPK ?
         strdup(kNativePrivilegeType) : strdup(kWebPrivilegeType);
     privilege->value = strdup(kAppDebuggingPrivilegeStr);