From 7ae4b1ad7f6d09f5994403b253a0494a6642c8f2 Mon Sep 17 00:00:00 2001 From: Jason Ginchereau Date: Sat, 13 Aug 2016 00:12:21 -0700 Subject: [PATCH] win: fix lstat reparse point without link data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: https://github.com/libuv/libuv/issues/995 Fixes: https://github.com/nodejs/node/issues/5160 PR-URL: https://github.com/libuv/libuv/pull/996 Reviewed-By: Saúl Ibarra Corretgé --- src/win/fs.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/win/fs.c b/src/win/fs.c index b6d43921..6a4157bf 100644 --- a/src/win/fs.c +++ b/src/win/fs.c @@ -1088,17 +1088,28 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf) { statbuf->st_mode = 0; if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - statbuf->st_mode |= S_IFLNK; - if (fs__readlink_handle(handle, NULL, &statbuf->st_size) != 0) + /* + * It is possible for a file to have FILE_ATTRIBUTE_REPARSE_POINT but not have + * any link data. In that case DeviceIoControl() in fs__readlink_handle() sets + * the last error to ERROR_NOT_A_REPARSE_POINT. Then the stat result mode + * calculated below will indicate a normal directory or file, as if + * FILE_ATTRIBUTE_REPARSE_POINT was not present. + */ + if (fs__readlink_handle(handle, NULL, &statbuf->st_size) == 0) { + statbuf->st_mode |= S_IFLNK; + } else if (GetLastError() != ERROR_NOT_A_REPARSE_POINT) { return -1; + } + } - } else if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - statbuf->st_mode |= _S_IFDIR; - statbuf->st_size = 0; - - } else { - statbuf->st_mode |= _S_IFREG; - statbuf->st_size = file_info.StandardInformation.EndOfFile.QuadPart; + if (statbuf->st_mode == 0) { + if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + statbuf->st_mode |= _S_IFDIR; + statbuf->st_size = 0; + } else { + statbuf->st_mode |= _S_IFREG; + statbuf->st_size = file_info.StandardInformation.EndOfFile.QuadPart; + } } if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_READONLY)