fs: fix readdir failure when libuv returns UV_DIRENT_UNKNOWN

Fixes: https://github.com/nodejs/node/issues/33348

PR-URL: https://github.com/nodejs/node/pull/33395
Refs: https://github.com/nodejs/node/issues/33348
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Kirill Shatskiy 2020-05-14 10:32:38 +03:00 committed by James M Snell
parent b831b081c4
commit 82f13fa803
No known key found for this signature in database
GPG key ID: 7341B15C070877AC
3 changed files with 182 additions and 3 deletions

View file

@ -173,6 +173,31 @@ function copyObject(source) {
return target;
}
const bufferSep = Buffer.from(pathModule.sep);
function join(path, name) {
if ((typeof path === 'string' || isUint8Array(path)) &&
name === undefined) {
return path;
}
if (typeof path === 'string' && isUint8Array(name)) {
const pathBuffer = Buffer.from(pathModule.join(path, pathModule.sep));
return Buffer.concat([pathBuffer, name]);
}
if (typeof path === 'string' && typeof name === 'string') {
return pathModule.join(path, name);
}
if (isUint8Array(path) && isUint8Array(name)) {
return Buffer.concat([path, bufferSep, name]);
}
throw new ERR_INVALID_ARG_TYPE(
'path', ['string', 'Buffer'], path);
}
function getDirents(path, [names, types], callback) {
let i;
if (typeof callback === 'function') {
@ -185,7 +210,14 @@ function getDirents(path, [names, types], callback) {
const name = names[i];
const idx = i;
toFinish++;
lazyLoadFs().lstat(pathModule.join(path, name), (err, stats) => {
let filepath;
try {
filepath = join(path, name);
} catch (err) {
callback(err);
return;
}
lazyLoadFs().lstat(filepath, (err, stats) => {
if (err) {
callback(err);
return;
@ -214,7 +246,14 @@ function getDirents(path, [names, types], callback) {
function getDirent(path, name, type, callback) {
if (typeof callback === 'function') {
if (type === UV_DIRENT_UNKNOWN) {
lazyLoadFs().lstat(pathModule.join(path, name), (err, stats) => {
let filepath;
try {
filepath = join(path, name);
} catch (err) {
callback(err);
return;
}
lazyLoadFs().lstat(filepath, (err, stats) => {
if (err) {
callback(err);
return;
@ -225,7 +264,7 @@ function getDirent(path, name, type, callback) {
callback(null, new Dirent(name, type));
}
} else if (type === UV_DIRENT_UNKNOWN) {
const stats = lazyLoadFs().lstatSync(pathModule.join(path, name));
const stats = lazyLoadFs().lstatSync(join(path, name));
return new DirentFromStats(name, stats);
} else {
return new Dirent(name, type);