libuv icon indicating copy to clipboard operation
libuv copied to clipboard

uv_fs_scandir memory leak

Open 5415nofar1 opened this issue 3 years ago • 0 comments

In some case of breaking the loop uv_fs_scandir_next() before the end , there seems to be a memory leak of the last entry

uv_fs_t scandir_req{}
uv_dirent_t entry{}

res = uv_fs_scandir(NULL, &scandir_req, path, 0, NULL);
...

while (UV_EOF != uv_fs_scandir_next(&scandir_req, &entry))
{
     ...
      goto exit;
}

exit:
  uv_fs_req_cleanup(&scandir_req)

my test directory includes only one file. if I am waiting until the end of the loop (one more iteration) there is no memory leak.

from my short research , I saw difference between the two cleanup cases (breaking the rule before UV_EOF and after)

Breaking the loop (my case)

uv_fs_req_cleanup calls uv__fs_scandir_cleanup(req)

void uv__fs_scandir_cleanup(uv_fs_t* req) {
  uv__dirent_t** dents;

  unsigned int* nbufs = uv__get_nbufs(req);

  dents = req->ptr;
  if (*nbufs > 0 && nbufs != (unsigned int) req->result)    // **the previous entity is not released**
    (*nbufs)--;
  for (; *nbufs < (unsigned int) req->result; (*nbufs)++)
    uv__fs_scandir_free(dents[*nbufs]);

  uv__fs_scandir_free(req->ptr);
  req->ptr = NULL;
}

Running until UV_EOF case (one more time):

the last uv_fs_scandir_next call releases the previous entity

int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) {
  uv__dirent_t** dents;
  uv__dirent_t* dent;
  unsigned int* nbufs;

  /* 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;

  /* Free previous entity */
  if (*nbufs > 0)
    uv__fs_scandir_free(dents[*nbufs - 1]);      // **the previous entity is released**

  /* End was already reached */
  if (*nbufs == (unsigned int) req->result) {
    uv__fs_scandir_free(dents);
    req->ptr = NULL;
    return UV_EOF;
  }

  ....
}

Is the uv__fs_scandir_cleanup's condition wrong? (nbufs != (unsigned int) req->result )

  • Version: v1.39.0
  • Platform: Linux ubuntu 5.4.0-113-generic

5415nofar1 avatar Sep 14 '22 13:09 5415nofar1