From: Pawel Wasowski Date: Mon, 8 May 2017 16:05:27 +0000 (+0200) Subject: [Filesystem] Rewrite f_isSubDir to handle symbolic links correctly X-Git-Tag: submit/tizen_3.0/20170510.071359~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=44917c81ea07d2609d6ee103d90e32752788261e;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Filesystem] Rewrite f_isSubDir to handle symbolic links correctly 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 --- diff --git a/src/filesystem/filesystem_instance.cc b/src/filesystem/filesystem_instance.cc index 47ffc97c..5434c510 100644 --- a/src/filesystem/filesystem_instance.cc +++ b/src/filesystem/filesystem_instance.cc @@ -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(); + + 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 diff --git a/src/filesystem/filesystem_instance.h b/src/filesystem/filesystem_instance.h index b46ef7da..e70d7c75 100644 --- a/src/filesystem/filesystem_instance.h +++ b/src/filesystem/filesystem_instance.h @@ -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 diff --git a/src/filesystem/filesystem_manager.cc b/src/filesystem/filesystem_manager.cc index dc96e58e..6039be14 100644 --- a/src/filesystem/filesystem_manager.cc +++ b/src/filesystem/filesystem_manager.cc @@ -31,6 +31,7 @@ #endif #include #undef _XOPEN_SOURCE +#include #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& success_cb, + const std::function& 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 diff --git a/src/filesystem/filesystem_manager.h b/src/filesystem/filesystem_manager.h index b2060fb1..0ef1815e 100644 --- a/src/filesystem/filesystem_manager.h +++ b/src/filesystem/filesystem_manager.h @@ -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& success_cb, + const std::function& error_cb); }; } // namespace filesystem } // namespace extension diff --git a/src/filesystem/js/common.js b/src/filesystem/js/common.js index 6eeddca6..adf52c7e 100644 --- a/src/filesystem/js/common.js +++ b/src/filesystem/js/common.js @@ -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('/'))