[Filesystem] Rewrite f_isSubDir to handle symbolic links correctly 31/128331/1
authorPawel Wasowski <p.wasowski2@partner.samsung.com>
Mon, 8 May 2017 16:05:27 +0000 (18:05 +0200)
committerPawel Wasowski <p.wasowski2@partner.samsung.com>
Mon, 8 May 2017 17:40:12 +0000 (19:40 +0200)
The function did not resolve indirect paths, i.e. containing symbolic
links.

The problem was reported in following PLM issues: P170503-03986, P170309-04700

[Verification] tct-filesystem-tizen-tests 100% pass rate
               The problem reported in mentioned PLM issues does not
               show up after applying the patch.

Change-Id: Ie9056e2f504333d2706622b9f3824807373902c6
Signed-off-by: Pawel Wasowski <p.wasowski2@partner.samsung.com>
src/filesystem/filesystem_instance.cc
src/filesystem/filesystem_instance.h
src/filesystem/filesystem_manager.cc
src/filesystem/filesystem_manager.h
src/filesystem/js/common.js

index 47ffc97c7e7c250a8b74746c05de0154ccd59521..5434c5101557421b151ad3a609916bce8b0cb08c 100644 (file)
@@ -69,6 +69,7 @@ FilesystemInstance::FilesystemInstance() {
   REGISTER_ASYNC("File_unlinkFile", UnlinkFile);
   REGISTER_ASYNC("File_removeDirectory", RemoveDirectory);
   REGISTER_ASYNC("File_copyTo", CopyTo);
+  REGISTER_SYNC("FileSystemManager_getCanonicalPath", FileSystemManagerGetCanonicalPath);
 #undef REGISTER_SYNC
 #undef REGISTER_ASYNC
   FilesystemManager::GetInstance().AddListener(this);
@@ -653,6 +654,27 @@ void FilesystemInstance::PrepareError(const FilesystemError& error, picojson::ob
   }
 }
 
+void FilesystemInstance::FileSystemManagerGetCanonicalPath(const picojson::value& args, picojson::object& out)
+{
+  LoggerD("Enter");
+  //TODO: any privilege needed?
+  CHECK_EXIST(args, "path", out);
+
+  const std::string& path = args.get("path").get<std::string>();
+
+  auto onSuccess = [&](const std::string& canonicalPath) {
+    LoggerD("Enter");
+    ReportSuccess(picojson::value(canonicalPath), out);
+  };
+
+  auto onError = [&](FilesystemError e) {
+    LoggerD("Enter");
+    PrepareError(e, out);
+  };
+
+  FilesystemManager::GetInstance().GetCanonicalPath(path, onSuccess, onError);
+}
+
 #undef CHECK_EXIST
 
 }  // namespace filesystem
index b46ef7da2f24d39220ed170218f95a6c3d1c1cd5..e70d7c75918143141b1efa9d4f132d9cd9d000f1 100644 (file)
@@ -57,6 +57,7 @@ class FilesystemInstance : public common::ParsedInstance,
   void onFilesystemStateChangeErrorCallback();
   void onFilesystemStateChangeSuccessCallback(const common::Storage& storage);
   void PrepareError(const FilesystemError& error, picojson::object& out);
+  void FileSystemManagerGetCanonicalPath(const picojson::value& args, picojson::object& out);
 };
 
 }  // namespace filesystem
index dc96e58ec1f8c246fa8a1d9bd55f2c74be4d5ab0..6039be147fbc8873b5a724ecc0ca5568cce938f1 100644 (file)
@@ -31,6 +31,7 @@
 #endif
 #include <ftw.h>
 #undef _XOPEN_SOURCE
+#include <stdlib.h>
 
 #include "common/logger.h"
 #include "common/tools.h"
@@ -482,5 +483,28 @@ void FilesystemManager::RemoveListener() {
   LoggerD("enter");
   listener_ = NULL;
 }
+
+void FilesystemManager::GetCanonicalPath(const std::string& path,
+                      const std::function<void(const std::string&)>& success_cb,
+                      const std::function<void(FilesystemError)>& error_cb) {
+  LoggerD("Enter");
+  char *canonicalPath = nullptr;
+
+  SCOPE_EXIT {
+    free(canonicalPath);
+  };
+
+  canonicalPath = realpath(path.c_str(), nullptr);
+  int tmpErrno;
+  if (!canonicalPath) {
+    tmpErrno = errno;
+    LoggerE("Cannot get realpath of %s. Error: %s!", path.c_str(), strerror(tmpErrno));
+    error_cb(FilesystemError::Other);
+  }
+
+  std::string canonicalPathStr(canonicalPath);
+  success_cb(canonicalPathStr);
+}
+
 }  // namespace filesystem
 }  // namespace extension
index b2060fb1a00597530b85c8caf48c2264a2016ec7..0ef1815ec36a616fb3a112c1bff04b88fd0adf3c 100644 (file)
@@ -117,6 +117,10 @@ void CopyTo(const std::string& originFilePath,
                           common::StorageState _old, common::StorageState _new);
   void AddListener(FilesystemStateChangeListener* listener);
   void RemoveListener();
+
+  void GetCanonicalPath(const std::string& path,
+                        const std::function<void(const std::string&)>& success_cb,
+                        const std::function<void(FilesystemError)>& error_cb);
 };
 }  // namespace filesystem
 }  // namespace extension
index 6eeddca6b80668488e44e20cbe0aeddf6824701f..adf52c7e514350805061fec593b0a735ee7c2d8d 100644 (file)
@@ -331,10 +331,25 @@ var commonFS_ = (function() {
     return true;
   }
 
+  function toCanonicalPath(path) {
+    var result = native_.callSync('FileSystemManager_getCanonicalPath', { "path": path});
+    if (native_.isFailure(result)) {
+      throw native_.getErrorObject(result);
+    }
+
+    return native_.getResultObject(result);
+  }
+
   function f_isSubDir(fullPathToCheck, fullPath) {
-    var realFullPath = toRealPath(fullPath);
-    return ((-1 !== fullPathToCheck.indexOf(realFullPath)) && (fullPathToCheck !== realFullPath));
-  };
+    var fullCanonicalPathToCheck = toCanonicalPath(toRealPath(fullPathToCheck));
+    var fullCanonicalPath = toCanonicalPath(toRealPath(fullPath));
+
+    if (fullCanonicalPathToCheck === fullCanonicalPath) {
+      return false;
+    }
+
+    return fullCanonicalPathToCheck.indexOf(fullCanonicalPath) === 0;
+  }
 
   function f_isCorrectRelativePath(relativePath) {
     return ((0 !== relativePath.indexOf('/'))