diff --git a/bundle.json b/bundle.json index ee3dcf798e5fd966873b22b3fcfed221eea4474f..60c317e0ee82d0dfa042e4d82b12deac16187a5f 100644 --- a/bundle.json +++ b/bundle.json @@ -36,6 +36,7 @@ "dfs_service", "eventhandler", "hilog", + "hisysevent", "hitrace", "ipc", "init", diff --git a/interfaces/kits/cj/src/copy_dir.cpp b/interfaces/kits/cj/src/copy_dir.cpp index 878bbe4f840a194a476427e7cdfaf863418a527d..f1404cfb9175164ec6b25b0421d1bb37cc8fe13a 100644 --- a/interfaces/kits/cj/src/copy_dir.cpp +++ b/interfaces/kits/cj/src/copy_dir.cpp @@ -64,6 +64,8 @@ static void Deleter(struct NameList *arg) } free(arg->namelist); arg->namelist = nullptr; + delete arg; + arg = nullptr; } static int CopyFile(const std::string &src, const std::string &dest, const int mode) @@ -198,20 +200,20 @@ static CConflictFiles* VectorToCConflict(std::vector &errf break; } if (strcpy_s(result[i].srcFiles, srcFilesLen, errfiles[i].srcFiles.c_str()) != 0) { - delete result[i].srcFiles; + delete[] result[i].srcFiles; result[i].srcFiles = nullptr; break; } size_t destFilesLen = errfiles[i].destFiles.length() + 1; result[i].destFiles = new(std::nothrow) char[destFilesLen]; if (result[i].destFiles == nullptr) { - delete result[i].srcFiles; + delete[] result[i].srcFiles; result[i].srcFiles = nullptr; break; } if (strcpy_s(result[i].destFiles, destFilesLen, errfiles[i].destFiles.c_str()) != 0) { - delete result[i].srcFiles; - delete result[i].destFiles; + delete[] result[i].srcFiles; + delete[] result[i].destFiles; result[i].srcFiles = nullptr; result[i].destFiles = nullptr; @@ -221,8 +223,8 @@ static CConflictFiles* VectorToCConflict(std::vector &errf } if (temp != errfiles.size()) { for (size_t j = temp; j > 0; j--) { - delete result[j - 1].srcFiles; - delete result[j - 1].destFiles; + delete[] result[j - 1].srcFiles; + delete[] result[j - 1].destFiles; result[j - 1].srcFiles = nullptr; result[j - 1].destFiles = nullptr; diff --git a/interfaces/kits/cj/src/copy_file.cpp b/interfaces/kits/cj/src/copy_file.cpp index db5b6553a7a7216709a3fdc55e23dc469cc778d5..9335526c0cb402f5b5c7efd22bb554f72ccd78d3 100644 --- a/interfaces/kits/cj/src/copy_file.cpp +++ b/interfaces/kits/cj/src/copy_file.cpp @@ -33,32 +33,35 @@ using namespace OHOS::FileManagement::LibN; using namespace OHOS::FileManagement; using namespace OHOS::CJSystemapi::FileFs; -std::tuple ParseFile(int32_t file) +std::tuple ParseOperand(int32_t file) { - LOGI("FS_TEST:: FS_TEST::ParseFile"); + LOGI("FS_TEST:: FS_TEST::ParseOperand"); if (file < 0) { LOGE("Invalid fd"); - return { false, FileInfo { false, {}, {} } }; + return { EINVAL, FileInfo { false, {}, {} } }; } auto fdg = CreateUniquePtr(file, false); if (fdg == nullptr) { LOGE("Failed to request heap memory."); - return { false, FileInfo { false, {}, {} } }; + return { ENOMEM, FileInfo { false, {}, {} } }; } - LOGI("FS_TEST:: FS_TEST::ParseFile success"); - return { true, FileInfo { false, {}, move(fdg) } }; + LOGI("FS_TEST:: FS_TEST::ParseOperand success"); + return { SUCCESS_CODE, FileInfo { false, {}, move(fdg) } }; }; -static FileInfo ParseFile(std::string file) +std::tuple ParseOperand(std::string file) { - LOGI("FS_TEST:: ParseFile"); + LOGI("FS_TEST:: ParseOperand"); std::unique_ptr filePath = std::make_unique(file.length() + 1); + if (!filePath) { + return { ENOMEM, FileInfo { true, {}, {} } }; + } for (size_t i = 0; i < file.length(); i++) { filePath[i] = file[i]; } - LOGI("FS_TEST:: ParseFile success"); - return FileInfo { true, move(filePath), {} }; + LOGI("FS_TEST:: ParseOperand success"); + return { SUCCESS_CODE, FileInfo { true, move(filePath), {} } }; }; static int IsAllPath(FileInfo& srcFile, FileInfo& destFile) @@ -194,19 +197,27 @@ static int OpenFile(FileInfo& srcFile, FileInfo& destFile) int CopyFileImpl::CopyFile(const std::string& src, const std::string& dest, int mode) { LOGI("FS_TEST:: CopyFile::CopyFile start"); - auto srcFileInfo = ParseFile(src); - auto destFileInfo = ParseFile(dest); + auto [succSrc, srcFileInfo] = ParseOperand(src); + if (succSrc != SUCCESS_CODE) { + return succSrc; + } + auto [succDest, destFileInfo] = ParseOperand(dest); + if (succDest != SUCCESS_CODE) { + return succDest; + } return IsAllPath(srcFileInfo, destFileInfo); } int CopyFileImpl::CopyFile(const std::string& src, int32_t dest, int mode) { LOGI("FS_TEST:: CopyFile::CopyFile start"); - auto srcFileInfo = ParseFile(src); - auto [succDest, destFileInfo] = ParseFile(dest); - if (!succDest) { - LOGE("The destargument requires fd"); - return EINVAL; + auto [succSrc, srcFileInfo] = ParseOperand(src); + if (succSrc != SUCCESS_CODE) { + return succSrc; + } + auto [succDest, destFileInfo] = ParseOperand(dest); + if (succDest != SUCCESS_CODE) { + return succDest; } return OpenFile(srcFileInfo, destFileInfo); } @@ -214,11 +225,13 @@ int CopyFileImpl::CopyFile(const std::string& src, int32_t dest, int mode) int CopyFileImpl::CopyFile(int32_t src, const std::string& dest, int mode) { LOGI("FS_TEST:: CopyFile::CopyFile start"); - auto [succSrc, srcFileInfo] = ParseFile(src); - auto destFileInfo = ParseFile(dest); - if (!succSrc) { - LOGE("The destargument requires fd"); - return EINVAL; + auto [succSrc, srcFileInfo] = ParseOperand(src); + if (succSrc != SUCCESS_CODE) { + return succSrc; + } + auto [succDest, destFileInfo] = ParseOperand(dest); + if (succDest != SUCCESS_CODE) { + return succDest; } return OpenFile(srcFileInfo, destFileInfo); } @@ -226,11 +239,13 @@ int CopyFileImpl::CopyFile(int32_t src, const std::string& dest, int mode) int CopyFileImpl::CopyFile(int32_t src, int32_t dest, int mode) { LOGI("FS_TEST:: CopyFile::CopyFile start"); - auto [succSrc, srcFileInfo] = ParseFile(src); - auto [succDest, destFileInfo] = ParseFile(dest); - if (!succSrc || !succDest) { - LOGE("The destargument requires fd"); - return EINVAL; + auto [succSrc, srcFileInfo] = ParseOperand(src); + if (succSrc != SUCCESS_CODE) { + return succSrc; + } + auto [succDest, destFileInfo] = ParseOperand(dest); + if (succDest != SUCCESS_CODE) { + return succDest; } return OpenFile(srcFileInfo, destFileInfo); } diff --git a/interfaces/kits/cj/src/file_fs_ffi.cpp b/interfaces/kits/cj/src/file_fs_ffi.cpp index c30942825c081e415c01397ef62e5747d79e7334..baf176be50b38b60f6d7f3fad392a03a83b99340 100644 --- a/interfaces/kits/cj/src/file_fs_ffi.cpp +++ b/interfaces/kits/cj/src/file_fs_ffi.cpp @@ -561,12 +561,12 @@ int32_t FfiOHOSFileFsWatcherStart(int64_t id) LOGE("FfiOHOSFileFsWatcherStart instance not exist %{public}" PRId64, id); return ERR_INVALID_INSTANCE_CODE; } - LOGI("FS_TEST::FfiOHOSFileFsWatcherStart success"); - int32_t startCode = instance->StartNotify(); + int32_t startCode = FileWatcherManager::GetInstance().StartNotify(instance->data_); if (startCode != SUCCESS_CODE) { return startCode; } - instance->GetNotifyEvent(); + FileWatcherManager::GetInstance().GetNotifyEvent(instance->data_); + LOGI("FfiOHOSFileFsWatcherStart success"); return SUCCESS_CODE; } @@ -579,7 +579,7 @@ int32_t FfiOHOSFileFsWatcherStop(int64_t id) return ERR_INVALID_INSTANCE_CODE; } LOGI("FS_TEST::FfiOHOSFileFsWatcherStart success"); - return instance->StopNotify(); + return FileWatcherManager::GetInstance().StopNotify(instance->data_); } } } // namespace FileFs diff --git a/interfaces/kits/cj/src/file_fs_impl.cpp b/interfaces/kits/cj/src/file_fs_impl.cpp index 973f49e73f0fa134b3a0a0a57aee580e1e6792fa..e647288fbfad0cc02da124e948be684e9cea7de6 100644 --- a/interfaces/kits/cj/src/file_fs_impl.cpp +++ b/interfaces/kits/cj/src/file_fs_impl.cpp @@ -40,6 +40,9 @@ std::tuple ParseFile(int32_t file) std::tuple ParseFile(std::string file) { std::unique_ptr filePath = std::make_unique(file.length() + 1); + if (!filePath) { + return { ENOMEM, FileInfo { true, nullptr, {} } }; + } for (size_t i = 0; i < file.length(); i++) { filePath[i] = file[i]; } @@ -77,7 +80,10 @@ std::tuple GetUvStat(const FileInfo& fileInfo) if (state != SUCCESS_CODE) { return { state, nullptr }; } - uv_stat_t* tempBuf = new uv_stat_t(stat_req->statbuf); + uv_stat_t* tempBuf = new (std::nothrow) uv_stat_t(stat_req->statbuf); + if (!tempBuf) { + return {ENOMEM, nullptr}; + } return {SUCCESS_CODE, tempBuf}; } @@ -85,16 +91,19 @@ std::tuple ParseRandomFile(std::string file) { LOGI("FS_TEST:: RandomAccessFileImpl::ParseRandomFile"); std::unique_ptr filePath = std::make_unique(file.length() + 1); + if (!filePath) { + return { false, FileInfo { true, nullptr, {} }, ENOMEM }; + } for (size_t i = 0; i < file.length(); i++) { filePath[i] = file[i]; } OHOS::DistributedFS::FDGuard sfd; auto fdg = CreateUniquePtr(sfd, false); if (fdg == nullptr) { - return { false, FileInfo { false, nullptr, nullptr }, ENOMEM}; + return { false, FileInfo { false, nullptr, nullptr }, ENOMEM }; } LOGI("FS_TEST:: RandomAccessFileImpl::ParseRandomFile success"); - return { true, FileInfo { true, move(filePath), move(fdg) }, ERRNO_NOERR}; + return { true, FileInfo { true, move(filePath), move(fdg) }, ERRNO_NOERR }; } std::tuple GetFsAccess(const FileInfo &fileInfo) @@ -126,7 +135,7 @@ std::tuple> FileFsImpl::Stat(int32_t file) auto [fileState, fileInfo] = ParseFile(file); if (fileState != SUCCESS_CODE) { - return {GetErrorCode(ENOMEM), nullptr}; + return {GetErrorCode(fileState), nullptr}; } auto [statState, stat] = GetUvStat(fileInfo); if (statState != SUCCESS_CODE) { @@ -322,6 +331,9 @@ int FileFsImpl::Rmdir(std::string path) { std::unique_ptr scandir_req = { new (std::nothrow) uv_fs_t, CommonFunc::FsReqCleanup }; + if (!scandir_req) { + return GetErrorCode(ENOMEM); + } int ret = 0; ret = uv_fs_scandir(nullptr, scandir_req.get(), path.c_str(), 0, nullptr); if (ret < 0) { @@ -464,11 +476,13 @@ struct NameListArg { static void Deleter(struct NameListArg *arg) { for (int i = 0; i < arg->num; i++) { - delete (arg->namelist)[i]; + free((arg->namelist)[i]); (arg->namelist)[i] = nullptr; } - delete arg->namelist; + free(arg->namelist); arg->namelist = nullptr; + delete arg; + arg = nullptr; } static int32_t FilterFunc(const struct dirent *filename) @@ -964,7 +978,7 @@ int FileFsImpl::Truncate(int32_t fd, int64_t len) { auto [fileState, fileInfo] = ParseFile(fd); if (fileState != SUCCESS_CODE) { - return GetErrorCode(EINVAL); + return GetErrorCode(fileState); } if (len < 0) { return GetErrorCode(EINVAL); @@ -1211,7 +1225,7 @@ std::tuple> FileFsImpl::CreateWatcher(std::string pat void (*callback)(CWatchEvent)) { std::shared_ptr infoArg = std::make_shared(callback); - if (!WatcherImpl::GetInstance().CheckEventValid(events)) { + if (!FileWatcherManager::GetInstance().CheckEventValid(events)) { return { GetErrorCode(EINVAL), nullptr }; } infoArg->events = events; @@ -1223,12 +1237,13 @@ std::tuple> FileFsImpl::CreateWatcher(std::string pat } watcherImpl->data_ = infoArg; - if (watcherImpl->GetNotifyId() < 0 && !watcherImpl->InitNotify()) { + if (FileWatcherManager::GetInstance().GetNotifyId() < 0 && + !FileWatcherManager::GetInstance().InitNotify()) { HILOGE("Failed to get notifyId or initnotify fail"); return { GetErrorCode(errno), nullptr }; } - bool ret = watcherImpl->AddWatcherInfo(infoArg->fileName, infoArg); + bool ret = FileWatcherManager::GetInstance().AddWatcherInfo(infoArg->fileName, infoArg); if (!ret) { HILOGE("Failed to add watcher info."); return {GetErrorCode(EINVAL), nullptr}; diff --git a/interfaces/kits/cj/src/file_impl.cpp b/interfaces/kits/cj/src/file_impl.cpp index f60a1580d6757432a35d6ed9957b5a9896310fab..56b2b362795d57de62a5bbecee4dd2a6ce104f03 100644 --- a/interfaces/kits/cj/src/file_impl.cpp +++ b/interfaces/kits/cj/src/file_impl.cpp @@ -211,9 +211,9 @@ std::tuple> FileEntity::Open(const char* path, int64_t return { ENOMEM, nullptr}; } auto fileUri = FFIData::Create(std::move(fileEntity->fd_), fileEntity->path_, fileEntity->uri_); + delete(fileEntity); + fileEntity = nullptr; if (!fileUri) { - delete(fileEntity); - fileEntity = nullptr; return {ENOMEM, nullptr}; } return {SUCCESS_CODE, fileUri}; @@ -229,9 +229,9 @@ std::tuple> FileEntity::Open(const char* path, int64_t return { ENOMEM, nullptr}; } auto filePath = FFIData::Create(std::move(file->fd_), file->path_, file->uri_); + delete(file); + file = nullptr; if (!filePath) { - delete(file); - file = nullptr; return {ENOMEM, nullptr}; } return {SUCCESS_CODE, filePath}; diff --git a/interfaces/kits/cj/src/list_file.cpp b/interfaces/kits/cj/src/list_file.cpp index 444e2abcc191ff879248500d6609d53ad7849770..1942675dbcc11bdd1eb88ccda39c75fe7ec0c401 100644 --- a/interfaces/kits/cj/src/list_file.cpp +++ b/interfaces/kits/cj/src/list_file.cpp @@ -203,6 +203,8 @@ static void Deleter(struct NameListArg *arg) } free(arg->namelist); arg->namelist = nullptr; + delete arg; + arg = nullptr; } static int FilterFileRes(const string &path, vector &dirents) @@ -267,7 +269,7 @@ static char** VectorToCArrString(vector &vec) break; } if (strcpy_s(result[i], vec[i].length() + 1, vec[i].c_str()) != 0) { - free(result[i]); + delete[] result[i]; result[i] = nullptr; break; } @@ -275,7 +277,7 @@ static char** VectorToCArrString(vector &vec) } if (temp != vec.size()) { for (size_t j = temp; j > 0; j--) { - free(result[j - 1]); + delete[] result[j - 1]; result[j - 1] = nullptr; } delete[] result; diff --git a/interfaces/kits/cj/src/randomAccessFile_impl.cpp b/interfaces/kits/cj/src/randomAccessFile_impl.cpp index ace5848757cfdeab612a0e5150aa6f499adbde37..65239dd456a423196c72919de1a193d9b36edd53 100644 --- a/interfaces/kits/cj/src/randomAccessFile_impl.cpp +++ b/interfaces/kits/cj/src/randomAccessFile_impl.cpp @@ -84,6 +84,10 @@ void RandomAccessFileImpl::CloseSync() { std::unique_ptr close_req = { new (std::nothrow) uv_fs_t, CommonFunc::FsReqCleanup }; + if (!close_req) { + LOGE("Failed to close file with ret: %{public}d", ENOMEM); + return; + } int ret = uv_fs_close(nullptr, close_req.get(), entity_->fd.get()->GetFD(), nullptr); if (ret < 0) { LOGE("Failed to close file with ret: %{public}d", ret); diff --git a/interfaces/kits/cj/src/stream_impl.cpp b/interfaces/kits/cj/src/stream_impl.cpp index a210b5ae69906b0994e9745e3d89e551740d1094..a26b4a2fc33cf833d94ed41c1ca3c1f7abd6cfbf 100644 --- a/interfaces/kits/cj/src/stream_impl.cpp +++ b/interfaces/kits/cj/src/stream_impl.cpp @@ -28,6 +28,9 @@ namespace FileFs { std::tuple, size_t> DecodeString(const std::string& buffer, const std::string& encode) { std::unique_ptr buf = std::make_unique(buffer.length() + 1); + if (!buf) { + return { ENOMEM, nullptr, 0}; + } for (size_t i = 0; i < buffer.length(); i++) { buf[i] = buffer[i]; diff --git a/interfaces/kits/cj/src/watcher_impl.cpp b/interfaces/kits/cj/src/watcher_impl.cpp index 82a7dfadbc1f51446f212d383a0b806d68f3f6a6..0e65570b4d6bab19a30eb6853c5c408fc4c3f726 100644 --- a/interfaces/kits/cj/src/watcher_impl.cpp +++ b/interfaces/kits/cj/src/watcher_impl.cpp @@ -14,33 +14,44 @@ */ #include "watcher_impl.h" +#include +#include +#include #include +#include "securec.h" using namespace OHOS::CJSystemapi::FileFs; namespace OHOS::CJSystemapi { using namespace std; -mutex WatcherImpl::watchMutex_; +mutex FileWatcherManager::watchMutex_; -WatcherImpl::WatcherImpl() {} +FileWatcherManager::FileWatcherManager() {} -int32_t WatcherImpl::GetNotifyId() +FileWatcherManager::~FileWatcherManager() {} + +int32_t FileWatcherManager::GetNotifyId() { return notifyFd_; } -bool WatcherImpl::InitNotify() +bool FileWatcherManager::InitNotify() { notifyFd_ = inotify_init(); if (notifyFd_ < 0) { LOGE("Failed to init notify errCode:%{public}d", errno); return false; } + eventFd_ = eventfd(0, EFD_CLOEXEC); + if (eventFd_ < 0) { + LOGE("Failed to init eventfd errCode:%{public}d", errno); + return false; + } return true; } -tuple WatcherImpl::CheckEventWatched(const string &fileName, const uint32_t &event) +tuple FileWatcherManager::CheckEventWatched(const string &fileName, const uint32_t &event) { int wd = -1; auto iter = wdFileNameMap_.find(fileName); @@ -54,12 +65,14 @@ tuple WatcherImpl::CheckEventWatched(const string &fileName, const ui return {false, wd}; } -bool WatcherImpl::AddWatcherInfo(const string &fileName, shared_ptr arg) +bool FileWatcherManager::AddWatcherInfo(const string &fileName, shared_ptr arg) { for (auto const &iter : watcherInfoSet_) { if (iter->fileName == arg->fileName && iter->events == arg->events) { - LOGE("Faile to add watcher, fileName:%{public}s the callback is same", fileName.c_str()); - return false; + if (iter->callbackId == arg->callbackId) { + LOGE("Faile to add watcher, fileName:%{public}s the callback is same", fileName.c_str()); + return false; + } } } watcherInfoSet_.insert(arg); @@ -74,7 +87,7 @@ bool CheckIncludeEvent(const uint32_t &mask, const uint32_t &event) return false; } -uint32_t WatcherImpl::RemoveWatcherInfo(shared_ptr arg) +uint32_t FileWatcherManager::RemoveWatcherInfo(shared_ptr arg) { watcherInfoSet_.erase(arg); uint32_t otherEvents = 0; @@ -86,36 +99,36 @@ uint32_t WatcherImpl::RemoveWatcherInfo(shared_ptr arg) return otherEvents; } -int32_t WatcherImpl::StartNotify() +int32_t FileWatcherManager::StartNotify(std::shared_ptr arg) { lock_guard lock(watchMutex_); if (notifyFd_ < 0) { LOGE("Failed to start notify notifyFd_:%{public}d", notifyFd_); return GetErrorCode(EIO); } - auto [isWatched, wd] = CheckEventWatched(data_->fileName, data_->events); + auto [isWatched, wd] = CheckEventWatched(arg->fileName, arg->events); if (isWatched && wd > 0) { - data_->wd = wd; + arg->wd = wd; return SUCCESS_CODE; } uint32_t watchEvents = 0; if (wd != -1) { - watchEvents = wdFileNameMap_[data_->fileName].second | data_->events; + watchEvents = wdFileNameMap_[arg->fileName].second | arg->events; } else { - watchEvents = data_->events; + watchEvents = arg->events; } - int newWd = inotify_add_watch(notifyFd_, data_->fileName.c_str(), watchEvents); + int newWd = inotify_add_watch(notifyFd_, arg->fileName.c_str(), watchEvents); if (newWd < 0) { LOGE("Failed to start notify errCode:%{public}d", errno); return GetErrorCode(errno); } - data_->wd = newWd; - wdFileNameMap_[data_->fileName].first = newWd; - wdFileNameMap_[data_->fileName].second = watchEvents; + arg->wd = newWd; + wdFileNameMap_[arg->fileName].first = newWd; + wdFileNameMap_[arg->fileName].second = watchEvents; return SUCCESS_CODE; } -int WatcherImpl::NotifyToWatchNewEvents(const string &fileName, const int &wd, const uint32_t &watchEvents) +int FileWatcherManager::NotifyToWatchNewEvents(const string &fileName, const int &wd, const uint32_t &watchEvents) { int newWd = inotify_add_watch(notifyFd_, fileName.c_str(), watchEvents); if (newWd < 0) { @@ -131,36 +144,55 @@ int WatcherImpl::NotifyToWatchNewEvents(const string &fileName, const int &wd, c return SUCCESS_CODE; } -void WatcherImpl::GetNotifyEvent() +void FileWatcherManager::ReadNotifyEvent(std::function callback) +{ + int len = 0; + int index = 0; + char buf[BUF_SIZE] = {0}; + struct inotify_event *event = nullptr; + while (((len = read(notifyFd_, &buf, sizeof(buf))) < 0) && (errno == EINTR)) {}; + while (index < len) { + event = reinterpret_cast(buf + index); + NotifyEvent(event, callback); + index += sizeof(struct inotify_event) + static_cast(event->len); + } +} + +void FileWatcherManager::GetNotifyEvent(std::shared_ptr arg) { if (run_) { return; } - run_ = true; - char buf[BUF_SIZE] = {0}; - struct inotify_event *event = nullptr; - fd_set fds; - FD_ZERO(&fds); - FD_SET(notifyFd_, &fds); - while (run_) { - if (notifyFd_ < 0) { - LOGE("Failed to run Listener Thread because notifyFd_:%{public}d", notifyFd_); - break; - } - if (select(notifyFd_ + 1, &fds, nullptr, nullptr, nullptr) > 0) { - int len = 0; - int index = 0; - while (((len = read(notifyFd_, &buf, sizeof(buf))) < 0) && (errno == EINTR)) {}; - while (index < len) { - event = reinterpret_cast(buf + index); - NotifyEvent(event); - index += static_cast(sizeof(struct inotify_event) + event->len); + auto fileListener = [this, arg]() { + run_ = true; + nfds_t nfds = 2; + struct pollfd fds[2]; + fds[0].fd = eventFd_; + fds[0].events = 0; + fds[1].fd = notifyFd_; + fds[1].events = POLLIN; + while (run_) { + int ret = poll(fds, nfds, -1); + if (ret > 0) { + if (static_cast(fds[0].revents) & POLLNVAL) { + run_ = false; + return; + } + if (static_cast(fds[1].revents) & POLLIN) { + ReadNotifyEvent(arg->watchCallback_); + } + } else if (ret < 0 && errno == EINTR) { + continue; + } else { + LOGE("Failed to poll NotifyFd, errno=%{public}d", errno); + return; } } - } + }; + std::thread(fileListener).detach(); } -void WatcherImpl::NotifyEvent(const struct inotify_event *event) +void FileWatcherManager::NotifyEvent(const struct inotify_event *event, std::function callback) { lock_guard lock(watchMutex_); string tempFileName; @@ -185,14 +217,26 @@ void WatcherImpl::NotifyEvent(const struct inotify_event *event) fileName += "/" + string(event->name); } CWatchEvent ret = { - .fileName = fileName.c_str(), + .fileName = nullptr, .event = event->mask & IN_ALL_EVENTS, .cookie = event->cookie }; - data_->watchCallback_(ret); + int len = fileName.size() + 1; + ret.fileName = (char*)malloc(len); + if (ret.fileName == nullptr) { + LOGE("Failed to create WatchEvent"); + continue; + } + int errCode = memcpy_s(ret.fileName, len, fileName.c_str(), len); + if (errCode != 0) { + LOGE("Failed to get file name"); + continue; + } + callback(ret); + free(ret.fileName); } } -int WatcherImpl::CloseNotifyFd() +int FileWatcherManager::CloseNotifyFd() { int closeRet = SUCCESS_CODE; if (watcherInfoSet_.size() == 0) { @@ -201,37 +245,46 @@ int WatcherImpl::CloseNotifyFd() LOGE("Failed to stop notify close fd errCode:%{public}d", closeRet); } notifyFd_ = -1; + closeRet = close(eventFd_); + if (closeRet != 0) { + LOGE("Failed to close eventfd errCode:%{public}d", closeRet); + } + eventFd_ = -1; run_ = false; } return closeRet; } -int32_t WatcherImpl::StopNotify() +int32_t FileWatcherManager::StopNotify(std::shared_ptr arg) { unique_lock lock(watchMutex_); if (notifyFd_ < 0) { LOGE("Failed to stop notify notifyFd_:%{public}d", notifyFd_); return EIO; } - uint32_t newEvents = RemoveWatcherInfo(data_); + uint32_t newEvents = RemoveWatcherInfo(arg); if (newEvents > 0) { - return NotifyToWatchNewEvents(data_->fileName, data_->wd, newEvents); + if (access(arg->fileName.c_str(), F_OK) == 0) { + return NotifyToWatchNewEvents(arg->fileName, arg->wd, newEvents); + } + LOGE("The Watched file does not exist, and the remaining monitored events will be invalid."); + return SUCCESS_CODE; } - if (inotify_rm_watch(notifyFd_, data_->wd) == -1) { + if (inotify_rm_watch(notifyFd_, arg->wd) == -1) { int rmErr = errno; - if (access(data_->fileName.c_str(), F_OK) == 0) { + if (access(arg->fileName.c_str(), F_OK) == 0) { LOGE("Failed to stop notify errCode:%{public}d", rmErr); - wdFileNameMap_.erase(data_->fileName); + wdFileNameMap_.erase(arg->fileName); CloseNotifyFd(); return rmErr; } } - wdFileNameMap_.erase(data_->fileName); + wdFileNameMap_.erase(arg->fileName); return CloseNotifyFd(); } -bool WatcherImpl::CheckEventValid(const uint32_t &event) +bool FileWatcherManager::CheckEventValid(const uint32_t &event) { if ((event & IN_ALL_EVENTS) == event) { return true; diff --git a/interfaces/kits/cj/src/watcher_impl.h b/interfaces/kits/cj/src/watcher_impl.h index cb51f0a607a7dec06f53b0af060b9be2bbfc8e2a..68964fe27004f97ba1f739e5606cd1ee89e0f9b0 100644 --- a/interfaces/kits/cj/src/watcher_impl.h +++ b/interfaces/kits/cj/src/watcher_impl.h @@ -32,7 +32,7 @@ namespace CJSystemapi { constexpr int BUF_SIZE = 1024; struct CWatchEvent { - const char* fileName; + char* fileName; uint32_t event; uint32_t cookie; }; @@ -40,31 +40,50 @@ struct WatcherInfoArg { std::string fileName = ""; uint32_t events = 0; int wd = -1; + int64_t callbackId = -1; std::function watchCallback_; explicit WatcherInfoArg(void (*callback)(CWatchEvent)) { watchCallback_ = CJLambda::Create(callback); + callbackId = reinterpret_cast(callback); } ~WatcherInfoArg() = default; }; -class WatcherImpl : public OHOS::FFI::FFIData, public Singleton { +class WatcherImpl : public OHOS::FFI::FFIData { public: std::shared_ptr data_; - WatcherImpl(); + OHOS::FFI::RuntimeType* GetRuntimeType() override { return GetClassType(); } +private: + friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::TypeBase; + static OHOS::FFI::RuntimeType* GetClassType() + { + static OHOS::FFI::RuntimeType runtimeType = OHOS::FFI::RuntimeType::Create("WatcherImpl"); + return &runtimeType; + } +}; + +class FileWatcherManager : public Singleton { +public: + FileWatcherManager(); + ~FileWatcherManager(); + FileWatcherManager(FileWatcherManager const &) = delete; + void operator=(FileWatcherManager const &) = delete; + int32_t GetNotifyId(); bool InitNotify(); bool AddWatcherInfo(const std::string &fileName, std::shared_ptr arg); bool CheckEventValid(const uint32_t &event); - int32_t StartNotify(); - void GetNotifyEvent(); - int32_t StopNotify(); + int32_t StartNotify(std::shared_ptr arg); + void GetNotifyEvent(std::shared_ptr arg); + void ReadNotifyEvent(std::function callback); + int32_t StopNotify(std::shared_ptr arg); - OHOS::FFI::RuntimeType* GetRuntimeType() override { return GetClassType(); } private: uint32_t RemoveWatcherInfo(std::shared_ptr arg); std::tuple CheckEventWatched(const std::string &fileName, const uint32_t &event); - void NotifyEvent(const struct inotify_event *event); + void NotifyEvent(const struct inotify_event *event, std::function callback); int CloseNotifyFd(); int NotifyToWatchNewEvents(const std::string &fileName, const int &wd, const uint32_t &watchEvents); @@ -72,16 +91,9 @@ private: static std::mutex watchMutex_; bool run_ = false; int32_t notifyFd_ = -1; + int32_t eventFd_ = -1; std::unordered_set> watcherInfoSet_; std::unordered_map> wdFileNameMap_; - - friend class OHOS::FFI::RuntimeType; - friend class OHOS::FFI::TypeBase; - static OHOS::FFI::RuntimeType* GetClassType() - { - static OHOS::FFI::RuntimeType runtimeType = OHOS::FFI::RuntimeType::Create("WatcherImpl"); - return &runtimeType; - } }; } // OHOS::FileManagement::ModuleFileIO } diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index fa41f4cb38194db0b7d26874dc8f26aa956220e2..d1e895ed637accc50e96235fe86dc2088be301ba 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -214,7 +214,6 @@ ohos_shared_library("fs") { sources += [ "src/mod_fs/class_randomaccessfile/randomaccessfile_n_exporter.cpp", "src/mod_fs/class_readeriterator/readeriterator_n_exporter.cpp", - "src/mod_fs/class_stream/flush.cpp", "src/mod_fs/class_stream/stream_n_exporter.cpp", "src/mod_fs/class_tasksignal/task_signal_entity.cpp", "src/mod_fs/class_tasksignal/task_signal_n_exporter.cpp", @@ -255,6 +254,7 @@ ohos_shared_library("fs") { "data_share:datashare_common", "data_share:datashare_consumer", "dfs_service:distributed_file_daemon_kit_inner", + "hisysevent:libhisysevent", "hitrace:hitrace_meter", "ipc:ipc_core", "samgr:samgr_proxy", diff --git a/interfaces/kits/js/src/common/dfs_event_dfx.h b/interfaces/kits/js/src/common/dfs_event_dfx.h new file mode 100644 index 0000000000000000000000000000000000000000..ba3d423b2da4e48694f54aaa3fc50826e221ad86 --- /dev/null +++ b/interfaces/kits/js/src/common/dfs_event_dfx.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTEDFILE_DFS_EVENT_DFX_H +#define DISTRIBUTEDFILE_DFS_EVENT_DFX_H + +#include "hisysevent.h" +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace RadarReporter { +using namespace OHOS::HiviewDFX; +static constexpr int DIST_DATA_MGR_SYS_ID = 0xd; +static constexpr int DFS_ID = 13; +enum BizScene : std::int32_t { + DFX_SET_DFS = 1, +}; + +enum BizStageSetDfs : std::int32_t { + DFX_SET_BIZ_SCENE = 1, +}; + +enum StageRes : std::int32_t { + DFX_IDLE = 0, + DFX_SUCCESS = 1, + DFX_FAILED = 2, + DFX_CANCELLED = 3, +}; + +enum BizState : std::int32_t { + DFX_BEGIN = 1, + DFX_END = 2, +}; + +enum ErrorCode : std::int32_t { + DFS_ERROR = (DIST_DATA_MGR_SYS_ID << 21) | (DFS_ID << 16), + PREPARE_COPY_SESSION_ERROR, + COPY_TO_SANDBOX_ERROR, + SEND_FILE_ERROR, +}; + +static constexpr char DOMAIN[] = "DISTDATAMGR"; +constexpr const char* EVENT_NAME = "DISTRIBUTED_DFS_BEHAVIOR"; +constexpr const char* ORG_PKG = "distributedfile"; +constexpr const char* BIZ_STATE = "BIZ_STATE"; +constexpr const char* ERROR_CODE = "ERROR_CODE"; +constexpr const char* PACKAGE_NAME = "PACKAGE_NAME"; +constexpr const char* CONCURRENT_ID = "CONCURRENT_ID"; +static constexpr HiviewDFX::HiSysEvent::EventType TYPE = HiviewDFX::HiSysEvent::EventType::BEHAVIOR; + +#define RADAR_REPORT(bizScene, bizStage, stageRes, ...) \ +({ \ + HiSysEventWrite(RadarReporter::DOMAIN, RadarReporter::EVENT_NAME, RadarReporter::TYPE, \ + "ORG_PKG", RadarReporter::ORG_PKG, "FUNC", __FUNCTION__, \ + "BIZ_SCENE", bizScene, "BIZ_STAGE", bizStage, "STAGE_RES", stageRes, \ + ##__VA_ARGS__); \ +}) +} // namespace RadarReporter +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif //DISTRIBUTEDFILE_DFS_EVENT_DFX_H \ No newline at end of file diff --git a/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.cpp b/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.cpp index be644d529d6a40c1d163b249422ed96e8290fe2d..75136db63bd81f8e8864c21c924c5e105ab50406 100644 --- a/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.cpp +++ b/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.cpp @@ -22,7 +22,14 @@ using namespace std; NAsyncWorkCallback::NAsyncWorkCallback(napi_env env, NVal thisPtr, NVal cb) : NAsyncWorkFactory(env) { - ctx_ = new NAsyncContextCallback(thisPtr, cb); + ctx_ = new(std::nothrow) NAsyncContextCallback(thisPtr, cb); +} +NAsyncWorkCallback::~NAsyncWorkCallback() +{ + if (!ctx_) { + return; + } + delete ctx_; } static void CallbackExecute(napi_env env, void *data) @@ -71,7 +78,7 @@ static void CallbackComplete(napi_env env, napi_status status, void *data) NVal NAsyncWorkCallback::Schedule(string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete) { - if (!ctx_->cb_ || !ctx_->cb_.Deref(env_).TypeIs(napi_function)) { + if (!ctx_ || !ctx_->cb_ || !ctx_->cb_.Deref(env_).TypeIs(napi_function)) { HILOGE("The callback shall be a function"); UniError(EINVAL).ThrowErr(env_); return NVal(); diff --git a/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.h b/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.h index 9bc6d5f3d7b7125e50fda9baedb4d70f2b397003..1b78939eb2cd473ff1b3032cfd84af35b9a07dea 100644 --- a/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.h +++ b/interfaces/kits/js/src/common/napi/n_async/n_async_work_callback.h @@ -23,7 +23,7 @@ namespace DistributedFS { class NAsyncWorkCallback : public NAsyncWorkFactory { public: NAsyncWorkCallback(napi_env env, NVal thisPtr, NVal cb); - ~NAsyncWorkCallback() = default; + ~NAsyncWorkCallback() override; NVal Schedule(std::string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete) final; diff --git a/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.cpp b/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.cpp index 978096042049ff119f58a94e75f6ac166c2ddb8a..1ba6a0fdb0d2339bca96cfff86975fe37c4f2894 100644 --- a/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.cpp +++ b/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.cpp @@ -22,7 +22,7 @@ using namespace std; NAsyncWorkPromise::NAsyncWorkPromise(napi_env env, NVal thisPtr) : NAsyncWorkFactory(env) { - ctx_ = new NAsyncContextPromise(thisPtr); + ctx_ = new(std::nothrow) NAsyncContextPromise(thisPtr); } static void PromiseOnExec(napi_env env, void *data) @@ -63,6 +63,10 @@ static void PromiseOnComplete(napi_env env, napi_status status, void *data) NVal NAsyncWorkPromise::Schedule(string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete) { + if (ctx_ == nullptr) { + HILOGE("ctx is nullptr"); + return NVal(); + } ctx_->cbExec_ = move(cbExec); ctx_->cbComplete_ = move(cbComplete); diff --git a/interfaces/kits/js/src/common/napi/n_async/n_ref.cpp b/interfaces/kits/js/src/common/napi/n_async/n_ref.cpp index 8b78ac9c8462575d69240e68e3c7efdd5a080b8d..3509b6fdf3aed68a22ecf5b61264e2faaef1fd89 100644 --- a/interfaces/kits/js/src/common/napi/n_async/n_ref.cpp +++ b/interfaces/kits/js/src/common/napi/n_async/n_ref.cpp @@ -29,7 +29,7 @@ NRef::NRef(NVal val) NRef::~NRef() { - if (ref_) { + if (ref_ && env_) { napi_delete_reference(env_, ref_); } } @@ -41,7 +41,7 @@ NRef::operator bool() const NVal NRef::Deref(napi_env env) { - if (!ref_) { + if (!ref_ || !env) { return NVal(); } diff --git a/interfaces/kits/js/src/common/napi/n_class.cpp b/interfaces/kits/js/src/common/napi/n_class.cpp index cde1e0b94ce4ee4a6016add57cfcae2a5eca4ed1..191fefc0de2694d4329c5565d53f77f15b3306a6 100644 --- a/interfaces/kits/js/src/common/napi/n_class.cpp +++ b/interfaces/kits/js/src/common/napi/n_class.cpp @@ -72,7 +72,7 @@ bool NClass::SaveClass(napi_env env, string className, napi_value exClass) napi_value NClass::InstantiateClass(napi_env env, const string& className, const vector& args) { NClass &nClass = NClass::GetInstance(); - lock_guard(nClass.exClassMapLock); + lock_guard lock(nClass.exClassMapLock); auto it = nClass.exClassMap.find(className); if (it == nClass.exClassMap.end()) { HILOGE("Class %{public}s hasn't been saved yet", className.c_str()); diff --git a/interfaces/kits/js/src/common/uni_error.cpp b/interfaces/kits/js/src/common/uni_error.cpp index 93d5e46acc9d2077c3e84eb4f395e3df27164b6e..e7a81705ed650530b5bc109fde14e7da11e82178 100644 --- a/interfaces/kits/js/src/common/uni_error.cpp +++ b/interfaces/kits/js/src/common/uni_error.cpp @@ -103,9 +103,10 @@ napi_value UniError::GetNapiErr(napi_env env) } int32_t code; string msg; - if (errCodeTable.find(errCode) != errCodeTable.end()) { - code = errCodeTable.at(errCode).first; - msg = errCodeTable.at(errCode).second; + auto it = errCodeTable.find(errCode); + if (it != errCodeTable.end()) { + code = it->second.first; + msg = it->second.second; } else { code = errCodeTable.at(-1).first; msg = errCodeTable.at(-1).second; @@ -131,9 +132,10 @@ void UniError::ThrowErr(napi_env env) int32_t code; string msg; napi_status throwStatus = napi_ok; - if (errCodeTable.find(errno_) != errCodeTable.end()) { - code = errCodeTable.at(errno_).first; - msg = errCodeTable.at(errno_).second; + auto it = errCodeTable.find(errno_); + if (it != errCodeTable.end()) { + code = it->second.first; + msg = it->second.second; } else { code = errCodeTable.at(-1).first; msg = errCodeTable.at(-1).second; @@ -143,7 +145,7 @@ void UniError::ThrowErr(napi_env env) } else { throwStatus = napi_throw(env, GenerateBusinessError(env, code, msg)); } - + if (throwStatus != napi_ok) { HILOGE("Failed to throw an exception, %{public}d, code = %{public}s", throwStatus, msg.c_str()); } diff --git a/interfaces/kits/js/src/mod_file/class_file/file_n_exporter.cpp b/interfaces/kits/js/src/mod_file/class_file/file_n_exporter.cpp index 4a0dc77721e569bc9af6d30f4787201e68526885..972c56b50e24e06c9da0c230609323ca6dfcc464 100644 --- a/interfaces/kits/js/src/mod_file/class_file/file_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_file/class_file/file_n_exporter.cpp @@ -1304,12 +1304,18 @@ napi_value FileNExporter::WriteArrayBuffer(napi_env env, napi_callback_info info napi_ref bufferRef = nullptr; NVal bufNapi = NVal(env, funcArg[NARG_POS::FIRST]).GetProp("buffer"); tie(succ, buffer, bufLength) = bufNapi.ToTypedArray(); - napi_create_reference(env, bufNapi.val_, 1, &bufferRef); + napi_status status = napi_create_reference(env, bufNapi.val_, 1, &bufferRef); + if (status != napi_ok) { + UniError(EINVAL).ThrowErr(env, "Failed to create reference to buffer"); + delete asyncCallbackInfo; + return nullptr; + } string path = (uri == nullptr) ? "" : uri.get(); if (!CheckUri(env, path)) { CallBackError(env, asyncCallbackInfo->callback[COMMON_NUM::ONE], "illegal uri", URI_PARAMER_ERROR); CallComplete(env, asyncCallbackInfo->callback[COMMON_NUM::TWO]); + napi_delete_reference(env, bufferRef); delete asyncCallbackInfo; return nullptr; } diff --git a/interfaces/kits/js/src/mod_fs/class_file/file_entity.h b/interfaces/kits/js/src/mod_fs/class_file/file_entity.h index fb3b816559932e9c5d7c2a2b7f7618dd41a816e3..4531f36a81bef0d7f7aa3af110573c42cc8e7e09 100644 --- a/interfaces/kits/js/src/mod_fs/class_file/file_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_file/file_entity.h @@ -30,25 +30,10 @@ namespace FileManagement { namespace ModuleFileIO { struct FileEntity { std::unique_ptr fd_ = { nullptr }; - std::string path_; - std::string uri_; + std::string path_ = ""; + std::string uri_ = ""; #ifndef WIN_PLATFORM - virtual ~FileEntity() - { - if (!fd_.get()) { - return; - } - int32_t fd = fd_.get()->GetFD(); - int ret = flock(fd, LOCK_UN); - if (ret == 0) { - struct stat buf; - if (fstat(fd, &buf) == 0) { - HILOGD("Unlock succeeded inode = %{public}" PRIu64, buf.st_ino); - } else { - HILOGE("Failed to get inode number, error: %{public}d", errno); - } - } - } + virtual ~FileEntity() {}; #endif }; } // namespace ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.cpp index 4b7bf13bafb4eadb914b2d8b69f09c4d8286158d..f323319c16da6ad8ed770b2c438e05914d25b935 100644 --- a/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_file/file_n_exporter.cpp @@ -116,7 +116,7 @@ napi_value FileNExporter::GetPath(napi_env env, napi_callback_info info) } auto [realPathRes, realPath] = RealPathCore(fileEntity->path_); if (realPathRes != ERRNO_NOERR) { - HILOGE("Failed to get real path, ret: %{public}d", realPathRes); + HILOGE("Failed to get real path"); NError(realPathRes).ThrowErr(env); return nullptr; } @@ -143,7 +143,7 @@ napi_value FileNExporter::GetName(napi_env env, napi_callback_info info) } auto [realPathRes, realPath] = RealPathCore(fileEntity->path_); if (realPathRes != ERRNO_NOERR) { - HILOGE("Failed to get real path, ret: %{public}d", realPathRes); + HILOGE("Failed to get real path"); NError(realPathRes).ThrowErr(env); return nullptr; } @@ -179,7 +179,7 @@ napi_value FileNExporter::GetParent(napi_env env, napi_callback_info info) } else { auto [realPathRes, realPath] = RealPathCore(path); if (realPathRes) { - HILOGE("Failed to get real path, ret: %{public}d", realPathRes); + HILOGE("Failed to get real path"); NError(realPathRes).ThrowErr(env); return nullptr; } diff --git a/interfaces/kits/js/src/mod_fs/class_stream/flush.cpp b/interfaces/kits/js/src/mod_fs/class_stream/flush.cpp deleted file mode 100755 index 105eab7bae4f85d7b8704967f58955742d78fcd5..0000000000000000000000000000000000000000 --- a/interfaces/kits/js/src/mod_fs/class_stream/flush.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "flush.h" - -#include -#include - -#include "class_stat/stat_entity.h" -#include "class_stat/stat_n_exporter.h" -#include "filemgmt_libhilog.h" -#include "stream_entity.h" - -namespace OHOS { -namespace FileManagement { -namespace ModuleFileIO { -using namespace std; -using namespace OHOS::FileManagement::LibN; - -napi_value Flush::Sync(napi_env env, napi_callback_info info) -{ - NFuncArg funcArg(env, info); - if (!funcArg.InitArgs(NARG_CNT::ZERO)) { - HILOGE("Number of arguments unmatched"); - NError(EINVAL).ThrowErr(env); - return nullptr; - } - - auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); - if (!streamEntity || !streamEntity->fp) { - HILOGE("Failed to get entity of Stream"); - NError(EIO).ThrowErr(env); - return nullptr; - } - - int ret = fflush(streamEntity->fp.get()); - if (ret < 0) { - HILOGE("Failed to fflush file in the stream, ret: %{public}d", ret); - NError(errno).ThrowErr(env); - return nullptr; - } - return NVal::CreateUndefined(env).val_; -} - -napi_value Flush::Async(napi_env env, napi_callback_info info) -{ - NFuncArg funcArg(env, info); - if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { - HILOGE("Number of arguments unmatched"); - NError(EINVAL).ThrowErr(env); - return nullptr; - } - - auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); - if (!streamEntity || !streamEntity->fp) { - HILOGE("Failed to get entity of Stream"); - NError(EIO).ThrowErr(env); - return nullptr; - } - - auto cbExec = [streamEntity]() -> NError { - if (!streamEntity || !streamEntity->fp) { - HILOGE("Stream has been closed in flush cbExec possibly"); - return NError(EIO); - } - int ret = fflush(streamEntity->fp.get()); - if (ret < 0) { - HILOGE("Failed to fflush file in the stream"); - return NError(errno); - } else { - return NError(ERRNO_NOERR); - } - }; - auto cbCompl = [](napi_env env, NError err) -> NVal { - if (err) { - return { env, err.GetNapiErr(env) }; - } - return { NVal::CreateUndefined(env) }; - }; - - NVal thisVar(env, funcArg.GetThisVar()); - if (funcArg.GetArgc() == NARG_CNT::ZERO) { - return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_STREAM_FLUSH_NAME, cbExec, cbCompl).val_; - } else { - NVal cb(env, funcArg[NARG_POS::FIRST]); - return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_STREAM_FLUSH_NAME, cbExec, cbCompl).val_; - } -} -} // namespace ModuleFileIO -} // namespace FileManagement -} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_stream/flush.h b/interfaces/kits/js/src/mod_fs/class_stream/flush.h deleted file mode 100755 index aa7be7012cdc5ecf146f7b23bd6006e1c8d0ed43..0000000000000000000000000000000000000000 --- a/interfaces/kits/js/src/mod_fs/class_stream/flush.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_STREAM_FLUSH_H -#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_STREAM_FLUSH_H - -#include "filemgmt_libn.h" - -namespace OHOS { -namespace FileManagement { -namespace ModuleFileIO { -class Flush final { -public: - static napi_value Async(napi_env env, napi_callback_info info); - static napi_value Sync(napi_env env, napi_callback_info info); -}; - -const std::string PROCEDURE_STREAM_FLUSH_NAME = "FileIOStreamFlush"; -} // namespace ModuleFileIO -} // namespace FileManagement -} // namespace namespace OHOS -#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_STREAM_FLUSH_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h b/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h index 11cdae1dc8c70fa34f5804158e6b4c575a94ac5e..e42c21e087548d9f24c893da868cda130585b139 100755 --- a/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h +++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_entity.h @@ -16,11 +16,12 @@ #ifndef INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STREAM_STREAM_ENTITY_H #define INTERFACES_KITS_JS_SRC_MOD_FILEIO_CLASS_STREAM_STREAM_ENTITY_H +#include namespace OHOS { namespace FileManagement { namespace ModuleFileIO { struct StreamEntity { - std::unique_ptr fp = { nullptr, fclose }; + std::shared_ptr fp{ nullptr }; }; } // namespace ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp index d220521a95c116b27a5d64c3156a2effa5280bce..a166a05f1b5d73bd0b2e7b0a8c99dbe8e36ff3dc 100644 --- a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp @@ -27,7 +27,6 @@ #include "common_func.h" #include "file_utils.h" #include "filemgmt_libhilog.h" -#include "flush.h" #include "rust_file.h" #include "stream_entity.h" @@ -36,6 +35,87 @@ namespace FileManagement { namespace ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; +std::mutex StreamNExporter::mutex; +std::shared_ptr StreamNExporter::GetFilePtr(StreamEntity *streamEntity) +{ + std::lock_guard lock(mutex); + if (streamEntity) { + return streamEntity->fp; + } + return nullptr; +} + +napi_value StreamNExporter::FlushSync(napi_env env, napi_callback_info cbInfo) +{ + NFuncArg funcArg(env, cbInfo); + if (!funcArg.InitArgs(NARG_CNT::ZERO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + auto fp = GetFilePtr(streamEntity); + if (fp == nullptr) { + HILOGE("Failed to get entity of Stream"); + NError(EIO).ThrowErr(env); + return nullptr; + } + + int ret = fflush(fp.get()); + if (ret < 0) { + HILOGE("Failed to fflush file in the stream, ret: %{public}d", ret); + NError(errno).ThrowErr(env); + return nullptr; + } + return NVal::CreateUndefined(env).val_; +} + +napi_value StreamNExporter::Flush(napi_env env, napi_callback_info cbInfo) +{ + NFuncArg funcArg(env, cbInfo); + if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + auto fp = GetFilePtr(streamEntity); + if (fp == nullptr) { + HILOGE("Failed to get entity of Stream"); + NError(EIO).ThrowErr(env); + return nullptr; + } + + auto cbExec = [fp]() -> NError { + if (!fp) { + HILOGE("Stream has been closed in flush cbExec possibly"); + return NError(EIO); + } + int ret = fflush(fp.get()); + if (ret < 0) { + HILOGE("Failed to fflush file in the stream"); + return NError(errno); + } else { + return NError(ERRNO_NOERR); + } + }; + auto cbCompl = [](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return { NVal::CreateUndefined(env) }; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ZERO) { + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_STREAM_FLUSH_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::FIRST]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_STREAM_FLUSH_NAME, cbExec, cbCompl).val_; + } +} napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info cbInfo) { @@ -47,13 +127,13 @@ napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info cbInfo) } auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); - if (!streamEntity || !streamEntity->fp) { + + auto fp = GetFilePtr(streamEntity); + if (fp == nullptr) { HILOGE("Failed to get entity of Stream"); NError(EIO).ThrowErr(env); return nullptr; } - FILE *filp = nullptr; - filp = streamEntity->fp.get(); auto [succ, buf, len, offset] = CommonFunc::GetReadArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); @@ -63,7 +143,7 @@ napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info cbInfo) } if (offset >= 0) { - int ret = fseek(filp, static_cast(offset), SEEK_SET); + int ret = fseek(fp.get(), static_cast(offset), SEEK_SET); if (ret < 0) { HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); NError(errno).ThrowErr(env); @@ -71,8 +151,8 @@ napi_value StreamNExporter::ReadSync(napi_env env, napi_callback_info cbInfo) } } - size_t actLen = fread(buf, 1, len, filp); - if ((actLen != static_cast(len) && !feof(filp)) || ferror(filp)) { + size_t actLen = fread(buf, 1, len, fp.get()); + if ((actLen != static_cast(len) && !feof(fp.get())) || ferror(fp.get())) { HILOGE("Invalid buffer size and pointer, actlen: %{public}zu", actLen); NError(EIO).ThrowErr(env); return nullptr; @@ -89,16 +169,16 @@ napi_value StreamNExporter::CloseSync(napi_env env, napi_callback_info cbInfo) NError(EINVAL).ThrowErr(env); return nullptr; } - auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); - if (!streamEntity || !streamEntity->fp) { - HILOGE("Failed to get entity of Stream"); + if (!streamEntity) { + HILOGE("Failed to get entity of Stream, may closed twice"); NError(EIO).ThrowErr(env); return nullptr; } - streamEntity->fp.reset(); - (void)NClass::RemoveEntityOfFinal(env, funcArg.GetThisVar()); - + { + std::lock_guard lock(mutex); + (void)NClass::RemoveEntityOfFinal(env, funcArg.GetThisVar()); + } return NVal::CreateUndefined(env).val_; } @@ -112,13 +192,12 @@ napi_value StreamNExporter::WriteSync(napi_env env, napi_callback_info cbInfo) } auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); - if (!streamEntity || !streamEntity->fp) { + auto fp = GetFilePtr(streamEntity); + if (fp == nullptr) { HILOGE("Failed to get entity of Stream"); NError(EIO).ThrowErr(env); return nullptr; } - FILE *filp = nullptr; - filp = streamEntity->fp.get(); auto [succ, bufGuard, buf, len, offset] = CommonFunc::GetWriteArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); @@ -127,7 +206,7 @@ napi_value StreamNExporter::WriteSync(napi_env env, napi_callback_info cbInfo) return nullptr; } if (offset >= 0) { - int ret = fseek(filp, static_cast(offset), SEEK_SET); + int ret = fseek(fp.get(), static_cast(offset), SEEK_SET); if (ret < 0) { HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); NError(errno).ThrowErr(env); @@ -135,7 +214,7 @@ napi_value StreamNExporter::WriteSync(napi_env env, napi_callback_info cbInfo) } } - size_t writeLen = fwrite(buf, 1, len, filp); + size_t writeLen = fwrite(buf, 1, len, fp.get()); if ((writeLen == 0) && (writeLen != len)) { HILOGE("Failed to fwrite stream"); NError(EIO).ThrowErr(env); @@ -145,7 +224,7 @@ napi_value StreamNExporter::WriteSync(napi_env env, napi_callback_info cbInfo) return NVal::CreateInt64(env, static_cast(writeLen)).val_; } -static napi_value WriteExec(napi_env env, NFuncArg &funcArg, StreamEntity *streamEntity) +static napi_value WriteExec(napi_env env, NFuncArg &funcArg, shared_ptr fp) { auto [succ, bufGuard, buf, len, offset] = CommonFunc::GetWriteArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); @@ -160,19 +239,19 @@ static napi_value WriteExec(napi_env env, NFuncArg &funcArg, StreamEntity *strea NError(ENOMEM).ThrowErr(env); return nullptr; } - auto cbExec = [arg, buf = buf, len = len, streamEntity, offset = offset]() -> NError { - if (!streamEntity || !streamEntity->fp.get()) { + auto cbExec = [arg, buf = buf, len = len, fp, offset = offset]() -> NError { + if (!fp.get()) { HILOGE("Stream has been closed in write cbExec possibly"); return NError(EIO); } if (offset >= 0) { - int ret = fseek(streamEntity->fp.get(), static_cast(offset), SEEK_SET); + int ret = fseek(fp.get(), static_cast(offset), SEEK_SET); if (ret < 0) { HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); return NError(errno); } } - arg->actLen = fwrite(buf, 1, len, streamEntity->fp.get()); + arg->actLen = fwrite(buf, 1, len, fp.get()); if ((arg->actLen == 0) && (arg->actLen != len)) { HILOGE("Failed to fwrite stream"); return NError(EIO); @@ -186,7 +265,6 @@ static napi_value WriteExec(napi_env env, NFuncArg &funcArg, StreamEntity *strea } return { NVal::CreateInt64(env, static_cast(arg->actLen)) }; }; - NVal thisVar(env, funcArg.GetThisVar()); if (funcArg.GetArgc() == NARG_CNT::ONE || (funcArg.GetArgc() == NARG_CNT::TWO && !NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_function))) { @@ -208,15 +286,16 @@ napi_value StreamNExporter::Write(napi_env env, napi_callback_info cbInfo) } auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); - if (!streamEntity || !streamEntity->fp) { - HILOGD("Failed to get entity of Stream"); + auto fp = GetFilePtr(streamEntity); + if (fp == nullptr) { + HILOGE("Failed to get entity of Stream"); NError(EIO).ThrowErr(env); return nullptr; } - return WriteExec(env, funcArg, streamEntity); + return WriteExec(env, funcArg, fp); } -static napi_value ReadExec(napi_env env, NFuncArg &funcArg, StreamEntity *streamEntity) +static napi_value ReadExec(napi_env env, NFuncArg &funcArg, shared_ptr fp) { auto [succ, buf, len, offset] = CommonFunc::GetReadArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); @@ -232,19 +311,19 @@ static napi_value ReadExec(napi_env env, NFuncArg &funcArg, StreamEntity *stream NError(ENOMEM).ThrowErr(env); return nullptr; } - auto cbExec = [arg, buf = buf, len = len, streamEntity, offset = offset]() -> NError { - if (!streamEntity || !streamEntity->fp.get()) { + auto cbExec = [arg, buf = buf, len = len, fp, offset = offset]() -> NError { + if (!fp.get()) { HILOGE("Stream has been closed in read cbExec possibly"); return NError(EIO); } if (offset >= 0) { - if (fseek(streamEntity->fp.get(), static_cast(offset), SEEK_SET) < 0) { + if (fseek(fp.get(), static_cast(offset), SEEK_SET) < 0) { HILOGE("Failed to set the offset location of the file stream pointer"); return NError(errno); } } - size_t actLen = fread(buf, 1, len, streamEntity->fp.get()); - if ((actLen != static_cast(len) && !feof(streamEntity->fp.get())) || ferror(streamEntity->fp.get())) { + size_t actLen = fread(buf, 1, len, fp.get()); + if ((actLen != static_cast(len) && !feof(fp.get())) || ferror(fp.get())) { HILOGE("Invalid buffer size and pointer, actlen: %{public}zu", actLen); return NError(EIO); } else { @@ -281,12 +360,13 @@ napi_value StreamNExporter::Read(napi_env env, napi_callback_info cbInfo) } auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); - if (!streamEntity || !streamEntity->fp) { + auto fp = GetFilePtr(streamEntity); + if (fp == nullptr) { HILOGE("Failed to get entity of Stream"); NError(EIO).ThrowErr(env); return nullptr; } - return ReadExec(env, funcArg, streamEntity); + return ReadExec(env, funcArg, fp); } napi_value StreamNExporter::Close(napi_env env, napi_callback_info cbInfo) @@ -297,20 +377,21 @@ napi_value StreamNExporter::Close(napi_env env, napi_callback_info cbInfo) NError(EINVAL).ThrowErr(env); return nullptr; } - auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); - if (!streamEntity || !streamEntity->fp) { - HILOGE("Failed to get entity of Stream"); + if (!streamEntity) { + HILOGE("Failed to get entity of Stream, may closed twice"); NError(EIO).ThrowErr(env); return nullptr; } - - auto fp = NClass::RemoveEntityOfFinal(env, funcArg.GetThisVar()); - if (!fp) { + StreamEntity* ret = nullptr; + { + std::lock_guard lock(mutex); + ret = NClass::RemoveEntityOfFinal(env, funcArg.GetThisVar()); + } + if (!ret) { NError(EINVAL).ThrowErr(env); return nullptr; } - auto cbExec = []() -> NError { return NError(ERRNO_NOERR); }; @@ -342,12 +423,12 @@ napi_value StreamNExporter::Seek(napi_env env, napi_callback_info cbInfo) } auto streamEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); - if (!streamEntity || !streamEntity->fp) { + auto fp = GetFilePtr(streamEntity); + if (fp == nullptr) { HILOGE("Failed to get entity of Stream"); NError(EIO).ThrowErr(env); return nullptr; } - auto [succGetOffset, offset] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt64(); if (!succGetOffset) { HILOGE("Invalid offset from JS first argument"); @@ -367,14 +448,14 @@ napi_value StreamNExporter::Seek(napi_env env, napi_callback_info cbInfo) } if (offset >= 0) { - int ret = fseek(streamEntity->fp.get(), static_cast(offset), whence); + int ret = fseek(fp.get(), static_cast(offset), whence); if (ret < 0) { HILOGE("Failed to set the offset location of the file stream pointer, ret: %{public}d", ret); NError(errno).ThrowErr(env); return nullptr; } } - int64_t res = ftell(streamEntity->fp.get()); + int64_t res = ftell(fp.get()); if (res < 0) { HILOGE("Failed to tell, error:%{public}d", errno); NError(errno).ThrowErr(env); @@ -411,8 +492,8 @@ bool StreamNExporter::Export() { vector props = { NVal::DeclareNapiFunction("writeSync", WriteSync), - NVal::DeclareNapiFunction("flush", Flush::Async), - NVal::DeclareNapiFunction("flushSync", Flush::Sync), + NVal::DeclareNapiFunction("flush", Flush), + NVal::DeclareNapiFunction("flushSync", FlushSync), NVal::DeclareNapiFunction("readSync", ReadSync), NVal::DeclareNapiFunction("closeSync", CloseSync), NVal::DeclareNapiFunction("write", Write), diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h index fb7f0fb3bd56e2e505f8fc8a98433eac12b59ff1..8b2a05bc78a4a585abd75c873de3e8346cebcf93 100644 --- a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h +++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.h @@ -18,12 +18,16 @@ #include "filemgmt_libn.h" +#include +#include "stream_entity.h" namespace OHOS { namespace FileManagement { namespace ModuleFileIO { using namespace OHOS::FileManagement::LibN; class StreamNExporter final : public NExporter { public: + static std::mutex mutex; + inline static const std::string className_ = "FsStream"; bool Export() override; @@ -34,11 +38,15 @@ public: static napi_value WriteSync(napi_env env, napi_callback_info cbInfo); static napi_value ReadSync(napi_env env, napi_callback_info cbInfo); static napi_value CloseSync(napi_env env, napi_callback_info cbInfo); + static napi_value FlushSync(napi_env env, napi_callback_info cbInfo); static napi_value Write(napi_env env, napi_callback_info cbInfo); static napi_value Read(napi_env env, napi_callback_info cbInfo); static napi_value Close(napi_env env, napi_callback_info cbInfo); static napi_value Seek(napi_env env, napi_callback_info cbInfo); + static napi_value Flush(napi_env env, napi_callback_info cbInfo); + + static std::shared_ptr GetFilePtr(StreamEntity *streamEntity); StreamNExporter(napi_env env, napi_value exports); ~StreamNExporter() override; @@ -65,6 +73,8 @@ struct AsyncWriteArg { const std::string PROCEDURE_STREAM_WRITE_NAME = "FileIOStreamWrite"; const std::string PROCEDURE_STREAM_READ_NAME = "FileIOStreamRead"; const std::string PROCEDURE_STREAM_CLOSE_NAME = "FileIOStreamClose"; +const std::string PROCEDURE_STREAM_FLUSH_NAME = "FileIOStreamFlush"; + } // namespace ModuleFileIO } // namespace FileManagement } // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 384c0ae20f1addb8b609814f1c2cb7b841d882b5..379b7bf2cdedc57733d3671aba420892ce7398fb 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -117,8 +117,12 @@ int FileWatcher::NotifyToWatchNewEvents(const string &fileName, const int &wd, c int FileWatcher::CloseNotifyFd() { int closeRet = ERRNO_NOERR; + int fd = notifyFd_; + if (watcherInfoSet_.size() == 0) { - closeRet = close(notifyFd_); + run_ = false; + notifyFd_ = -1; + closeRet = close(fd); if (closeRet != 0) { HILOGE("Failed to stop notify close fd errCode:%{public}d", errno); } @@ -128,7 +132,6 @@ int FileWatcher::CloseNotifyFd() HILOGE("Failed to close eventfd errCode:%{public}d", errno); } eventFd_ = -1; - run_ = false; } return closeRet; diff --git a/interfaces/kits/js/src/mod_fs/common_func.cpp b/interfaces/kits/js/src/mod_fs/common_func.cpp index 93d0e1c58e313075cea6602a53973878776e094c..43aa39b31ef68ff67cf6e9b9a8cfc144ca772516 100644 --- a/interfaces/kits/js/src/mod_fs/common_func.cpp +++ b/interfaces/kits/js/src/mod_fs/common_func.cpp @@ -251,7 +251,7 @@ NVal CommonFunc::InstantiateFile(napi_env env, int fd, const string &pathOrUri, return { env, objFile }; } -NVal CommonFunc::InstantiateStream(napi_env env, unique_ptr fp) +NVal CommonFunc::InstantiateStream(napi_env env, shared_ptr fp) { napi_value objStream = NClass::InstantiateClass(env, StreamNExporter::className_, {}); if (!objStream) { @@ -266,7 +266,6 @@ NVal CommonFunc::InstantiateStream(napi_env env, unique_ptrfp.swap(fp); return { env, objStream }; } diff --git a/interfaces/kits/js/src/mod_fs/common_func.h b/interfaces/kits/js/src/mod_fs/common_func.h index 2a51b350618605836fbe4d3a6871b2f95e79047d..c99a7ee510b834d837c45ac32c6e63ee5cd8184c 100644 --- a/interfaces/kits/js/src/mod_fs/common_func.h +++ b/interfaces/kits/js/src/mod_fs/common_func.h @@ -85,7 +85,7 @@ struct CommonFunc { #endif #ifndef WIN_PLATFORM static LibN::NVal InstantiateFile(napi_env env, int fd, const std::string &pathOrUri, bool isUri); - static LibN::NVal InstantiateStream(napi_env env, std::unique_ptr fp); + static LibN::NVal InstantiateStream(napi_env env, std::shared_ptr fp); #endif static std::tuple GetReadArg(napi_env env, napi_value readBuf, diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index ad4b439752c9c396a53bd72ff2ba06ddff939f33..fa2b36bc76d379d6043b49b4d1f4dc9c2461bff7 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -50,6 +50,7 @@ const std::string FILE_PREFIX_NAME = "file://"; const std::string NETWORK_PARA = "?networkid="; const string PROCEDURE_COPY_NAME = "FileFSCopy"; const std::string MEDIALIBRARY_DATA_URI = "datashare:///media"; +const std::string MEDIA = "media"; constexpr int DISMATCH = 0; constexpr int MATCH = 1; constexpr int BUF_SIZE = 1024; @@ -61,7 +62,7 @@ std::map> Copy::jsCbMap_; static int OpenSrcFile(const string &srcPth, std::shared_ptr infos, int32_t &srcFd) { Uri uri(infos->srcUri); - if (uri.GetAuthority() == "media") { + if (uri.GetAuthority() == MEDIA) { std::shared_ptr dataShareHelper = nullptr; sptr remote = new (std::nothrow) IRemoteStub(); if (!remote) { @@ -187,28 +188,39 @@ bool Copy::IsRemoteUri(const std::string &uri) return uri.find(NETWORK_PARA) != uri.npos; } -bool Copy::IsDirectory(const std::string &path) +bool Copy::IsDirectory(const std::string &path, int &errCode) { + errCode = 0; struct stat buf {}; int ret = stat(path.c_str(), &buf); if (ret == -1) { - HILOGE("stat failed, errno is %{public}d, path is %{public}s", errno, path.c_str()); + errCode = errno; + HILOGE("stat failed, errno is %{public}d", errno); return false; } return (buf.st_mode & S_IFMT) == S_IFDIR; } -bool Copy::IsFile(const std::string &path) +bool Copy::IsFile(const std::string &path, int &errCode) { + errCode = 0; struct stat buf {}; int ret = stat(path.c_str(), &buf); if (ret == -1) { + errCode = errno; HILOGI("stat failed, errno is %{public}d, ", errno); return false; } return (buf.st_mode & S_IFMT) == S_IFREG; } +bool Copy::IsMediaUri(const std::string &uriPath) +{ + Uri uri(uriPath); + string bundleName = uri.GetAuthority(); + return bundleName == MEDIA; +} + tuple Copy::GetFileSize(const std::string &path) { struct stat buf {}; @@ -220,16 +232,21 @@ tuple Copy::GetFileSize(const std::string &path) return { ERRNO_NOERR, buf.st_size }; } -void Copy::CheckOrCreatePath(const std::string &destPath) +int Copy::CheckOrCreatePath(const std::string &destPath) { - if (!filesystem::exists(destPath)) { - HILOGI("destPath not exist, destPath = %{public}s", destPath.c_str()); + std::error_code errCode; + if (!filesystem::exists(destPath, errCode) && errCode.value() == ERRNO_NOERR) { + HILOGI("destPath not exist"); auto file = open(destPath.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (file < 0) { HILOGE("Error opening file descriptor. errno = %{public}d", errno); + return errno; } close(file); + } else if (errCode.value() != 0) { + return errCode.value(); } + return ERRNO_NOERR; } int Copy::CopyFile(const string &src, const string &dest, std::shared_ptr infos) @@ -270,12 +287,16 @@ int Copy::MakeDir(const string &path) int Copy::CopySubDir(const string &srcPath, const string &destPath, std::shared_ptr infos) { - if (!filesystem::exists(destPath)) { + std::error_code errCode; + if (!filesystem::exists(destPath, errCode) && errCode.value() == ERRNO_NOERR) { int res = MakeDir(destPath); if (res != ERRNO_NOERR) { HILOGE("Failed to mkdir"); return res; } + } else if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); } uint32_t watchEvents = IN_MODIFY; if (infos->notifyFd >= 0) { @@ -324,6 +345,9 @@ static void Deleter(struct NameList *arg) (arg->namelist)[i] = nullptr; } free(arg->namelist); + arg->namelist = nullptr; + delete arg; + arg = nullptr; } std::string Copy::GetRealPath(const std::string& path) @@ -419,11 +443,19 @@ int Copy::CopyDirFunc(const string &src, const string &dest, std::shared_ptr infos, std::shared_ptr callback) { - if (IsFile(infos->srcPath)) { - if (infos->srcPath == infos->destPath) { - HILOGE("The src and dest is same, path = %{public}s", infos->srcPath.c_str()); - return EINVAL; - } + int errCode = 0; + infos->isFile = IsMediaUri(infos->srcUri) || IsFile(infos->srcPath, errCode); + if (errCode != 0) { + return errCode; + } + if (!infos->isFile && !IsDirectory(infos->srcPath, errCode)) { + return EINVAL; + } + if (infos->srcPath == infos->destPath) { + HILOGE("The src and dest is same, path = %{public}s", infos->srcPath.c_str()); + return EINVAL; + } + if (infos->isFile) { CheckOrCreatePath(infos->destPath); } if (!infos->hasListener) { @@ -470,7 +502,7 @@ int Copy::SubscribeLocalListener(std::shared_ptr infos, } receiveInfo->path = infos->destPath; callback->wds.push_back({ newWd, receiveInfo }); - if (IsDirectory(infos->srcPath)) { + if (!infos->isFile) { callback->totalSize = GetDirSize(infos, infos->srcPath); return ERRNO_NOERR; } @@ -674,7 +706,7 @@ tuple Copy::HandleProgress( return { true, EINVAL, false }; } std::string fileName = receivedInfo->path; - if (event->len > 0) { // files under subdir + if (!infos->isFile) { // files under subdir fileName += "/" + string(event->name); if (!CheckFileValid(fileName, infos)) { return { true, EINVAL, false }; @@ -801,11 +833,15 @@ void Copy::StartNotify(std::shared_ptr infos, std::shared_ptr infos) { - if (IsFile(infos->srcPath) && IsFile(infos->destPath)) { + int errCode = 0; + if (infos->isFile && IsFile(infos->destPath, errCode) && errCode == 0) { // copyFile return CopyFile(infos->srcPath.c_str(), infos->destPath.c_str(), infos); } - if (IsDirectory(infos->srcPath) && IsDirectory(infos->destPath)) { + if (errCode != 0) { + return errCode; + } + if (!infos->isFile && IsDirectory(infos->destPath, errCode) && errCode == 0) { if (infos->srcPath.back() != '/') { infos->srcPath += '/'; } @@ -815,6 +851,9 @@ int Copy::ExecCopy(std::shared_ptr infos) // copyDir return CopyDirFunc(infos->srcPath.c_str(), infos->destPath.c_str(), infos); } + if (errCode != 0) { + return errCode; + } return EINVAL; } diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.h b/interfaces/kits/js/src/mod_fs/properties/copy.h index f1dc61a379a646cdbd08a7abc0e0ef5bb017f4c4..cc09ae23a72d6df739d9f20c3d27ee555d93a458 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy.h @@ -81,6 +81,7 @@ struct FileInfos { std::string destUri; std::string srcPath; std::string destPath; + bool isFile = false; std::chrono::steady_clock::time_point notifyTime; int32_t notifyFd = -1; int32_t eventFd = -1; @@ -129,7 +130,7 @@ private: static tuple ParseJsOperand(napi_env env, NVal pathOrFdFromJsArg); static tuple GetListenerFromOptionArg(napi_env env, const NFuncArg &funcArg); static tuple GetCopySignalFromOptionArg(napi_env env, const NFuncArg &funcArg); - static void CheckOrCreatePath(const std::string &destPath); + static int CheckOrCreatePath(const std::string &destPath); static int ParseJsParam(napi_env env, NFuncArg &funcArg, std::shared_ptr &fileInfos); // operator of local listener @@ -171,8 +172,9 @@ private: // operator of uri or path static bool IsValidUri(const std::string &uri); static bool IsRemoteUri(const std::string &uri); - static bool IsDirectory(const std::string &path); - static bool IsFile(const std::string &path); + static bool IsDirectory(const std::string &path, int &errCode); + static bool IsFile(const std::string &path, int &errCode); + static bool IsMediaUri(const std::string &uriPath); static std::string ConvertUriToPath(const std::string &uri); static std::string GetRealPath(const std::string& path); }; diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp index 5c4816668ffb1cec4c7f644249884934f02c6b4b..7446d845484da3ab0cb89e05f7ca5b2cda3633d9 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp @@ -33,33 +33,6 @@ namespace ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; -static NError IsAllPath(FileInfo& srcFile, FileInfo& destFile) -{ -#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) - filesystem::path srcPath(string(srcFile.path.get())); - filesystem::path dstPath(string(destFile.path.get())); - error_code errCode; - if (!filesystem::copy_file(srcPath, dstPath, filesystem::copy_options::overwrite_existing, errCode)) { - HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); - return NError(errCode.value()); - } -#else - std::unique_ptr copyfile_req = { - new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; - if (!copyfile_req) { - HILOGE("Failed to request heap memory."); - return NError(ENOMEM); - } - int ret = uv_fs_copyfile(nullptr, copyfile_req.get(), srcFile.path.get(), destFile.path.get(), - UV_FS_COPYFILE_FICLONE, nullptr); - if (ret < 0) { - HILOGE("Failed to copy file when all parameters are paths"); - return NError(ret); - } -#endif - return NError(ERRNO_NOERR); -} - static NError SendFileCore(FileInfo& srcFdg, FileInfo& destFdg, struct stat& statbf) { std::unique_ptr sendfile_req = { @@ -137,7 +110,7 @@ static NError OpenCore(FileInfo& fileInfo, const int flags, const int mode) static NError OpenFile(FileInfo& srcFile, FileInfo& destFile) { if (srcFile.isPath) { - auto openResult = OpenCore(srcFile, UV_FS_O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + auto openResult = OpenCore(srcFile, UV_FS_O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (openResult) { return openResult; } @@ -229,18 +202,10 @@ napi_value CopyFile::Sync(napi_env env, napi_callback_info info) return nullptr; } - if (src.isPath && dest.isPath) { - auto err = IsAllPath(src, dest); - if (err) { - err.ThrowErr(env); - return nullptr; - } - } else { - auto err = OpenFile(src, dest); - if (err) { - err.ThrowErr(env); - return nullptr; - } + auto err = OpenFile(src, dest); + if (err) { + err.ThrowErr(env); + return nullptr; } return NVal::CreateUndefined(env).val_; } @@ -276,9 +241,6 @@ napi_value CopyFile::Async(napi_env env, napi_callback_info info) return nullptr; } auto cbExec = [para]() -> NError { - if (para->src_.isPath && para->dest_.isPath) { - return IsAllPath(para->src_, para->dest_); - } return OpenFile(para->src_, para->dest_); }; diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.cpp index ebe7e0c38cb6a816a266c9f5925705d9ea7799fd..abe3a4750ebdc50f95bad876e2354ee2cde2218d 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.cpp @@ -23,6 +23,7 @@ #include "sandbox_helper.h" #include "uri.h" #include "n_error.h" +#include "dfs_event_dfx.h" namespace OHOS { namespace FileManagement { @@ -33,6 +34,7 @@ const std::string NETWORK_PARA = "?networkid="; const std::string FILE_MANAGER_AUTHORITY = "docs"; const std::string MEDIA_AUTHORITY = "media"; const std::string DISTRIBUTED_PATH = "/data/storage/el2/distributedfiles/"; +std::atomic TransListener::getSequenceId_ = 0; void TransListener::RmDir(const std::string &path) { @@ -45,7 +47,7 @@ void TransListener::RmDir(const std::string &path) HILOGE("Failed to remove directory, error code: %{public}d", errCode.value()); } } else { - HILOGE("pathName is not exists, error code: %{public}d", errCode.value()); + HILOGE("pathName is not exists, error code: %{public}d", errCode.value()); } } @@ -59,10 +61,48 @@ std::string TransListener::CreateDfsCopyPath() return random; } +NError TransListener::HandleCopyFailure(CopyEvent ©Event, const Storage::DistributedFile::HmdfsInfo &info, + const std::string &disSandboxPath, const std::string ¤tId) +{ + if (info.authority != FILE_MANAGER_AUTHORITY && info.authority != MEDIA_AUTHORITY) { + RmDir(disSandboxPath); + } + auto it = softbusErr2ErrCodeTable.find(copyEvent.errorCode); + if (it == softbusErr2ErrCodeTable.end()) { + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, + RadarReporter::SEND_FILE_ERROR, RadarReporter::CONCURRENT_ID, currentId); + return NError(EIO); + } + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, + RadarReporter::SEND_FILE_ERROR, RadarReporter::CONCURRENT_ID, currentId); + return NError(it->second); +} + +int TransListener::WaitForCopyResult(TransListener* transListener) +{ + if (transListener == nullptr) { + HILOGE("transListener is nullptr"); + return FAILED; + } + std::unique_lock lock(transListener->cvMutex_); + transListener->cv_.wait(lock, [&transListener]() { + return transListener->copyEvent_.copyResult == SUCCESS || + transListener->copyEvent_.copyResult == FAILED; + }); + return transListener->copyEvent_.copyResult; +} + NError TransListener::CopyFileFromSoftBus(const std::string &srcUri, const std::string &destUri, std::shared_ptr fileInfos, std::shared_ptr callback) { HILOGI("CopyFileFromSoftBus begin."); + std::string currentId = "CopyFile_" + std::to_string(getpid()) + "_" + std::to_string(getSequenceId_); + ++getSequenceId_; + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS, + RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN, RadarReporter::PACKAGE_NAME, std::to_string(getpid()), + RadarReporter::CONCURRENT_ID, currentId); sptr transListener = new (std::nothrow) TransListener(); if (transListener == nullptr) { HILOGE("new trans listener failed"); @@ -77,34 +117,26 @@ NError TransListener::CopyFileFromSoftBus(const std::string &srcUri, const std:: std::string disSandboxPath; auto ret = PrepareCopySession(srcUri, destUri, transListener, info, disSandboxPath); if (ret != ERRNO_NOERR) { - HILOGE("PrepareCopySession failed, ret = %{public}d.", ret); + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, + RadarReporter::PREPARE_COPY_SESSION_ERROR, RadarReporter::CONCURRENT_ID, currentId); return NError(EIO); } if (fileInfos->taskSignal != nullptr) { fileInfos->taskSignal->SetFileInfoOfRemoteTask(info.sessionName, fileInfos->srcPath); } - std::unique_lock lock(transListener->cvMutex_); - transListener->cv_.wait(lock, [&transListener]() { - return transListener->copyEvent_.copyResult == SUCCESS || - transListener->copyEvent_.copyResult == FAILED; - }); - HILOGI("dfs PrepareSession Finish, result is %{public}d", transListener->copyEvent_.copyResult); - if (transListener->copyEvent_.copyResult == FAILED) { - if (info.authority != FILE_MANAGER_AUTHORITY && info.authority != MEDIA_AUTHORITY) { - RmDir(disSandboxPath); - } - auto it = softbusErr2ErrCodeTable.find(transListener->copyEvent_.errorCode); - if (it == softbusErr2ErrCodeTable.end()) { - return NError(EIO); - } - return NError(it->second); + auto copyResult = WaitForCopyResult(transListener); + if (copyResult == FAILED) { + return HandleCopyFailure(transListener->copyEvent_, info, disSandboxPath, currentId); } if (info.authority == FILE_MANAGER_AUTHORITY || info.authority == MEDIA_AUTHORITY) { HILOGW("Public or media path not copy"); + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, currentId); return NError(ERRNO_NOERR); } - ret = CopyToSandBox(srcUri, disSandboxPath, info.sandboxPath); + ret = CopyToSandBox(srcUri, disSandboxPath, info.sandboxPath, currentId); RmDir(disSandboxPath); if (ret != ERRNO_NOERR) { HILOGE("CopyToSandBox failed, ret = %{public}d.", ret); @@ -156,7 +188,7 @@ int32_t TransListener::PrepareCopySession(const std::string &srcUri, } int32_t TransListener::CopyToSandBox(const std::string &srcUri, const std::string &disSandboxPath, - const std::string &sandboxPath) + const std::string &sandboxPath, const std::string ¤tId) { std::error_code errCode; if (std::filesystem::exists(sandboxPath) && std::filesystem::is_directory(sandboxPath)) { @@ -165,6 +197,9 @@ int32_t TransListener::CopyToSandBox(const std::string &srcUri, const std::strin std::filesystem::copy_options::recursive | std::filesystem::copy_options::update_existing, errCode); if (errCode.value() != 0) { HILOGE("Copy dir failed: errCode: %{public}d", errCode.value()); + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, + RadarReporter::COPY_TO_SANDBOX_ERROR, RadarReporter::CONCURRENT_ID, currentId); return EIO; } } else { @@ -180,10 +215,15 @@ int32_t TransListener::CopyToSandBox(const std::string &srcUri, const std::strin errCode); if (errCode.value() != 0) { HILOGE("Copy file failed: errCode: %{public}d", errCode.value()); + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, + RadarReporter::COPY_TO_SANDBOX_ERROR, RadarReporter::CONCURRENT_ID, currentId); return EIO; } } HILOGI("Copy file success."); + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, currentId); return ERRNO_NOERR; } diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.h b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.h index 95c63d930db441213a84bdbd32ca7b75b4cdca54..d04335bee54f4c33407505475ba78f7fa7762b05 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener.h @@ -50,13 +50,16 @@ private: static std::string CreateDfsCopyPath(); static std::string GetFileName(const std::string &path); static int32_t CopyToSandBox(const std::string &srcUri, const std::string &disSandboxPath, - const std::string &sandboxPath); + const std::string &sandboxPath, const std::string ¤tId); static int32_t PrepareCopySession(const std::string &srcUri, const std::string &destUri, TransListener* transListener, Storage::DistributedFile::HmdfsInfo &info, std::string &disSandboxPath); - + static NError HandleCopyFailure(CopyEvent ©Event, const Storage::DistributedFile::HmdfsInfo &info, + const std::string &disSandboxPath, const std::string ¤tId); + static int WaitForCopyResult(TransListener* transListener); + static std::atomic getSequenceId_; std::mutex cvMutex_; std::condition_variable cv_; CopyEvent copyEvent_; diff --git a/interfaces/kits/js/src/mod_fs/properties/copydir.cpp b/interfaces/kits/js/src/mod_fs/properties/copydir.cpp index 6646192f90e77287f2d46a0dbc75b37dedb897e8..1c643abb8ace3839f7d7dfa64db8a59f5be8ce37 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copydir.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copydir.cpp @@ -35,10 +35,23 @@ using namespace OHOS::FileManagement::LibN; static int RecurCopyDir(const string &srcPath, const string &destPath, const int mode, vector &errfiles); +static bool EndWithSlash(const string &src) +{ + return src.back() == '/'; +} + static bool AllowToCopy(const string &src, const string &dest) { - if (dest.find(src) == 0 || filesystem::path(src).parent_path() == dest) { - HILOGE("Failed to copy file"); + if (src == dest) { + HILOGE("Failed to copy file, the same path"); + return false; + } + if (EndWithSlash(src) ? dest.find(src) == 0 : dest.find(src + "/") == 0) { + HILOGE("Failed to copy file, dest is under src"); + return false; + } + if (filesystem::path(src).parent_path() == dest) { + HILOGE("Failed to copy file, src's parent path is dest"); return false; } return true; @@ -48,13 +61,14 @@ static tuple, unique_ptr, int> ParseAndCheckJsO const NFuncArg &funcArg) { auto [resGetFirstArg, src, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath(); - if (!resGetFirstArg || !filesystem::is_directory(filesystem::status(src.get()))) { - HILOGE("Invalid src"); + std::error_code errCode; + if (!resGetFirstArg || !filesystem::is_directory(filesystem::status(src.get(), errCode))) { + HILOGE("Invalid src, errCode = %{public}d", errCode.value()); return { false, nullptr, nullptr, 0 }; } auto [resGetSecondArg, dest, unused] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8StringPath(); - if (!resGetSecondArg || !filesystem::is_directory(filesystem::status(dest.get()))) { - HILOGE("Invalid dest"); + if (!resGetSecondArg || !filesystem::is_directory(filesystem::status(dest.get(), errCode))) { + HILOGE("Invalid dest, errCode = %{public}d", errCode.value()); return { false, nullptr, nullptr, 0 }; } if (!AllowToCopy(src.get(), dest.get())) { @@ -106,20 +120,27 @@ static void Deleter(struct NameList *arg) (arg->namelist)[i] = nullptr; } free(arg->namelist); + arg->namelist = nullptr; + delete arg; + arg = nullptr; } static int CopyFile(const string &src, const string &dest, const int mode) { filesystem::path dstPath(dest); - if (filesystem::exists(dstPath)) { + std::error_code errCode; + if (filesystem::exists(dstPath, errCode)) { int ret = (mode == DIRMODE_FILE_COPY_THROW_ERR) ? EEXIST : RemoveFile(dest); if (ret) { HILOGE("Failed to copy file due to existing destPath with throw err"); return ret; } } + if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); + } filesystem::path srcPath(src); - std::error_code errCode; if (!filesystem::copy_file(srcPath, dstPath, filesystem::copy_options::overwrite_existing, errCode)) { HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); return errCode.value(); @@ -130,12 +151,16 @@ static int CopyFile(const string &src, const string &dest, const int mode) static int CopySubDir(const string &srcPath, const string &destPath, const int mode, vector &errfiles) { - if (!filesystem::exists(destPath)) { + std::error_code errCode; + if (!filesystem::exists(destPath, errCode) && errCode.value() == ERRNO_NOERR) { int res = MakeDir(destPath); if (res != ERRNO_NOERR) { HILOGE("Failed to mkdir"); return res; } + } else if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); } return RecurCopyDir(srcPath, destPath, mode, errfiles); } @@ -157,6 +182,10 @@ static int RecurCopyDir(const string &srcPath, const string &destPath, const int return ENOMEM; } int num = scandir(srcPath.c_str(), &(pNameList->namelist), FilterFunc, alphasort); + if (num < 0) { + HILOGE("scandir fail errno is %{public}d", errno); + return errno; + } pNameList->direntNum = num; for (int i = 0; i < num; i++) { @@ -194,12 +223,16 @@ static int CopyDirFunc(const string &src, const string &dest, const int mode, ve } string dirName = string(src).substr(found); string destStr = dest + dirName; - if (!filesystem::exists(destStr)) { + std::error_code errCode; + if (!filesystem::exists(destStr, errCode) && errCode.value() == ERRNO_NOERR) { int res = MakeDir(destStr); if (res != ERRNO_NOERR) { HILOGE("Failed to mkdir"); return res; } + } else if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); } int res = RecurCopyDir(src, destStr, mode, errfiles); if (!errfiles.empty() && res == ERRNO_NOERR) { diff --git a/interfaces/kits/js/src/mod_fs/properties/create_stream.cpp b/interfaces/kits/js/src/mod_fs/properties/create_stream.cpp index 1440e4a5df1b03f7a0a55c573e087bfd3e0e8056..7ace8cc18f18203b3a9d5608a0996b230ba38187 100755 --- a/interfaces/kits/js/src/mod_fs/properties/create_stream.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/create_stream.cpp @@ -60,14 +60,13 @@ napi_value CreateStream::Sync(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - - unique_ptr fp = { fopen(argPath.c_str(), argMode.c_str()), fclose }; - if (!fp) { + FILE *file = fopen(argPath.c_str(), argMode.c_str()); + if (!file) { HILOGE("Failed to fdopen file by path"); NError(errno).ThrowErr(env); return nullptr; } - + std::shared_ptr fp(file, fclose); return CommonFunc::InstantiateStream(env, move(fp)).val_; } @@ -93,11 +92,12 @@ napi_value CreateStream::Async(napi_env env, napi_callback_info info) return nullptr; } auto cbExec = [arg, argPath = move(argPath), argMode = move(argMode)]() -> NError { - arg->fp = { fopen(argPath.c_str(), argMode.c_str()), fclose }; - if (!arg->fp) { + FILE *file = fopen(argPath.c_str(), argMode.c_str()); + if (!file) { HILOGE("Failed to fdopen file by path"); return NError(errno); } + arg->fp = std::shared_ptr(file, fclose); return NError(ERRNO_NOERR); }; diff --git a/interfaces/kits/js/src/mod_fs/properties/create_stream.h b/interfaces/kits/js/src/mod_fs/properties/create_stream.h index 9e7b01493dc6ff432791cd841773072dbdf40522..1e9d7e6843f484461b2694322392fddec7e653d1 100755 --- a/interfaces/kits/js/src/mod_fs/properties/create_stream.h +++ b/interfaces/kits/js/src/mod_fs/properties/create_stream.h @@ -28,7 +28,7 @@ public: }; struct AsyncCreateStreamArg { - std::unique_ptr fp = { nullptr, fclose }; + std::shared_ptr fp{ nullptr }; }; const std::string PROCEDURE_CREATESTREAM_NAME = "FileIOCreateStream"; diff --git a/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.cpp b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.cpp index 4029464edb7c624e33ddab79d506628f7671b2bb..1d6ababb4050afb4343169edb8255c62835e250d 100755 --- a/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.cpp @@ -60,14 +60,13 @@ napi_value FdopenStream::Sync(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - - unique_ptr fp = { fdopen(fd, mode.c_str()), fclose }; - if (!fp) { - HILOGE("Failed to fdopen file by fd:%{public}d", fd); + FILE *file = fdopen(fd, mode.c_str()); + if (!file) { + HILOGE("Failed to fdopen file by path"); NError(errno).ThrowErr(env); return nullptr; } - + std::shared_ptr fp(file, fclose); return CommonFunc::InstantiateStream(env, move(fp)).val_; } @@ -93,11 +92,12 @@ napi_value FdopenStream::Async(napi_env env, napi_callback_info info) return nullptr; } auto cbExec = [arg, fd = fd, mode = mode]() -> NError { - arg->fp = { fdopen(fd, mode.c_str()), fclose }; - if (!arg->fp) { - HILOGE("Failed to fdopen file by fd:%{public}d", fd); + FILE *file = fdopen(fd, mode.c_str()); + if (!file) { + HILOGE("Failed to fdopen file by path"); return NError(errno); } + arg->fp = std::shared_ptr(file, fclose); return NError(ERRNO_NOERR); }; diff --git a/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.h b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.h index ed43f3d3bd8b4a71499dfdaadbb997d42e7488f2..0bdc3c49da8f3fa60e4552c374ba8cefe2dad840 100755 --- a/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.h +++ b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream.h @@ -28,7 +28,7 @@ public: }; struct AsyncFdopenStreamArg { - std::unique_ptr fp = { nullptr, fclose }; + std::shared_ptr fp{ nullptr }; }; const std::string PROCEDURE_FDOPENSTREAM_NAME = "FileIOFdopenStream"; diff --git a/interfaces/kits/js/src/mod_fs/properties/listfile.cpp b/interfaces/kits/js/src/mod_fs/properties/listfile.cpp index 7772979959f91cdd3f21702a5df9ccbe1b1da98a..46afa981f1cf971a46da4547161b76146c210bad 100755 --- a/interfaces/kits/js/src/mod_fs/properties/listfile.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/listfile.cpp @@ -258,6 +258,9 @@ static void Deleter(struct NameListArg *arg) (arg->namelist)[i] = nullptr; } free(arg->namelist); + arg->namelist = nullptr; + delete arg; + arg = nullptr; } static int FilterFileRes(const string &path, vector &dirents) diff --git a/interfaces/kits/js/src/mod_fs/properties/move.cpp b/interfaces/kits/js/src/mod_fs/properties/move.cpp index 03b5876e546ae1f6712844a2f284becf77c48f7d..f75481d88910412010851d4e843ac3cc972bb6a2 100644 --- a/interfaces/kits/js/src/mod_fs/properties/move.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/move.cpp @@ -37,7 +37,8 @@ using namespace OHOS::FileManagement::LibN; #ifdef __MUSL__ static bool CheckDir(const string &path) { - if (!filesystem::is_directory(filesystem::status(path))) { + std::error_code errCode; + if (!filesystem::is_directory(filesystem::status(path, errCode))) { return false; } return true; @@ -97,7 +98,7 @@ static int CopyAndDeleteFile(const string &src, const string &dest) #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) filesystem::path dstPath(dest); std::error_code errCode; - if (filesystem::exists(dstPath)) { + if (filesystem::exists(dstPath, errCode)) { if (!filesystem::remove(dstPath, errCode)) { HILOGE("Failed to remove dest file, error code: %{public}d", errCode.value()); return errCode.value(); diff --git a/interfaces/kits/js/src/mod_fs/properties/movedir.cpp b/interfaces/kits/js/src/mod_fs/properties/movedir.cpp index 7e1874e516d15adf530a0e0705e33f81d389c2ea..ecb833420cc5fdd4ced3542d60776b6d1ecea0d7 100644 --- a/interfaces/kits/js/src/mod_fs/properties/movedir.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/movedir.cpp @@ -38,9 +38,10 @@ static int RecurMoveDir(const string &srcPath, const string &destPath, const int static tuple JudgeExistAndEmpty(const string &path) { + std::error_code errCode; filesystem::path pathName(path); - if (filesystem::exists(pathName)) { - if (filesystem::is_empty(pathName)) { + if (filesystem::exists(pathName, errCode)) { + if (filesystem::is_empty(pathName, errCode)) { return { true, true }; } return { true, false }; @@ -51,13 +52,17 @@ static tuple JudgeExistAndEmpty(const string &path) static int RmDirectory(const string &path) { filesystem::path pathName(path); - if (filesystem::exists(pathName)) { + std::error_code errCode; + if (filesystem::exists(pathName, errCode)) { std::error_code errCode; (void)filesystem::remove_all(pathName, errCode); if (errCode.value() != 0) { HILOGE("Failed to remove directory, error code: %{public}d", errCode.value()); return errCode.value(); } + } else if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); } return ERRNO_NOERR; } @@ -76,13 +81,14 @@ static int RemovePath(const string& pathStr) static tuple, unique_ptr, int> ParseJsOperand(napi_env env, const NFuncArg& funcArg) { auto [resGetFirstArg, src, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath(); - if (!resGetFirstArg || !filesystem::is_directory(filesystem::status(src.get()))) { - HILOGE("Invalid src"); + std::error_code errCode; + if (!resGetFirstArg || !filesystem::is_directory(filesystem::status(src.get(), errCode))) { + HILOGE("Invalid src, errCode = %{public}d", errCode.value()); return { false, nullptr, nullptr, 0 }; } auto [resGetSecondArg, dest, unused] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8StringPath(); - if (!resGetSecondArg || !filesystem::is_directory(filesystem::status(dest.get()))) { - HILOGE("Invalid dest"); + if (!resGetSecondArg || !filesystem::is_directory(filesystem::status(dest.get(), errCode))) { + HILOGE("Invalid dest,errCode = %{public}d", errCode.value()); return { false, nullptr, nullptr, 0 }; } int mode = 0; @@ -100,7 +106,8 @@ static tuple, unique_ptr, int> ParseJsOperand(n static int CopyAndDeleteFile(const string &src, const string &dest) { filesystem::path dstPath(dest); - if (filesystem::exists(dstPath)) { + std::error_code errCode; + if (filesystem::exists(dstPath, errCode)) { int removeRes = RemovePath(dest); if (removeRes != 0) { HILOGE("Failed to remove dest file"); @@ -108,7 +115,6 @@ static int CopyAndDeleteFile(const string &src, const string &dest) } } filesystem::path srcPath(src); - std::error_code errCode; if (!filesystem::copy_file(srcPath, dstPath, filesystem::copy_options::overwrite_existing, errCode)) { HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); return errCode.value(); @@ -119,8 +125,9 @@ static int CopyAndDeleteFile(const string &src, const string &dest) static int RenameFile(const string &src, const string &dest, const int mode, deque &errfiles) { filesystem::path dstPath(dest); - if (filesystem::exists(dstPath)) { - if (filesystem::is_directory(dstPath)) { + std::error_code errCode; + if (filesystem::exists(dstPath, errCode)) { + if (filesystem::is_directory(dstPath, errCode)) { errfiles.emplace_front(src, dest); return ERRNO_NOERR; } @@ -129,8 +136,10 @@ static int RenameFile(const string &src, const string &dest, const int mode, deq return ERRNO_NOERR; } } + if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists or is_directory fail, errcode is %{public}d", errCode.value()); + } filesystem::path srcPath(src); - std::error_code errCode; filesystem::rename(srcPath, dstPath, errCode); if (errCode.value() == EXDEV) { HILOGD("Failed to rename file due to EXDEV"); @@ -150,11 +159,14 @@ static int32_t FilterFunc(const struct dirent *filename) static int RenameDir(const string &src, const string &dest, const int mode, deque &errfiles) { filesystem::path destPath(dest); - if (filesystem::exists(destPath)) { + std::error_code errCode; + if (filesystem::exists(destPath, errCode)) { return RecurMoveDir(src, dest, mode, errfiles); + } else if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); } filesystem::path srcPath(src); - std::error_code errCode; filesystem::rename(srcPath, destPath, errCode); if (errCode.value() == EXDEV) { HILOGD("Failed to rename file due to EXDEV"); @@ -183,13 +195,17 @@ static void Deleter(struct NameListArg *arg) (arg->namelist)[i] = nullptr; } free(arg->namelist); + arg->namelist = nullptr; + delete arg; + arg = nullptr; } static int RecurMoveDir(const string &srcPath, const string &destPath, const int mode, deque &errfiles) { filesystem::path dpath(destPath); - if (!filesystem::is_directory(dpath)) { + std::error_code errCode; + if (!filesystem::is_directory(dpath, errCode)) { errfiles.emplace_front(srcPath, destPath); return ERRNO_NOERR; } diff --git a/interfaces/kits/js/src/mod_fs/properties/open.cpp b/interfaces/kits/js/src/mod_fs/properties/open.cpp index 3ec0bb4414bee47f252b032d374fc1efd862f017..bfb5cc80bbe600a7f922df1c5aef8e350a8e5b88 100644 --- a/interfaces/kits/js/src/mod_fs/properties/open.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/open.cpp @@ -163,23 +163,23 @@ static tuple OpenByFileDataUri(Uri &uri, const string &uriStr, unsi string bundleName = uri.GetAuthority(); AppFileService::ModuleFileUri::FileUri fileUri(uriStr); string realPath = fileUri.GetRealPath(); - if ((bundleName == MEDIA || bundleName == DOCS) && access(realPath.c_str(), F_OK) != 0) { + if (bundleName == MEDIA) { int res = OpenFileByDatashare(uri.ToString(), mode); if (res < 0) { HILOGE("Failed to open file by Datashare error %{public}d", res); } return { res, uri.ToString() }; + } else if (bundleName == DOCS && access(realPath.c_str(), F_OK) != 0) { + int res = OpenFileByDatashare(uri.ToString(), mode); + if (res < 0) { + HILOGE("Failed to open file by Datashare error %{public}d", res); + return { -ENOENT, uri.ToString() }; + } + return { res, uri.ToString() }; } int ret = OpenFileByPath(realPath, mode); if (ret < 0) { - if (bundleName == MEDIA) { - ret = OpenFileByDatashare(uriStr, mode); - if (ret < 0) { - HILOGE("Failed to open file by Datashare error %{public}d", ret); - } - } else { - HILOGE("Failed to open file for libuv error %{public}d", ret); - } + HILOGE("Failed to open file for libuv error %{public}d", ret); } return { ret, uriStr }; } diff --git a/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp index 7fcccd97f16cabe9a0c8f691b3bad3501a6d5b77..1191c331106aa3a427ea92087dda8bc36c68d909 100644 --- a/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp @@ -22,10 +22,10 @@ #include #include -#include "common_func.h" #include "class_file/file_entity.h" #include "class_file/file_n_exporter.h" #include "close.h" +#include "common_func.h" #include "fdatasync.h" #include "file_utils.h" #include "filemgmt_libn.h" @@ -42,14 +42,21 @@ #include "utimes.h" #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) +#include + +#include "bundle_mgr_proxy.h" +#include "connectdfs.h" #include "copy.h" #include "copy_file.h" #include "copydir.h" #include "create_randomaccessfile.h" #include "create_stream.h" #include "create_streamrw.h" +#include "disconnectdfs.h" #include "dup.h" #include "fdopen_stream.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" #include "listfile.h" #include "lseek.h" #include "move.h" @@ -58,9 +65,8 @@ #include "read_text.h" #include "rust_file.h" #include "symlink.h" +#include "system_ability_definition.h" #include "watcher.h" -#include "connectdfs.h" -#include "disconnectdfs.h" #include "xattr.h" #endif @@ -73,17 +79,125 @@ namespace FileManagement { namespace ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) +const string CLOUDDISK_FILE_PREFIX = "/data/storage/el2/cloud"; +const string DISTRIBUTED_FILE_PREFIX = "/data/storage/el2/distributedfiles"; +const string PACKAGE_NAME_FLAG = ""; +const string USER_ID_FLAG = ""; +const string PHYSICAL_PATH_PREFIX = "/mnt/hmdfs//account/device_view/local/data/"; +const string CLOUD_FILE_LOCATION = "user.cloud.location"; +const char POSITION_LOCAL = '1'; +const char POSITION_BOTH = '3'; +const int BASE_USER_RANGE = 200000; +#endif + +enum AccessFlag : int32_t { + DEFAULT_FLAG = -1, + LOCAL_FLAG, +}; + +struct AccessArgs { + string path; + int mode = -1; + int flag = DEFAULT_FLAG; +}; -static int AccessCore(const string &path, int mode) +static int UvAccess(const string &path, int mode) { - std::unique_ptr access_req = { - new uv_fs_t, CommonFunc::fs_req_cleanup }; + std::unique_ptr access_req = {new uv_fs_t, + CommonFunc::fs_req_cleanup}; if (!access_req) { HILOGE("Failed to request heap memory."); return ENOMEM; } - int ret = uv_fs_access(nullptr, access_req.get(), path.c_str(), mode, nullptr); - return ret; + return uv_fs_access(nullptr, access_req.get(), path.c_str(), mode, nullptr); +} + +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) +static bool IsCloudOrDistributedFilePath(const string &path) +{ + return path.find(CLOUDDISK_FILE_PREFIX) == 0 || path.find(DISTRIBUTED_FILE_PREFIX) == 0; +} + +static int GetCurrentUserId() +{ + int uid = IPCSkeleton::GetCallingUid(); + int userId = uid / BASE_USER_RANGE; + return userId; +} + +static sptr GetBundleMgrProxy() +{ + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (!systemAbilityManager) { + HILOGE("fail to get system ability mgr"); + return nullptr; + } + sptr remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (!remoteObject) { + HILOGE("fail to get bundle manager proxy"); + return nullptr; + } + + return iface_cast(remoteObject); +} + +static string GetSelfBundleName() +{ + sptr bundleMgrProxy = GetBundleMgrProxy(); + if (!bundleMgrProxy) { + HILOGE("bundleMgrProxy is nullptr"); + return ""; + } + BundleInfo bundleInfo; + auto ret = bundleMgrProxy->GetBundleInfoForSelf(0, bundleInfo); + if (ret != 0) { + HILOGE("bundleName get fail"); + return ""; + } + return bundleInfo.name; +} + +static int HandleLocalCheck(const string &path, int mode) +{ + // check if the file of /data/storage/el2/cloud is on the local + if (path.find(CLOUDDISK_FILE_PREFIX) == 0) { + char val[2] = {'\0'}; + if (getxattr(path.c_str(), CLOUD_FILE_LOCATION.c_str(), val, sizeof(val)) < 0) { + HILOGI("get cloud file location fail, err: %{public}d", errno); + return errno; + } + if (val[0] == POSITION_LOCAL || val[0] == POSITION_BOTH) { + return 0; + } + return ENOENT; + } + // check if the distributed file of /data/storage/el2/distributedfiles is on the local, + // convert into physical path(/mnt/hmdfs//account/device_view/local/data/) and check + if (path.find(DISTRIBUTED_FILE_PREFIX) == 0) { + int userId = GetCurrentUserId(); + string bundleName = GetSelfBundleName(); + string relativePath = path.substr(DISTRIBUTED_FILE_PREFIX.length()); + string physicalPath = PHYSICAL_PATH_PREFIX + relativePath; + physicalPath.replace(physicalPath.find(USER_ID_FLAG), USER_ID_FLAG.length(), to_string(userId)); + physicalPath.replace(physicalPath.find(PACKAGE_NAME_FLAG), PACKAGE_NAME_FLAG.length(), bundleName); + + return UvAccess(physicalPath, mode); + } + + return ENOENT; +} +#endif + +static int AccessCore(const string &path, int mode, int flag = DEFAULT_FLAG) +{ +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) + if (flag == LOCAL_FLAG && IsCloudOrDistributedFilePath(path)) { + return HandleLocalCheck(path, mode); + } +#endif + return UvAccess(path, mode); } static int GetMode(NVal secondVar, bool *hasMode) @@ -101,36 +215,53 @@ static int GetMode(NVal secondVar, bool *hasMode) return -1; } -napi_value PropNExporter::AccessSync(napi_env env, napi_callback_info info) +static bool GetAccessArgs(napi_env env, const NFuncArg &funcArg, AccessArgs &args) { - NFuncArg funcArg(env, info); - if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { - HILOGE("Number of arguments unmatched"); - NError(EINVAL).ThrowErr(env); - return nullptr; - } - auto [succ, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath(); if (!succ) { HILOGE("Invalid path from JS first argument"); - NError(EINVAL).ThrowErr(env); - return nullptr; + return false; } + args.path = path.get(); bool hasMode = false; - int mode = 0; - if (funcArg.GetArgc() == NARG_CNT::TWO) { - mode = GetMode(NVal(env, funcArg[NARG_POS::SECOND]), &hasMode); + if (funcArg.GetArgc() >= NARG_CNT::TWO) { + args.mode = GetMode(NVal(env, funcArg[NARG_POS::SECOND]), &hasMode); } - if (mode < 0 && hasMode) { + if (args.mode < 0 && hasMode) { HILOGE("Invalid mode from JS second argument"); + return false; + } + args.mode = hasMode ? args.mode : 0; + + if (funcArg.GetArgc() == NARG_CNT::THREE) { + tie(succ, args.flag) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(args.flag); + if (!succ) { + HILOGE("Invalid flag from JS third argument"); + return false; + } + } + + return true; +} + +napi_value PropNExporter::AccessSync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + AccessArgs args; + if (!GetAccessArgs(env, funcArg, args)) { NError(EINVAL).ThrowErr(env); return nullptr; } - mode = hasMode ? mode : 0; bool isAccess = false; - int ret = AccessCore(path.get(), mode); + int ret = AccessCore(args.path, args.mode, args.flag); if (ret < 0 && (string_view(uv_err_name(ret)) != "ENOENT")) { HILOGE("Failed to access file by path"); NError(ret).ThrowErr(env); @@ -145,30 +276,17 @@ napi_value PropNExporter::AccessSync(napi_env env, napi_callback_info info) napi_value PropNExporter::Access(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); - if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::THREE)) { HILOGE("Number of arguments unmatched"); NError(EINVAL).ThrowErr(env); return nullptr; } - auto [succ, tmp, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8StringPath(); - if (!succ) { - HILOGE("Invalid path from JS first argument"); - NError(EINVAL).ThrowErr(env); - return nullptr; - } - - bool hasMode = false; - int mode = 0; - if (funcArg.GetArgc() == NARG_CNT::TWO) { - mode = GetMode(NVal(env, funcArg[NARG_POS::SECOND]), &hasMode); - } - if (mode < 0 && hasMode) { - HILOGE("Invalid mode from JS second argument"); + AccessArgs args; + if (!GetAccessArgs(env, funcArg, args)) { NError(EINVAL).ThrowErr(env); return nullptr; } - mode = hasMode ? mode : 0; auto result = CreateSharedPtr(); if (result == nullptr) { @@ -176,8 +294,8 @@ napi_value PropNExporter::Access(napi_env env, napi_callback_info info) NError(ENOMEM).ThrowErr(env); return nullptr; } - auto cbExec = [path = string(tmp.get()), result, mode]() -> NError { - int ret = AccessCore(path, mode); + auto cbExec = [path = args.path, result, mode = args.mode, flag = args.flag]() -> NError { + int ret = AccessCore(path, mode, flag); if (ret == 0) { result->isAccess = true; } @@ -192,7 +310,7 @@ napi_value PropNExporter::Access(napi_env env, napi_callback_info info) }; NVal thisVar(env, funcArg.GetThisVar()); - if (funcArg.GetArgc() == NARG_CNT::ONE || hasMode) { + if (funcArg.GetArgc() == NARG_CNT::ONE || NVal(env, funcArg[NARG_POS::SECOND]).TypeIs(napi_number)) { return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ACCESS_NAME, cbExec, cbComplete).val_; } else { NVal cb(env, funcArg[NARG_POS::SECOND]); diff --git a/interfaces/kits/js/src/mod_fs/properties/rmdirent.cpp b/interfaces/kits/js/src/mod_fs/properties/rmdirent.cpp index f5e2bbfb1cb2f4411bdb283d4bfe528b9264710e..9d375c2440dfa9d852cb9d701b76979b551c43fe 100755 --- a/interfaces/kits/js/src/mod_fs/properties/rmdirent.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/rmdirent.cpp @@ -39,14 +39,18 @@ static NError RmDirent(const string &fpath) std::filesystem::path strToPath(fpath); std::error_code errCode; std::uintmax_t num = std::filesystem::remove_all(strToPath, errCode); - if (errCode) { + if (errCode.value() != ERRNO_NOERR) { HILOGD("Failed to remove directory, error code: %{public}d", errCode.value()); return NError(errCode.value()); } - if (!num || std::filesystem::exists(strToPath)) { + if (!num || std::filesystem::exists(strToPath, errCode)) { HILOGE("Failed to remove directory, dirPath does not exist"); return NError(ENOENT); } + if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists fail, error code: %{public}d", errCode.value()); + return NError(errCode.value()); + } return NError(ERRNO_NOERR); } diff --git a/interfaces/kits/js/src/mod_fs/properties/stat.cpp b/interfaces/kits/js/src/mod_fs/properties/stat.cpp index 5153e8332df95a2382cf13ce617afd99ae6e6b4a..08de2f1e98207a1873c58ecbcc93769ac961930e 100644 --- a/interfaces/kits/js/src/mod_fs/properties/stat.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/stat.cpp @@ -44,7 +44,6 @@ static tuple ParseJsFile(napi_env env, napi_value pathOrFdFromJs auto fdg = CreateUniquePtr(fd, false); if (fdg == nullptr) { HILOGE("Failed to request heap memory."); - close(fd); NError(ENOMEM).ThrowErr(env); return { false, FileInfo { false, {}, {} } }; } diff --git a/interfaces/kits/js/src/mod_fs/properties/truncate.cpp b/interfaces/kits/js/src/mod_fs/properties/truncate.cpp index 2749f259e83158814c2ad21a66e0ea4f10e10590..3e2837433ed8b101779f2ffd92c4028368b85a64 100644 --- a/interfaces/kits/js/src/mod_fs/properties/truncate.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/truncate.cpp @@ -42,7 +42,6 @@ static tuple ParseJsFile(napi_env env, napi_value pathOrFdFromJs auto fdg = CreateUniquePtr(fd, false); if (fdg == nullptr) { HILOGE("Failed to request heap memory."); - close(fd); NError(ENOMEM).ThrowErr(env); return { false, FileInfo { false, {}, {} } }; } diff --git a/interfaces/kits/js/src/mod_fs/properties/xattr.cpp b/interfaces/kits/js/src/mod_fs/properties/xattr.cpp index b986d8eef24b50f8f603c493bc46443d6263d38b..2fb1961d02fa73172ca28d4b568e7876f3fea23d 100644 --- a/interfaces/kits/js/src/mod_fs/properties/xattr.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/xattr.cpp @@ -158,8 +158,10 @@ napi_value Xattr::GetAsync(napi_env env, napi_callback_info info) return nullptr; } auto result = make_shared(); - auto cbExec = [path = path.get(), key = key.get(), result]() -> NError { - int ret = GetXattrCore(path, key, result); + string pathString(path.get()); + string keyString(key.get()); + auto cbExec = [path = move(pathString), key = move(keyString), result]() -> NError { + int ret = GetXattrCore(path.c_str(), key.c_str(), result); return NError(ret); }; auto cbComplete = [result](napi_env env, NError err) -> NVal { @@ -206,8 +208,11 @@ napi_value Xattr::SetAsync(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - auto cbExec = [path = path.get(), key = key.get(), value = value.get()]() -> NError { - if (setxattr(path, key, value, strnlen(value, MAX_XATTR_SIZE), 0)) { + string pathString(path.get()); + string keyString(key.get()); + string valueString(value.get()); + auto cbExec = [path = move(pathString), key = move(keyString), value = move(valueString)]() -> NError { + if (setxattr(path.c_str(), key.c_str(), value.c_str(), strnlen(value.c_str(), MAX_XATTR_SIZE), 0) < 0) { HILOGE("setxattr fail, errno is %{public}d", errno); return NError(errno); } @@ -222,8 +227,7 @@ napi_value Xattr::SetAsync(napi_env env, napi_callback_info info) static const std::string PROCEDURE_NAME = "SetXattr"; NVal thisVar(env, funcArg.GetThisVar()); return NAsyncWorkPromise(env, thisVar) - .Schedule(PROCEDURE_NAME, cbExec, cbComplete) - .val_; + .Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_; } } // namespace ModuleFileIO } // namespace FileManagement diff --git a/interfaces/kits/js/src/mod_securitylabel/security_label.h b/interfaces/kits/js/src/mod_securitylabel/security_label.h index 1b0eb61b0931c88f8d73978c2b9c53549bb8327e..02e44c0002023e1a1cc01e5a896aee929399effc 100644 --- a/interfaces/kits/js/src/mod_securitylabel/security_label.h +++ b/interfaces/kits/js/src/mod_securitylabel/security_label.h @@ -28,6 +28,7 @@ namespace FileManagement { namespace ModuleSecurityLabel { const char XATTR_KEY[] = {"user.security"}; const std::string DEFAULT_DATA_LEVEL = "s3"; +const int DEFAULT_DATA_LENGTH = 2; const std::set DATA_LEVEL = {"s0", "s1", "s2", "s3", "s4"}; class SecurityLabel { public: @@ -42,14 +43,15 @@ public: #else auto xattrValueSize = getxattr(path.c_str(), XATTR_KEY, nullptr, 0); #endif - if (xattrValueSize == static_cast(DEFAULT_DATA_LEVEL.length())) { - std::unique_ptr xattrValue = std::make_unique((long)xattrValueSize + 1); + if (xattrValueSize == static_cast(DEFAULT_DATA_LENGTH)) { + char xattrValue[DEFAULT_DATA_LENGTH + 1]; #ifdef IOS_PLATFORM - xattrValueSize = getxattr(path.c_str(), XATTR_KEY, xattrValue.get(), xattrValueSize, 0, 0); + xattrValueSize = getxattr(path.c_str(), XATTR_KEY, xattrValue, xattrValueSize, 0, 0); #else - xattrValueSize = getxattr(path.c_str(), XATTR_KEY, xattrValue.get(), xattrValueSize); + xattrValueSize = getxattr(path.c_str(), XATTR_KEY, xattrValue, xattrValueSize); #endif - if (xattrValue[xattrValueSize - 1] > dataLevel.at(dataLevel.size() - 1)) { + xattrValue[DEFAULT_DATA_LENGTH] = '\0'; + if (std::string(xattrValue) > dataLevel) { errno = EINVAL; return false; } diff --git a/interfaces/kits/rust/BUILD.gn b/interfaces/kits/rust/BUILD.gn index 51d2b5296225f16eae363077fc02461eef3b1bf5..a4cc7d69884cbd02fb53601c148ad8a0643bd072 100644 --- a/interfaces/kits/rust/BUILD.gn +++ b/interfaces/kits/rust/BUILD.gn @@ -26,6 +26,5 @@ ohos_rust_shared_ffi("rust_file") { rustflags = [ "-Zstack-protector=all" ] deps = [ "//third_party/rust/crates/libc:lib" ] external_deps = [ "hilog:hilog_rust" ] - innerapi_tags = [ "platformsdk" ] public_configs = [ ":public_config" ] } diff --git a/interfaces/kits/ts/streamhash/BUILD.gn b/interfaces/kits/ts/streamhash/BUILD.gn index 73315c93ad4ecc3d600c4a52b121e4d74ea5d3ef..a27f83fe40d7468814d783f25737a9c809742dc2 100644 --- a/interfaces/kits/ts/streamhash/BUILD.gn +++ b/interfaces/kits/ts/streamhash/BUILD.gn @@ -75,7 +75,6 @@ streamhash_sources = [ "native_module_streamhash.cpp" ] config("optimize-size") { cflags = [ - "-fvisibility=hidden", "-fdata-sections", "-ffunction-sections", "-Oz", @@ -87,7 +86,7 @@ config("optimize-size") { } ohos_shared_library("streamhash") { - config = [ ":optimize-size" ] + configs = [ ":optimize-size" ] branch_protector_ret = "pac_ret" sanitize = { integer_overflow = true diff --git a/interfaces/kits/ts/streamrw/BUILD.gn b/interfaces/kits/ts/streamrw/BUILD.gn index 912d15771f3a3dc6e032711c18687d9c45907ac0..a2eece6f1e1fc76675d23f65978db63d43078a99 100644 --- a/interfaces/kits/ts/streamrw/BUILD.gn +++ b/interfaces/kits/ts/streamrw/BUILD.gn @@ -75,7 +75,6 @@ streamrw_sources = [ "native_module_streamrw.cpp" ] config("optimize-size") { cflags = [ - "-fvisibility=hidden", "-fdata-sections", "-ffunction-sections", "-Oz", @@ -87,7 +86,7 @@ config("optimize-size") { } ohos_shared_library("streamrw") { - config = [ ":optimize-size" ] + configs = [ ":optimize-size" ] branch_protector_ret = "pac_ret" sanitize = { integer_overflow = true diff --git a/interfaces/test/unittest/BUILD.gn b/interfaces/test/unittest/BUILD.gn index b61ff4d248e66c607b1b4ac87ee6c5bf6eb0dee3..95f924b844e04552b66b00271d787063419395ea 100644 --- a/interfaces/test/unittest/BUILD.gn +++ b/interfaces/test/unittest/BUILD.gn @@ -16,7 +16,6 @@ group("unittest") { deps = [ "class_file:class_file_test", "filemgmt_libn_test:filemgmt_libn_test", - "napi_test:file_api_js_test", "remote_uri:remote_uri_test", "task_signal:task_signal_test", ] diff --git a/interfaces/test/unittest/napi_test/openharmony_sx.p7b b/interfaces/test/unittest/napi_test/openharmony_sx.p7b index 166e7985b623f7bf896e6363761bb1a331c54db7..c69f83414e5ae8062eef7be0315ec8a490575eb8 100644 Binary files a/interfaces/test/unittest/napi_test/openharmony_sx.p7b and b/interfaces/test/unittest/napi_test/openharmony_sx.p7b differ diff --git a/utils/filemgmt_libn/include/n_class.h b/utils/filemgmt_libn/include/n_class.h index ca59dcc8bcac0b4c0c9b158c9270acd4161d8a57..f8f8019f402a5f1a84a59aa4bc7a869f07c9458f 100644 --- a/utils/filemgmt_libn/include/n_class.h +++ b/utils/filemgmt_libn/include/n_class.h @@ -38,6 +38,7 @@ public: napi_callback constructor, std::vector &&properties); static bool SaveClass(napi_env env, std::string className, napi_value exClass); + static void CleanClass(void *arg); static napi_value InstantiateClass(napi_env env, const std::string& className, const std::vector& args); template static T *GetEntityOf(napi_env env, napi_value objStat) @@ -82,11 +83,12 @@ public: } private: - NClass() = default; + NClass() : addCleanHook(false) {}; ~NClass() = default; static NClass &GetInstance(); std::map exClassMap; std::mutex exClassMapLock; + bool addCleanHook; }; } // namespace LibN } // namespace FileManagement diff --git a/utils/filemgmt_libn/src/n_async/n_async_work_callback.cpp b/utils/filemgmt_libn/src/n_async/n_async_work_callback.cpp index eb10bf77323dec1b324345aca45e9ba1897b0fee..74cf5a5e28656152ad77f6a5a09421fa84eb3b49 100644 --- a/utils/filemgmt_libn/src/n_async/n_async_work_callback.cpp +++ b/utils/filemgmt_libn/src/n_async/n_async_work_callback.cpp @@ -29,7 +29,7 @@ using namespace std; NAsyncWorkCallback::NAsyncWorkCallback(napi_env env, NVal thisPtr, NVal cb) : NAsyncWork(env) { - ctx_ = new NAsyncContextCallback(thisPtr, cb); + ctx_ = new(std::nothrow) NAsyncContextCallback(thisPtr, cb); } NAsyncWorkCallback::~NAsyncWorkCallback() @@ -122,7 +122,7 @@ static void CallbackComplete(napi_env env, napi_status status, void *data) NVal NAsyncWorkCallback::Schedule(string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete) { - if (!ctx_->cb_ || !ctx_->cb_.Deref(env_).TypeIs(napi_function)) { + if (!ctx_ || !ctx_->cb_ || !ctx_->cb_.Deref(env_).TypeIs(napi_function)) { HILOGE("The callback should be a function"); NError(EINVAL).ThrowErr(env_); return NVal(); @@ -214,8 +214,11 @@ void NAsyncWorkCallback::ThreadSafeSchedule(NContextCBComplete cbComplete) work->data = static_cast(workArgs.get()); int ret = uv_queue_work( - loop, work.get(), [](uv_work_t *work) {}, + loop, work.get(), [](uv_work_t *work) { + HILOGI("Enter, %{public}zu", (size_t)work); + }, [](uv_work_t *work, int status) { + HILOGI("AsyncWork Enter, %{public}zu", (size_t)work); auto workArgs = static_cast(work->data); AfterWorkCallback(workArgs->ptr->env_, napi_ok, workArgs->ptr->ctx_, workArgs->cb); delete workArgs; diff --git a/utils/filemgmt_libn/src/n_async/n_async_work_promise.cpp b/utils/filemgmt_libn/src/n_async/n_async_work_promise.cpp index 443c450efd521541549d5cfe136235f714c94765..641debf1eefc95a499bb1a6f1350ea114b0971e9 100644 --- a/utils/filemgmt_libn/src/n_async/n_async_work_promise.cpp +++ b/utils/filemgmt_libn/src/n_async/n_async_work_promise.cpp @@ -23,7 +23,7 @@ using namespace std; NAsyncWorkPromise::NAsyncWorkPromise(napi_env env, NVal thisPtr) : NAsyncWork(env) { - ctx_ = new NAsyncContextPromise(thisPtr); + ctx_ = new(std::nothrow) NAsyncContextPromise(thisPtr); } static void PromiseOnExec(napi_env env, void *data) @@ -61,6 +61,10 @@ static void PromiseOnComplete(napi_env env, napi_status status, void *data) NVal NAsyncWorkPromise::Schedule(string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete) { + if (ctx_ == nullptr) { + HILOGE("ctx is nullptr"); + return NVal(); + } ctx_->cbExec_ = move(cbExec); ctx_->cbComplete_ = move(cbComplete); diff --git a/utils/filemgmt_libn/src/n_async/n_ref.cpp b/utils/filemgmt_libn/src/n_async/n_ref.cpp index bd5ebc900d645131e24dd36c71b14bf87a0bcadc..d56a00ce9a9a65bf2ddbc82f9a46edf8b4c6b95d 100644 --- a/utils/filemgmt_libn/src/n_async/n_ref.cpp +++ b/utils/filemgmt_libn/src/n_async/n_ref.cpp @@ -30,7 +30,7 @@ NRef::NRef(NVal val) NRef::~NRef() { - if (ref_) { + if (ref_ && env_) { napi_delete_reference(env_, ref_); } } @@ -42,7 +42,7 @@ NRef::operator bool() const NVal NRef::Deref(napi_env env) { - if (!ref_) { + if (!ref_ || !env) { return NVal(); } diff --git a/utils/filemgmt_libn/src/n_class.cpp b/utils/filemgmt_libn/src/n_class.cpp index c9b8492ca8b34defe2ea62b31ed9edb549f13cea..8d94c36254f26348b5ab8403f830735710e4587b 100644 --- a/utils/filemgmt_libn/src/n_class.cpp +++ b/utils/filemgmt_libn/src/n_class.cpp @@ -59,9 +59,33 @@ bool NClass::SaveClass(napi_env env, string className, napi_value exClass) HILOGE("INNER BUG. Cannot ref class constructor %{public}s because of %{public}d", className.c_str(), res); } + if (!nClass.addCleanHook) { + napi_status status = napi_add_env_cleanup_hook(env, CleanClass, env); + if (status != napi_ok) { + HILOGE("INNER BUG. Cleanup_hook registation has failed because of %{public}d", res); + } else { + nClass.addCleanHook = true; + } + } return res == napi_ok; } +void NClass::CleanClass(void *arg) +{ + napi_env env = reinterpret_cast(arg); + NClass &nClass = NClass::GetInstance(); + lock_guard(nClass.exClassMapLock); + + napi_status res; + for (auto it = nClass.exClassMap.begin(); it != nClass.exClassMap.end(); ++it) { + res = napi_delete_reference(env, it->second); + if (res != napi_ok) { + HILOGE("Cannot del ref class constructor %{public}s because of %{public}d", it->first.c_str(), res); + } + } + nClass.exClassMap.clear(); +} + napi_value NClass::InstantiateClass(napi_env env, const string& className, const vector& args) { NClass &nClass = NClass::GetInstance(); diff --git a/utils/filemgmt_libn/src/n_error.cpp b/utils/filemgmt_libn/src/n_error.cpp index 048513bf3e7273f12be1b6cb97bea47ce795b509..cf28006ee4f16d2df9d81bf164ea25fcf70ab404 100644 --- a/utils/filemgmt_libn/src/n_error.cpp +++ b/utils/filemgmt_libn/src/n_error.cpp @@ -64,9 +64,10 @@ NError::NError() {} NError::NError(int errCode) { int genericCode = ConvertUVCode2ErrCode(errCode); - if (errCodeTable.find(genericCode) != errCodeTable.end()) { - errno_ = errCodeTable.at(genericCode).first; - errMsg_ = errCodeTable.at(genericCode).second; + auto it = errCodeTable.find(genericCode); + if (it != errCodeTable.end()) { + errno_ = it->second.first; + errMsg_ = it->second.second; } else { errno_ = errCodeTable.at(UNKROWN_ERR).first; errMsg_ = errCodeTable.at(UNKROWN_ERR).second + ", errno is " + to_string(abs(errCode)); @@ -98,9 +99,10 @@ napi_value NError::GetNapiErr(napi_env env, int errCode) } int32_t code = 0; string msg; - if (errCodeTable.find(errCode) != errCodeTable.end()) { - code = errCodeTable.at(errCode).first; - msg = errCodeTable.at(errCode).second; + auto it = errCodeTable.find(errCode); + if (it != errCodeTable.end()) { + code = it->second.first; + msg = it->second.second; } else { code = errCodeTable.at(UNKROWN_ERR).first; msg = errCodeTable.at(UNKROWN_ERR).second; diff --git a/utils/filemgmt_libn/src/n_val.cpp b/utils/filemgmt_libn/src/n_val.cpp index 6077fb13fd29a2e215e5bd3f17b35627e7816c6a..fbaa2cba0c6e876fb7dec528d98e514ccd46fce8 100644 --- a/utils/filemgmt_libn/src/n_val.cpp +++ b/utils/filemgmt_libn/src/n_val.cpp @@ -75,13 +75,19 @@ tuple, size_t> NVal::ToUTF8String() const if (status != napi_ok) { return { false, nullptr, 0 }; } - + if (strLen == std::numeric_limits::max()) { + HILOGE("string is too long"); + return { false, nullptr, 0 }; + } size_t bufLen = strLen + 1; auto str = CreateUniquePtr(bufLen); if (str == nullptr) { return { false, nullptr, 0 }; } status = napi_get_value_string_utf8(env_, val_, str.get(), bufLen, &strLen); + if (str == nullptr) { + return { false, nullptr, 0 }; + } return make_tuple(status == napi_ok, move(str), strLen); }