mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-03-23 15:09:24 -05:00
pscp: replace crash with diagnostic on opendir failure.
A user points out that the call to close_directory() in pscp.c's rsource() function should have been inside rather than outside the if statement that checks whether the directory handle is NULL. As a result, any failed attempt to open a directory during a 'pscp -r' recursive upload leads to a null-pointer dereference. Moved the close_directory call to where it should be, and also arranged to print the OS error code if the directory-open fails, by also changing the API of open_directory to return an error string on failure.
This commit is contained in:
parent
3322d4c082
commit
85fbb4216e
7
pscp.c
7
pscp.c
@ -1696,7 +1696,8 @@ static void rsource(const char *src)
|
|||||||
if (scp_send_dirname(last, 0755))
|
if (scp_send_dirname(last, 0755))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dir = open_directory(src);
|
const char *opendir_err;
|
||||||
|
dir = open_directory(src, &opendir_err);
|
||||||
if (dir != NULL) {
|
if (dir != NULL) {
|
||||||
char *filename;
|
char *filename;
|
||||||
while ((filename = read_filename(dir)) != NULL) {
|
while ((filename = read_filename(dir)) != NULL) {
|
||||||
@ -1705,8 +1706,10 @@ static void rsource(const char *src)
|
|||||||
sfree(foundfile);
|
sfree(foundfile);
|
||||||
sfree(filename);
|
sfree(filename);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
close_directory(dir);
|
close_directory(dir);
|
||||||
|
} else {
|
||||||
|
tell_user(stderr, "Error opening directory %s: %s", src, opendir_err);
|
||||||
|
}
|
||||||
|
|
||||||
(void) scp_send_enddir();
|
(void) scp_send_enddir();
|
||||||
|
|
||||||
|
5
psftp.c
5
psftp.c
@ -533,6 +533,7 @@ bool sftp_put_file(char *fname, char *outfname, bool recurse, bool restart)
|
|||||||
bool result;
|
bool result;
|
||||||
int nnames, namesize;
|
int nnames, namesize;
|
||||||
char *name, **ournames;
|
char *name, **ournames;
|
||||||
|
const char *opendir_err;
|
||||||
DirHandle *dh;
|
DirHandle *dh;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -563,9 +564,9 @@ bool sftp_put_file(char *fname, char *outfname, bool recurse, bool restart)
|
|||||||
nnames = namesize = 0;
|
nnames = namesize = 0;
|
||||||
ournames = NULL;
|
ournames = NULL;
|
||||||
|
|
||||||
dh = open_directory(fname);
|
dh = open_directory(fname, &opendir_err);
|
||||||
if (!dh) {
|
if (!dh) {
|
||||||
printf("%s: unable to open directory\n", fname);
|
printf("%s: unable to open directory: %s\n", fname, opendir_err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while ((name = read_filename(dh)) != NULL) {
|
while ((name = read_filename(dh)) != NULL) {
|
||||||
|
2
psftp.h
2
psftp.h
@ -127,7 +127,7 @@ int file_type(const char *name);
|
|||||||
* Read all the file names out of a directory.
|
* Read all the file names out of a directory.
|
||||||
*/
|
*/
|
||||||
typedef struct DirHandle DirHandle;
|
typedef struct DirHandle DirHandle;
|
||||||
DirHandle *open_directory(const char *name);
|
DirHandle *open_directory(const char *name, const char **errmsg);
|
||||||
/* The string returned from this will need freeing if not NULL */
|
/* The string returned from this will need freeing if not NULL */
|
||||||
char *read_filename(DirHandle *dir);
|
char *read_filename(DirHandle *dir);
|
||||||
void close_directory(DirHandle *dir);
|
void close_directory(DirHandle *dir);
|
||||||
|
@ -311,14 +311,16 @@ struct DirHandle {
|
|||||||
DIR *dir;
|
DIR *dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
DirHandle *open_directory(const char *name)
|
DirHandle *open_directory(const char *name, const char **errmsg)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
DirHandle *ret;
|
DirHandle *ret;
|
||||||
|
|
||||||
dir = opendir(name);
|
dir = opendir(name);
|
||||||
if (!dir)
|
if (!dir) {
|
||||||
|
*errmsg = strerror(errno);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ret = snew(DirHandle);
|
ret = snew(DirHandle);
|
||||||
ret->dir = dir;
|
ret->dir = dir;
|
||||||
|
@ -266,7 +266,7 @@ struct DirHandle {
|
|||||||
char *name;
|
char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
DirHandle *open_directory(const char *name)
|
DirHandle *open_directory(const char *name, const char **errmsg)
|
||||||
{
|
{
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
WIN32_FIND_DATA fdat;
|
WIN32_FIND_DATA fdat;
|
||||||
@ -276,8 +276,10 @@ DirHandle *open_directory(const char *name)
|
|||||||
/* Enumerate files in dir `foo'. */
|
/* Enumerate files in dir `foo'. */
|
||||||
findfile = dupcat(name, "/*", NULL);
|
findfile = dupcat(name, "/*", NULL);
|
||||||
h = FindFirstFile(findfile, &fdat);
|
h = FindFirstFile(findfile, &fdat);
|
||||||
if (h == INVALID_HANDLE_VALUE)
|
if (h == INVALID_HANDLE_VALUE) {
|
||||||
|
*errmsg = win_strerror(GetLastError());
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
sfree(findfile);
|
sfree(findfile);
|
||||||
|
|
||||||
ret = snew(DirHandle);
|
ret = snew(DirHandle);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user