fs: fix crash in uv_fs_scandir_next
Handle the case when it's called after the request has ended, or in case it ended with an error. PR-URL: https://github.com/libuv/libuv/pull/1181 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
parent
d251dee33b
commit
c8ab24bb92
@ -512,8 +512,18 @@ void uv__fs_scandir_cleanup(uv_fs_t* req) {
|
||||
int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) {
|
||||
uv__dirent_t** dents;
|
||||
uv__dirent_t* dent;
|
||||
unsigned int* nbufs;
|
||||
|
||||
unsigned int* nbufs = uv__get_nbufs(req);
|
||||
/* Check to see if req passed */
|
||||
if (req->result < 0)
|
||||
return req->result;
|
||||
|
||||
/* Ptr will be null if req was canceled or no files found */
|
||||
if (!req->ptr)
|
||||
return UV_EOF;
|
||||
|
||||
nbufs = uv__get_nbufs(req);
|
||||
assert(nbufs);
|
||||
|
||||
dents = req->ptr;
|
||||
|
||||
|
||||
@ -510,6 +510,18 @@ static void empty_scandir_cb(uv_fs_t* req) {
|
||||
scandir_cb_count++;
|
||||
}
|
||||
|
||||
static void non_existent_scandir_cb(uv_fs_t* req) {
|
||||
uv_dirent_t dent;
|
||||
|
||||
ASSERT(req == &scandir_req);
|
||||
ASSERT(req->fs_type == UV_FS_SCANDIR);
|
||||
ASSERT(req->result == UV_ENOENT);
|
||||
ASSERT(req->ptr == NULL);
|
||||
ASSERT(UV_ENOENT == uv_fs_scandir_next(req, &dent));
|
||||
uv_fs_req_cleanup(req);
|
||||
scandir_cb_count++;
|
||||
}
|
||||
|
||||
|
||||
static void file_scandir_cb(uv_fs_t* req) {
|
||||
ASSERT(req == &scandir_req);
|
||||
@ -2175,6 +2187,39 @@ TEST_IMPL(fs_scandir_empty_dir) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_scandir_non_existent_dir) {
|
||||
const char* path;
|
||||
uv_fs_t req;
|
||||
uv_dirent_t dent;
|
||||
int r;
|
||||
|
||||
path = "./non_existent_dir/";
|
||||
loop = uv_default_loop();
|
||||
|
||||
uv_fs_rmdir(NULL, &req, path, NULL);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
/* Fill the req to ensure that required fields are cleaned up */
|
||||
memset(&req, 0xdb, sizeof(req));
|
||||
|
||||
r = uv_fs_scandir(NULL, &req, path, 0, NULL);
|
||||
ASSERT(r == UV_ENOENT);
|
||||
ASSERT(req.result == UV_ENOENT);
|
||||
ASSERT(req.ptr == NULL);
|
||||
ASSERT(UV_ENOENT == uv_fs_scandir_next(&req, &dent));
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
r = uv_fs_scandir(loop, &scandir_req, path, 0, non_existent_scandir_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(scandir_cb_count == 0);
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
ASSERT(scandir_cb_count == 1);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_scandir_file) {
|
||||
const char* path;
|
||||
int r;
|
||||
|
||||
@ -295,6 +295,7 @@ TEST_DECLARE (fs_event_start_and_close)
|
||||
TEST_DECLARE (fs_event_error_reporting)
|
||||
TEST_DECLARE (fs_event_getpath)
|
||||
TEST_DECLARE (fs_scandir_empty_dir)
|
||||
TEST_DECLARE (fs_scandir_non_existent_dir)
|
||||
TEST_DECLARE (fs_scandir_file)
|
||||
TEST_DECLARE (fs_open_dir)
|
||||
TEST_DECLARE (fs_rename_to_existing_file)
|
||||
@ -751,6 +752,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (fs_event_error_reporting)
|
||||
TEST_ENTRY (fs_event_getpath)
|
||||
TEST_ENTRY (fs_scandir_empty_dir)
|
||||
TEST_ENTRY (fs_scandir_non_existent_dir)
|
||||
TEST_ENTRY (fs_scandir_file)
|
||||
TEST_ENTRY (fs_open_dir)
|
||||
TEST_ENTRY (fs_rename_to_existing_file)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user