Fix bug on checking error conditions when calling dlsym()
authorSoo-Hyun Choi <sh9.choi@samsung.com>
Wed, 25 Sep 2013 16:20:31 +0000 (01:20 +0900)
committerGerrit Code Review <gerrit@gerrit.vlan144.tizendev.org>
Sun, 29 Sep 2013 08:41:18 +0000 (08:41 +0000)
[Issue#]   N/A
[Problem]  A bug on checking error conditions when calling dlsym()
[Cause]    Missed to call dlerror() to clear any old error conditions.
[Solution] Added dlerror() before calling dlsym().
           Also, separated error conditions:
           one for dlsym related error and another for DRM API related error.

[Remarks] DLOPEN(3)
    The function dlsym() takes a "handle" of a dynamic library returned by
    dlopen() and the null-terminated symbol name, returning the address where
    that  symbol is loaded into memory.  If the symbol is not found, in the
    specified library or any of the libraries that were automatically loaded
    by dlopen() when that library was loaded, dlsym() returns NULL.  (The
    search performed by dlsym() is breadth first through the  dependency  tree
    of  these libraries.)  Since the value of the symbol could actually be
    NULL (so that a NULL return from dlsym() need not indicate an error), the
    correct way to test for an error is to call dlerror() to clear any old
    error conditions, then call dlsym(), and then call dlerror() again,  sav‐
    ing its return value into a variable, and check whether this saved value
    is not NULL.

Change-Id: Idee1834fbdcfee184d07f757c871994e9832d7d4

src/jobs/widget_install/widget_unzip.cpp

index 60bc464..8a7f601 100644 (file)
@@ -158,11 +158,20 @@ bool WidgetUnzip::isDRMPackage(const std::string &source)
         return false;
     }
 
+    // clear existing error
+    dlerror();
+
     drm_oem_sapps_is_drm_file = reinterpret_cast <int (*)(const char*, int)>
         (dlsym(pHandle, "drm_oem_sapps_is_drm_file"));
-    pErrorMsg = dlerror();
-    if ((pErrorMsg != NULL) || (drm_oem_sapps_is_drm_file == NULL)) {
-        _E("dlopen failed : %s [%s]", source.c_str(), pErrorMsg);
+
+    if ((pErrorMsg = dlerror()) != NULL) {
+        _E("dlsym failed : %s [%s]", source.c_str(), pErrorMsg);
+        dlclose(pHandle);
+        return false;
+    }
+
+    if (drm_oem_sapps_is_drm_file == NULL) {
+        _E("drm_oem_sapps_is_drm_file is NULL : %s", source.c_str());
         dlclose(pHandle);
         return false;
     }
@@ -193,12 +202,21 @@ bool WidgetUnzip::decryptDRMPackage(const std::string &source, const std::string
         return false;
     }
 
+    // clear existing error
+    dlerror();
+
     drm_oem_sapps_decrypt_package = reinterpret_cast <int (*)(const char*, int,
             const char*, int)>
         (dlsym(pHandle, "drm_oem_sapps_decrypt_package"));
-    pErrorMsg = dlerror();
-    if ((pErrorMsg != NULL) || (drm_oem_sapps_decrypt_package == NULL)) {
-        _E("dlopen failed : %s [%s]", source.c_str(), pErrorMsg);
+
+    if ((pErrorMsg = dlerror()) != NULL) {
+        _E("dlsym failed : %s [%s]", source.c_str(), pErrorMsg);
+        dlclose(pHandle);
+        return false;
+    }
+
+    if (drm_oem_sapps_decrypt_package == NULL) {
+        _E("drm_oem_sapps_decrypt_package is NULL : %s", source.c_str());
         dlclose(pHandle);
         return false;
     }