Merge "Coverity issue fixes" into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 10 Mar 2023 10:54:42 +0000 (10:54 +0000)
committerGerrit Code Review <gerrit@review>
Fri, 10 Mar 2023 10:54:42 +0000 (10:54 +0000)
automated-tests/src/dali-scene3d/CMakeLists.txt
automated-tests/src/dali-scene3d/utc-Dali-NavigationMesh.cpp
dali-scene3d/internal/algorithm/navigation-mesh-impl.cpp
dali-scene3d/internal/algorithm/path-finder-djikstra.cpp
dali-scene3d/public-api/loader/navigation-mesh-factory.cpp

index 66a766a..9c813df 100755 (executable)
@@ -111,7 +111,7 @@ ADD_CUSTOM_COMMAND(
 ADD_EXECUTABLE(${EXEC_NAME} ${EXEC_NAME}.h ${EXEC_NAME}.cpp ${TC_SOURCES} ${TEST_HARNESS_SOURCES})
 TARGET_LINK_LIBRARIES(${EXEC_NAME}
     ${${CAPI_LIB}_LIBRARIES}
-    -lpthread --coverage
+    -lpthread -ldl --coverage
 )
 
 INSTALL(PROGRAMS ${EXEC_NAME}
index ec9b0bc..f2f6cd3 100644 (file)
 #include "dali-scene3d/public-api/algorithm/navigation-mesh.h"
 #include "dali-scene3d/public-api/loader/navigation-mesh-factory.h"
 #include <dali-test-suite-utils.h>
-
+#include <dlfcn.h>
 using namespace Dali;
 using namespace Dali::Scene3D::Algorithm;
 using namespace Dali::Scene3D::Loader;
 
+/**
+ * SysOverride allows overriding a system symbol and
+ * set the return value for n-th call of it.
+ *
+ * After invoking the symbol override is disabled.
+ */
+template<class R, class F>
+struct SysOverride
+{
+  SysOverride(const char* funcName)
+  {
+    funcNameStr = funcName;
+    if(!func)
+    {
+      func = decltype(func)(dlsym(RTLD_NEXT, funcName));
+    }
+  }
+
+  void SetReturnValue( R value, uint32_t n )
+  {
+    if(overrideEnabled)
+    {
+      tet_infoline("Warning! Overriding return value is already enabled! Ignoring!\n");
+      return;
+    }
+    result = value;
+    overrideCounter = n;
+    overrideEnabled = true;
+  }
+
+  template<class... Args>
+  R Invoke(Args&&... args)
+  {
+    auto retval = func(args...);
+    if(overrideEnabled)
+    {
+      if(!overrideCounter)
+      {
+        overrideEnabled = false;
+        return result;
+      }
+      overrideCounter--;
+    }
+    return retval;
+  }
+
+  std::string funcNameStr;
+  R result{R{}};
+  F* func{nullptr};
+  uint32_t overrideCounter = 0;
+  bool overrideEnabled = false;
+};
+
+// Override fseek()
+static thread_local SysOverride<int, decltype(fseek)> call_fseek("fseek");
+extern "C" int fseek (FILE *s, long int o, int w)
+{
+  return call_fseek.Invoke( s, o, w );
+}
+
+// Override ftell()
+static thread_local SysOverride<int, decltype(ftell)> call_ftell("ftell");
+extern "C" long int ftell(FILE *s)
+{
+  return call_ftell.Invoke( s );
+}
+
+// Override fread()
+static thread_local SysOverride<int, decltype(fread)> call_fread("fread");
+extern "C" size_t fread (void *__restrict p, size_t s, size_t n, FILE *__restrict st)
+{
+  return call_fread.Invoke(p, s, n, st);
+}
+
 int UtcDaliNavigationMeshCreateFromFileFail1(void)
 {
   tet_infoline("UtcDaliNavigationMeshCreateFromFileFail1: Fails to create navigation mesh from file");
@@ -35,6 +109,58 @@ int UtcDaliNavigationMeshCreateFromFileFail1(void)
   END_TEST;
 }
 
+int UtcDaliNavigationMeshCreateFromFileFail2(void)
+{
+  tet_infoline("UtcDaliNavigationMeshCreateFromFileFail2: Fails to create navigation mesh using file");
+
+  // Override next fseek to fail
+  call_fseek.SetReturnValue(-1, 0);
+  auto result = NavigationMeshFactory::CreateFromFile("resources/navmesh-test.bin");
+
+  DALI_TEST_CHECK(result == nullptr);
+
+  END_TEST;
+}
+
+int UtcDaliNavigationMeshCreateFromFileFail3(void)
+{
+  tet_infoline("UtcDaliNavigationMeshCreateFromFileFail3: Fails to create navigation mesh using file");
+
+  // Override next ftell to fail
+  call_ftell.SetReturnValue(-1, 0);
+  auto result = NavigationMeshFactory::CreateFromFile("resources/navmesh-test.bin");
+
+  DALI_TEST_CHECK(result == nullptr);
+
+  END_TEST;
+}
+
+int UtcDaliNavigationMeshCreateFromFileFail4(void)
+{
+  tet_infoline("UtcDaliNavigationMeshCreateFromFileFail4: Fails to create navigation mesh using file");
+
+  // Override 2nd fseek to fail
+  call_fseek.SetReturnValue(-1, 1);
+  auto result = NavigationMeshFactory::CreateFromFile("resources/navmesh-test.bin");
+
+  DALI_TEST_CHECK(result == nullptr);
+
+  END_TEST;
+}
+
+int UtcDaliNavigationMeshCreateFromFileFail5(void)
+{
+  tet_infoline("UtcDaliNavigationMeshCreateFromFileFail5: Fails to create navigation mesh using file");
+
+  // Override fread() to fail reading file
+  call_fread.SetReturnValue(-1, 0);
+  auto result = NavigationMeshFactory::CreateFromFile("resources/navmesh-test.bin");
+
+  DALI_TEST_CHECK(result == nullptr);
+
+  END_TEST;
+}
+
 int UtcDaliNavigationMeshCreateFromFileOk1(void)
 {
   tet_infoline("UtcDaliNavigationMeshCreateFromFileOk1: Creates navigation mesh using file");
index e3b72d2..2a8d9f4 100644 (file)
@@ -21,9 +21,6 @@
 #include <dali/integration-api/debug.h>
 
 #include <algorithm>
-#include <cerrno>
-#include <cstdio>
-#include <cstring>
 #include <filesystem>
 
 using Dali::Vector3;
index 7c751ad..186acf2 100644 (file)
@@ -119,7 +119,14 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::FindPath(uint32_t
   do
   {
     // find minimum distance
-    [[maybe_unused]] auto minDistIndex = FindMinDistance(dist);
+    auto minDistIndex = FindMinDistance(dist);
+
+    // Failed to find minimum distance
+    if(minDistIndex == -1)
+    {
+      // Return empty WayPointList
+      return {};
+    }
 
     // remove from queue by assigning infinity to distance
     removeCount++;
index 5f66539..4ae02e6 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali-scene3d/internal/algorithm/navigation-mesh-impl.h>
+#include <dali/devel-api/adaptor-framework/file-stream.h>
 
 namespace Dali::Scene3D::Loader
 {
 std::unique_ptr<Algorithm::NavigationMesh> NavigationMeshFactory::CreateFromFile(std::string filename)
 {
   std::vector<uint8_t> buffer;
-  auto                 fin = fopen(filename.c_str(), "rb");
+
+  Dali::FileStream fileStream(filename, Dali::FileStream::READ | Dali::FileStream::BINARY);
+  auto fin = fileStream.GetFile();
+
   if(!fin)
   {
     DALI_LOG_ERROR("NavigationMesh: Can't open %s for reading: %s", filename.c_str(), strerror(errno));
@@ -36,19 +40,30 @@ std::unique_ptr<Algorithm::NavigationMesh> NavigationMeshFactory::CreateFromFile
   }
   else
   {
-    fseek(fin, 0, SEEK_END);
+    if(fseek(fin, 0, SEEK_END))
+    {
+      return {};
+    }
+
     auto size = ftell(fin);
-    fseek(fin, 0, SEEK_SET);
+    if(size < 0)
+    {
+      return {};
+    }
+
+    auto fileSize = size_t(size);
+    if(fseek(fin, 0, SEEK_SET))
+    {
+      return {};
+    }
+
     buffer.resize(size);
-    auto count = fread(buffer.data(), 1, size, fin);
-    if(!count)
+    auto count = fread(buffer.data(), 1, fileSize, fin);
+    if(count != fileSize)
     {
       DALI_LOG_ERROR("NavigationMesh: Error reading file: %s\n", filename.c_str());
-      fclose(fin);
       return nullptr;
     }
-    fclose(fin);
-
     return CreateFromBuffer(buffer);
   }
 }