Skip to content

Commit

Permalink
win: use long directory name for handle->dirw
Browse files Browse the repository at this point in the history
`uv_relative_path` assumes `dir` is a prefix of `filename`, which is not
the case when `handle->dirw` is a short path.

Refs: nodejs/node#19170
PR-URL: libuv#1769
Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com>
  • Loading branch information
seishun authored and bzoz committed Mar 19, 2018
1 parent 3ae8820 commit 7e865b6
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 3 deletions.
29 changes: 27 additions & 2 deletions src/win/fs-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ static void uv_relative_path(const WCHAR* filename,
size_t relpathlen;
size_t filenamelen = wcslen(filename);
size_t dirlen = wcslen(dir);
assert(!_wcsnicmp(filename, dir, dirlen));
if (dirlen > 0 && dir[dirlen - 1] == '\\')
dirlen--;
relpathlen = filenamelen - dirlen - 1;
Expand Down Expand Up @@ -151,11 +152,11 @@ int uv_fs_event_start(uv_fs_event_t* handle,
uv_fs_event_cb cb,
const char* path,
unsigned int flags) {
int name_size, is_path_dir;
int name_size, is_path_dir, size;
DWORD attr, last_error;
WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
WCHAR short_path_buffer[MAX_PATH];
WCHAR* short_path;
WCHAR* short_path, *long_path;

if (uv__is_active(handle))
return UV_EINVAL;
Expand Down Expand Up @@ -197,6 +198,30 @@ int uv_fs_event_start(uv_fs_event_t* handle,

if (is_path_dir) {
/* path is a directory, so that's the directory that we will watch. */

/* Convert to long path. */
size = GetLongPathNameW(pathw, NULL, 0);

if (size) {
long_path = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
if (!long_path) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}

size = GetLongPathNameW(pathw, long_path, size);
if (size) {
long_path[size] = '\0';
} else {
uv__free(long_path);
long_path = NULL;
}
}

if (long_path) {
uv__free(pathw);
pathw = long_path;
}

dir_to_watch = pathw;
} else {
/*
Expand Down
38 changes: 37 additions & 1 deletion test/test-fs-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ static void fs_event_cb_dir(uv_fs_event_t* handle, const char* filename,
++fs_event_cb_called;
ASSERT(handle == &fs_event);
ASSERT(status == 0);
ASSERT(events == UV_RENAME);
ASSERT(events == UV_CHANGE);
#if defined(__APPLE__) || defined(_WIN32) || defined(__linux__)
ASSERT(strcmp(filename, "file1") == 0);
#else
Expand Down Expand Up @@ -477,6 +477,42 @@ TEST_IMPL(fs_event_watch_dir_recursive) {
#endif
}

#ifdef _WIN32
TEST_IMPL(fs_event_watch_dir_short_path) {
uv_loop_t* loop;
int r;

/* Setup */
loop = uv_default_loop();
remove("watch_dir/file1");
remove("watch_dir/");
create_dir("watch_dir");
create_file("watch_dir/file1");

r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
r = uv_fs_event_start(&fs_event, fs_event_cb_dir, "watch_~1", 0);
ASSERT(r == 0);
r = uv_timer_init(loop, &timer);
ASSERT(r == 0);
r = uv_timer_start(&timer, timer_cb_file, 100, 0);
ASSERT(r == 0);

uv_run(loop, UV_RUN_DEFAULT);

ASSERT(fs_event_cb_called == 1);
ASSERT(timer_cb_called == 1);
ASSERT(close_cb_called == 1);

/* Cleanup */
remove("watch_dir/file1");
remove("watch_dir/");

MAKE_VALGRIND_HAPPY();
return 0;
}
#endif


TEST_IMPL(fs_event_watch_file) {
#if defined(NO_FS_EVENTS)
Expand Down
6 changes: 6 additions & 0 deletions test/test-list.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ TEST_DECLARE (fs_stat_missing_path)
TEST_DECLARE (fs_read_file_eof)
TEST_DECLARE (fs_event_watch_dir)
TEST_DECLARE (fs_event_watch_dir_recursive)
#ifdef _WIN32
TEST_DECLARE (fs_event_watch_dir_short_path)
#endif
TEST_DECLARE (fs_event_watch_file)
TEST_DECLARE (fs_event_watch_file_exact_path)
TEST_DECLARE (fs_event_watch_file_twice)
Expand Down Expand Up @@ -828,6 +831,9 @@ TASK_LIST_START
TEST_ENTRY (fs_file_open_append)
TEST_ENTRY (fs_event_watch_dir)
TEST_ENTRY (fs_event_watch_dir_recursive)
#ifdef _WIN32
TEST_ENTRY (fs_event_watch_dir_short_path)
#endif
TEST_ENTRY (fs_event_watch_file)
TEST_ENTRY (fs_event_watch_file_exact_path)
TEST_ENTRY (fs_event_watch_file_twice)
Expand Down

0 comments on commit 7e865b6

Please sign in to comment.