Replace the fixed-sized buffer file_fdpath with a dynamically allocated equivalent.
This commit is contained in:
@@ -48,7 +48,6 @@ extern "C" {
|
||||
#define PV_SIZEOF_PREVLINE_BUFFER 1024
|
||||
#define PV_FORMAT_ARRAY_MAX 100
|
||||
#define PV_SIZEOF_FORMAT_SEGMENTS_BUF 4096
|
||||
#define PV_SIZEOF_FILE_FDPATH 4096
|
||||
#define PV_SIZEOF_DISPLAY_NAME 512
|
||||
|
||||
#define PV_BARSTYLE_MAX 4 /* number of different styles allowed in a format */
|
||||
@@ -498,7 +497,7 @@ struct pvwatchfd_s {
|
||||
nullable_string_ptr file_fdinfo; /* path to /proc fdinfo file */
|
||||
nullable_string_ptr file_fdsymlink; /* path to /proc fd symlink */
|
||||
#endif
|
||||
char file_fdpath[PV_SIZEOF_FILE_FDPATH]; /* path to file that was opened */
|
||||
nullable_string_ptr file_fdpath; /* path to file that was opened */
|
||||
/*@keep@ */ char display_name[PV_SIZEOF_DISPLAY_NAME]; /* name to show on progress bar */
|
||||
struct stat sb_fd; /* stat of fd symlink */
|
||||
struct stat sb_fd_link; /* lstat of fd symlink */
|
||||
|
||||
+5
-1
@@ -221,7 +221,11 @@ pvstate_t pv_state_alloc(void)
|
||||
for (try_size = 32; try_size <= 16384; try_size = try_size * 2) {
|
||||
bool buffer_too_small;
|
||||
|
||||
/*@-mustfreeonly@ *//* splint mis-detects a memory leak here */
|
||||
if (NULL != state->status.cwd) {
|
||||
free(state->status.cwd);
|
||||
state->status.cwd = NULL;
|
||||
}
|
||||
/*@-mustfreeonly@ *//* splint mis-detects this as a memory leak. */
|
||||
state->status.cwd = malloc(try_size);
|
||||
/*@+mustfreeonly@ */
|
||||
if (NULL == state->status.cwd)
|
||||
|
||||
+61
-10
@@ -44,6 +44,8 @@ static bool filesize(pvwatchfd_t info)
|
||||
{
|
||||
if (NULL == info)
|
||||
return false;
|
||||
if (NULL == info->file_fdpath)
|
||||
return false;
|
||||
if (S_ISBLK(info->sb_fd.st_mode)) {
|
||||
int fd;
|
||||
|
||||
@@ -131,7 +133,15 @@ int pv_watchfd_info(pvstate_t state, pvwatchfd_t info, bool automatic)
|
||||
return 3;
|
||||
}
|
||||
|
||||
strlcpy(info->file_fdpath, vnodeInfo.pvip.vip_path, PV_SIZEOF_FILE_FDPATH);
|
||||
if (NULL != info->file_fdpath) {
|
||||
free(info->file_fdpath);
|
||||
info->file_fdpath = NULL;
|
||||
}
|
||||
info->file_fdpath = pv_strdup(vnodeInfo.pvip.vip_path);
|
||||
if (NULL == info->file_fdpath) {
|
||||
pv_perror("%s %u: %s %d", _("pid"), info->watch_pid, _("fd"), info->watch_fd);
|
||||
return 3;
|
||||
}
|
||||
|
||||
info->size = 0;
|
||||
|
||||
@@ -210,15 +220,50 @@ int pv_watchfd_info(pvstate_t state, pvwatchfd_t info, bool automatic)
|
||||
}
|
||||
|
||||
/* Get a string containing the path that the /proc fd symlink points to. */
|
||||
memset(info->file_fdpath, 0, PV_SIZEOF_FILE_FDPATH);
|
||||
if (readlink(info->file_fdsymlink, info->file_fdpath, PV_SIZEOF_FILE_FDPATH - 1) < 0) { /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder: memset() has put \0 at the end already, and
|
||||
* readlink() is given 1 byte less than the buffer length,
|
||||
* so \0 termination is assured. See filesize() above for
|
||||
* the mitigation of the risk that the link could change
|
||||
* while it is being read.
|
||||
*/
|
||||
if (NULL != info->file_fdpath) {
|
||||
free(info->file_fdpath);
|
||||
info->file_fdpath = NULL;
|
||||
}
|
||||
/* Try buffers of different sizes - see readlink(2). */
|
||||
{
|
||||
size_t try_size;
|
||||
|
||||
for (try_size = 16; try_size <= 16384; try_size = try_size * 2) {
|
||||
ssize_t bytes_stored;
|
||||
|
||||
if (NULL != info->file_fdpath) {
|
||||
free(info->file_fdpath);
|
||||
info->file_fdpath = NULL;
|
||||
}
|
||||
/*@-mustfreeonly@ *//* splint mis-detects this as a memory leak. */
|
||||
info->file_fdpath = calloc(1, try_size);
|
||||
/*@+mustfreeonly@ */
|
||||
if (NULL == info->file_fdpath)
|
||||
break;
|
||||
|
||||
bytes_stored = readlink(info->file_fdsymlink, info->file_fdpath, try_size - 1); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder: the risk is minimal, as no reads are
|
||||
* performed.
|
||||
*/
|
||||
if (bytes_stored < 0) {
|
||||
int old_errno;
|
||||
old_errno = errno;
|
||||
free(info->file_fdpath);
|
||||
info->file_fdpath = NULL;
|
||||
errno = old_errno;
|
||||
break;
|
||||
} else if (bytes_stored < (ssize_t) (try_size - 1)) {
|
||||
info->file_fdpath[bytes_stored] = '\0';
|
||||
break;
|
||||
} else {
|
||||
free(info->file_fdpath);
|
||||
info->file_fdpath = NULL;
|
||||
errno = ENAMETOOLONG;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NULL == info->file_fdpath) {
|
||||
if (!automatic)
|
||||
pv_perror("%s %u: %s %d", _("pid"), info->watch_pid, _("fd"), info->watch_fd);
|
||||
return 2;
|
||||
@@ -459,6 +504,10 @@ void pv_freecontents_watchfd(pvwatchfd_t info)
|
||||
info->file_fdsymlink = NULL;
|
||||
}
|
||||
#endif
|
||||
if (NULL != info->file_fdpath) {
|
||||
free(info->file_fdpath);
|
||||
info->file_fdpath = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -725,6 +774,8 @@ void pv_watchpid_setname(pvstate_t state, pvwatchfd_t info)
|
||||
file_fdpath = info->file_fdpath;
|
||||
|
||||
memset(info->display_name, 0, PV_SIZEOF_DISPLAY_NAME);
|
||||
if (NULL == file_fdpath)
|
||||
return;
|
||||
|
||||
path_length = strlen(info->file_fdpath); /* flawfinder: ignore */
|
||||
cwd_length = 0;
|
||||
|
||||
Reference in New Issue
Block a user