mirror of
https://github.com/nodejs/node.git
synced 2026-11-09 15:11:11 -05:00
src: report libuv error when openAsBlob cannot stat
`FdEntry::Create()` returned nullptr for any failed `uv_fs_stat()`, discarding the status, and `BlobFromFilePath()` turned that into `ERR_INVALID_ARG_VALUE: Unable to open file as blob`. A missing file is not a malformed argument, and the resulting `TypeError` carried no `errno`, `syscall`, or `path`, so ENOENT could not be told apart from any other reason the path was unusable. Thread the libuv status out of `CreateFdEntry()` and throw a `UVException` instead, so `fs.openAsBlob()` reports the same error `fs.stat()` does for the same path. Fixes: https://github.com/nodejs/node/issues/65514 Signed-off-by: Paul Bouchon <mail@bitpshr.net> PR-URL: https://github.com/nodejs/node/pull/65517 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
1 parent
e5a1ce2125
commit
05447419fb
4 files changed
+33
-7
No files matched your search
+11
-4
@@ -868,13 +868,19 @@ class FdEntry final : public EntryImpl {
|
||||
// the race
|
||||
// condition described in the comment above.
|
||||
public:
|
||||
static std::unique_ptr<FdEntry> Create(Environment* env, Local<Value> path) {
|
||||
static std::unique_ptr<FdEntry> Create(Environment* env,
|
||||
Local<Value> path,
|
||||
int* status) {
|
||||
// We're only going to create the FdEntry if the file exists.
|
||||
uv_fs_t req = uv_fs_t();
|
||||
auto cleanup = OnScopeLeave([&] { uv_fs_req_cleanup(&req); });
|
||||
|
||||
auto buf = std::make_shared<BufferValue>(env->isolate(), path);
|
||||
if (uv_fs_stat(nullptr, &req, buf->out(), nullptr) < 0) return nullptr;
|
||||
int err = uv_fs_stat(nullptr, &req, buf->out(), nullptr);
|
||||
if (err < 0) {
|
||||
if (status != nullptr) *status = err;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_unique<FdEntry>(
|
||||
env, std::move(buf), req.statbuf, 0, req.statbuf.st_size);
|
||||
@@ -1183,8 +1189,9 @@ std::unique_ptr<DataQueue::Entry> DataQueue::CreateDataQueueEntry(
|
||||
}
|
||||
|
||||
std::unique_ptr<DataQueue::Entry> DataQueue::CreateFdEntry(Environment* env,
|
||||
Local<Value> path) {
|
||||
return FdEntry::Create(env, path);
|
||||
Local<Value> path,
|
||||
int* status) {
|
||||
return FdEntry::Create(env, path, status);
|
||||
}
|
||||
|
||||
void DataQueue::Initialize(Environment* env, v8::Local<v8::Object> target) {
|
||||
|
||||
@@ -226,8 +226,11 @@ class DataQueue : public MemoryRetainer {
|
||||
static std::unique_ptr<Entry> CreateDataQueueEntry(
|
||||
std::shared_ptr<DataQueue> data_queue);
|
||||
|
||||
// Returns nullptr if the file cannot be stat'd. When `status` is given, it
|
||||
// is set to the libuv error code so callers can report why.
|
||||
static std::unique_ptr<Entry> CreateFdEntry(Environment* env,
|
||||
v8::Local<v8::Value> path);
|
||||
v8::Local<v8::Value> path,
|
||||
int* status = nullptr);
|
||||
|
||||
// Creates a Reader for the given queue. If the queue is idempotent,
|
||||
// any number of readers can be created, all of which are guaranteed
|
||||
|
||||
Reference in new issue
Block a user