From e1a50b44836dc32087bbae4782dd64e65b2334d0 Mon Sep 17 00:00:00 2001 From: gwx1278443 Date: Sun, 26 Nov 2023 17:27:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=A7=E5=87=BD=E6=95=B0=E6=95=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: gwx1278443 --- .../mod_fs/class_stream/stream_n_exporter.cpp | 78 +++++++++++------- .../mod_fs/class_stream/stream_n_exporter.h | 8 ++ .../src/mod_fs/properties/prop_n_exporter.cpp | 70 ++++++++-------- .../js/src/mod_fs/properties/read_text.cpp | 80 ++++++++++++------- 4 files changed, 145 insertions(+), 91 deletions(-) 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 bf11f3609..a4fa561d4 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 @@ -215,62 +215,78 @@ napi_value StreamNExporter::Write(napi_env env, napi_callback_info cbInfo) return WriteExec(env, funcArg, streamEntity); } -static napi_value ReadExec(napi_env env, NFuncArg &funcArg, StreamEntity *streamEntity) +static bool PerformRead(napi_env env, NFuncArg &funcArg, StreamEntity *streamEntity, ReadArgs &readArgs) { - auto [succ, buf, len, offset] = - CommonFunc::GetReadArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); + auto [succ, rawBuf, len, offset] = CommonFunc::GetReadArg(env, funcArg[NARG_POS::FIRST], funcArg[NARG_POS::SECOND]); if (!succ) { HILOGE("Failed to resolve buf and options"); NError(EINVAL).ThrowErr(env); - return nullptr; + return false; } - auto arg = CreateSharedPtr(NVal(env, funcArg[NARG_POS::FIRST])); - if (arg == nullptr) { + readArgs.arg = CreateSharedPtr(NVal(env, funcArg[NARG_POS::FIRST])); + if (readArgs.arg == nullptr) { HILOGE("Failed to request heap memory."); NError(ENOMEM).ThrowErr(env); - return nullptr; + return false; } - auto cbExec = [arg, buf = buf, len = len, streamEntity, offset = offset]() -> NError { - if (!streamEntity || !streamEntity->fp.get()) { - HILOGE("Stream has been closed in read cbExec possibly"); - return NError(EIO); - } - if (offset >= 0) { - int ret = fseek(streamEntity->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); - } - } - size_t actLen = fread(buf, 1, len, streamEntity->fp.get()); - if ((actLen != static_cast(len) && !feof(streamEntity->fp.get())) || ferror(streamEntity->fp.get())) { - HILOGE("Invalid buffer size and pointer, actlen: %{public}zu", actLen); - return NError(EIO); - } else { - arg->lenRead = actLen; - return NError(ERRNO_NOERR); + + readArgs.buf.resize(len); + readArgs.len = len; + readArgs.offset = offset; + + if (!streamEntity || !streamEntity->fp.get()) { + HILOGE("Stream has been closed in read cbExec possibly"); + return false; + } + + if (offset >= 0) { + if (fseek(streamEntity->fp.get(), static_cast(offset), SEEK_SET) < 0) { + HILOGE("Failed to set the offset location of the file stream pointer"); + NError(errno).ThrowErr(env); + return false; } - }; + } - auto cbCompl = [arg](napi_env env, NError err) -> NVal { + readArgs.actLen = fread(&readArgs.buf[0], 1, len, streamEntity->fp.get()); + bool incompleteRead = readArgs.actLen != static_cast(len) && !feof(streamEntity->fp.get()); + if (incompleteRead || ferror(streamEntity->fp.get())) { + HILOGE("Invalid buffer size and pointer, actlen: %{public}zu", readArgs.actLen); + NError(EIO).ThrowErr(env); + return false; + } + + readArgs.buf.resize(readArgs.actLen); + return true; +} + + +static napi_value ReadExec(napi_env env, NFuncArg &funcArg, StreamEntity *streamEntity) +{ + ReadArgs readArgs; + if (!PerformRead(env, funcArg, streamEntity, readArgs)) { + return nullptr; + } + + auto cbCompl = [&readArgs](napi_env env, NError err) -> NVal { if (err) { return { env, err.GetNapiErr(env) }; } - return { NVal::CreateInt64(env, arg->lenRead) }; + return { NVal::CreateInt64(env, readArgs.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))) { - return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_STREAM_READ_NAME, cbExec, cbCompl).val_; + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_STREAM_READ_NAME, nullptr, cbCompl).val_; } else { int cbIdx = ((funcArg.GetArgc() == NARG_CNT::TWO) ? NARG_POS::SECOND : NARG_POS::THIRD); NVal cb(env, funcArg[cbIdx]); - return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_STREAM_READ_NAME, cbExec, cbCompl).val_; + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_STREAM_READ_NAME, nullptr, cbCompl).val_; } } + napi_value StreamNExporter::Read(napi_env env, napi_callback_info cbInfo) { NFuncArg funcArg(env, cbInfo); 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 c68c246ad..906a7f041 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 @@ -51,6 +51,14 @@ struct AsyncReadArg { ~AsyncReadArg() = default; }; +struct ReadArgs { + std::shared_ptr arg; + std::string buf; + size_t len; + off_t offset; + size_t actLen; +}; + struct AsyncWriteArg { NRef refWriteArrayBuf; std::unique_ptr guardWriteStr = nullptr; 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 89e612164..3f4994852 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 @@ -65,6 +65,18 @@ namespace ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; +static int AccessCore(const string &path) +{ + 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(), 0, nullptr); + return ret; +} + napi_value PropNExporter::AccessSync(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); @@ -82,14 +94,7 @@ napi_value PropNExporter::AccessSync(napi_env env, napi_callback_info info) } bool isAccess = false; - std::unique_ptr access_req = { - new uv_fs_t, CommonFunc::fs_req_cleanup }; - if (!access_req) { - HILOGE("Failed to request heap memory."); - NError(ENOMEM).ThrowErr(env); - return nullptr; - } - int ret = uv_fs_access(nullptr, access_req.get(), path.get(), 0, nullptr); + int ret = AccessCore(path.get()); if (ret < 0 && (string_view(uv_err_name(ret)) != "ENOENT")) { HILOGE("Failed to access file by path"); NError(ret).ThrowErr(env); @@ -124,13 +129,7 @@ napi_value PropNExporter::Access(napi_env env, napi_callback_info info) return nullptr; } auto cbExec = [path = string(tmp.get()), result]() -> NError { - std::unique_ptr access_req = { - new uv_fs_t, CommonFunc::fs_req_cleanup }; - if (!access_req) { - HILOGE("Failed to request heap memory."); - return NError(ENOMEM); - } - int ret = uv_fs_access(nullptr, access_req.get(), path.c_str(), 0, nullptr); + int ret = AccessCore(path); if (ret == 0) { result->isAccess = true; } @@ -248,10 +247,24 @@ static NError MkdirExec(const string &path, bool recursion, bool hasOption) { #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) if (hasOption) { + int ret = AccessCore(path); + if (ret == ERRNO_NOERR) { + HILOGE("The path already exists"); + return NError(EEXIST); + } + if (ret != -ENOENT) { + HILOGE("Failed to check for illegal path or request for heap memory"); + return NError(ret); + } if (::Mkdirs(path.c_str(), static_cast(recursion)) < 0) { HILOGE("Failed to create directories, error: %{public}d", errno); return NError(errno); } + ret = AccessCore(path); + if (ret) { + HILOGE("Failed to verify the result of Mkdirs function"); + return NError(ret); + } return NError(ERRNO_NOERR); } #endif @@ -326,28 +339,21 @@ napi_value PropNExporter::MkdirSync(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } + bool hasOption = false; + bool recursion = false; #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) if (funcArg.GetArgc() == NARG_CNT::TWO) { - auto [success, recursion] = NVal(env, funcArg[NARG_POS::SECOND]).ToBool(false); - if (!success) { + tie(hasOption, recursion) = NVal(env, funcArg[NARG_POS::SECOND]).ToBool(false); + if (!hasOption) { HILOGE("Invalid recursion mode"); NError(EINVAL).ThrowErr(env); return nullptr; } - MakeDirectionMode recursionMode = SINGLE; - recursionMode = static_cast(recursion); - if (::Mkdirs(path.get(), recursionMode) < 0) { - HILOGE("Failed to create directories, error: %{public}d", errno); - NError(errno).ThrowErr(env); - return nullptr; - } - return NVal::CreateUndefined(env).val_; } #endif - int ret = MkdirCore(path.get()); - if (ret) { - HILOGE("Failed to create directory"); - NError(ret).ThrowErr(env); + auto err = MkdirExec(path.get(), recursion, hasOption); + if (err) { + err.ThrowErr(env); return nullptr; } return NVal::CreateUndefined(env).val_; @@ -503,9 +509,7 @@ napi_value PropNExporter::Write(napi_env env, napi_callback_info info) return nullptr; } - bool succ = false; - int32_t fd = 0; - tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + auto[succ, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); if (!succ || fd < 0) { HILOGE("Invalid fd from JS first argument"); NError(EINVAL).ThrowErr(env); @@ -530,7 +534,7 @@ napi_value PropNExporter::Write(napi_env env, napi_callback_info info) NError(ENOMEM).ThrowErr(env); return nullptr; } - auto cbExec = [arg, buf, len, fd, offset]() -> NError { + auto cbExec = [arg, buf, len, fd = fd, offset]() -> NError { return WriteExec(arg, static_cast(buf), len, fd, offset); }; diff --git a/interfaces/kits/js/src/mod_fs/properties/read_text.cpp b/interfaces/kits/js/src/mod_fs/properties/read_text.cpp index da1693ca3..85e6c593d 100755 --- a/interfaces/kits/js/src/mod_fs/properties/read_text.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/read_text.cpp @@ -119,6 +119,53 @@ static NError ReadTextAsync(const std::string &path, std::shared_ptr, + OHOS::DistributedFS::FDGuard> OpenFile(napi_env env, const std::string& path) +{ + std::unique_ptr open_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup + }; + if (!open_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return std::make_tuple(std::move(open_req), OHOS::DistributedFS::FDGuard()); + } + + int ret = uv_fs_open(nullptr, open_req.get(), path.c_str(), O_RDONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, nullptr); + if (ret < 0) { + HILOGE("Failed to open file by ret: %{public}d", ret); + NError(errno).ThrowErr(env); + return std::make_tuple(std::move(open_req), OHOS::DistributedFS::FDGuard()); + } + OHOS::DistributedFS::FDGuard sfd(ret); + return {std::move(open_req), std::move(sfd)}; +} + +std::tuple ReadFromFile(napi_env env, OHOS::DistributedFS::FDGuard& sfd, int64_t offset, int64_t len) +{ + std::string buffer(len, '\0'); + uv_buf_t readbuf = uv_buf_init(const_cast(buffer.c_str()), static_cast(len)); + + std::unique_ptr read_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup + }; + if (!read_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return std::make_tuple(-1, ""); + } + + int ret = uv_fs_read(nullptr, read_req.get(), sfd.GetFD(), &readbuf, 1, offset, nullptr); + if (ret < 0) { + HILOGE("Failed to read file by fd: %{public}d", sfd.GetFD()); + NError(errno).ThrowErr(env); + return std::make_tuple(-1, ""); + } + + return std::make_tuple(ret, buffer); +} + napi_value ReadText::Sync(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); @@ -141,24 +188,13 @@ napi_value ReadText::Sync(napi_env env, napi_callback_info info) return nullptr; } - OHOS::DistributedFS::FDGuard sfd; - std::unique_ptr open_req = { - new uv_fs_t, CommonFunc::fs_req_cleanup }; + auto [open_req, sfd] = OpenFile(env, path.get()); if (!open_req) { - HILOGE("Failed to request heap memory."); - NError(ENOMEM).ThrowErr(env); return nullptr; } - int ret = uv_fs_open(nullptr, open_req.get(), path.get(), O_RDONLY, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, nullptr); - if (ret < 0) { - HILOGE("Failed to open file by ret: %{public}d", ret); - NError(errno).ThrowErr(env); - return nullptr; - } - sfd.SetFD(ret); + struct stat statbf; - if ((!sfd) || (fstat(sfd.GetFD(), &statbf) < 0)) { + if (fstat(sfd.GetFD(), &statbf) < 0) { HILOGE("Failed to get stat of file by fd: %{public}d", sfd.GetFD()); NError(errno).ThrowErr(env); return nullptr; @@ -171,23 +207,13 @@ napi_value ReadText::Sync(napi_env env, napi_callback_info info) } len = (!hasLen || len > statbf.st_size) ? statbf.st_size : len; - string buffer(len, '\0'); - uv_buf_t readbuf = uv_buf_init(const_cast(buffer.c_str()), static_cast(len)); - std::unique_ptr read_req = { - new uv_fs_t, CommonFunc::fs_req_cleanup }; - if (!read_req) { - HILOGE("Failed to request heap memory."); - NError(ENOMEM).ThrowErr(env); - return nullptr; - } - ret = uv_fs_read(nullptr, read_req.get(), sfd.GetFD(), &readbuf, 1, offset, nullptr); + + auto [ret, buffer] = ReadFromFile(env, sfd, offset, len); if (ret < 0) { - HILOGE("Failed to read file by fd: %{public}d", sfd.GetFD()); - NError(errno).ThrowErr(env); return nullptr; } - return NVal::CreateUTF8String(env, readbuf.base, ret).val_; + return NVal::CreateUTF8String(env, buffer.c_str(), ret).val_; } napi_value ReadText::Async(napi_env env, napi_callback_info info) -- Gitee