1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-27 01:25:34 +00:00

Merge pull request #115 from sgerwk/master

avoid use of tempnam
This commit is contained in:
rkd77 2021-04-03 14:17:15 +02:00 committed by GitHub
commit bd442edc8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 102 additions and 26 deletions

View File

@ -1018,3 +1018,84 @@ get_system_str(int xwin)
{
return xwin ? SYSTEM_STR "-xwin" : SYSTEM_STR;
}
#if _DEFAULT_SOURCE || _SVID_SOURCE || _BSD_SOURCE
/* tempnam() replacement without races */
int isdirectory(char *path) {
struct stat ss;
if (path == NULL)
return 0;
if (-1 == stat(path, &ss))
return 0;
return S_ISDIR(ss.st_mode);
}
char *tempname(char *dir, char *pfx, char *suff) {
struct string path;
char *ret;
int fd;
if (isdirectory(getenv("TMPDIR")))
dir = getenv("TMPDIR");
else if (dir != NULL)
dir = dir;
else if (isdirectory(P_tmpdir))
dir = P_tmpdir;
else if (isdirectory("/tmp"))
dir = "/tmp";
else {
errno = ENOTDIR;
return NULL;
}
if (!init_string(&path)) {
errno = ENOMEM;
return NULL;
}
add_to_string(&path, dir);
add_to_string(&path, "/");
add_to_string(&path, pfx);
add_to_string(&path, "XXXXXX");
if (suff)
add_shell_safe_to_string(&path, suff, strlen(suff));
fd = mkstemps(path.source, suff ? strlen(suff) : 0);
if (fd == -1) {
done_string(&path);
errno = ENOENT;
return NULL;
}
close(fd);
ret = strdup(path.source);
done_string(&path);
return ret;
}
#else
#warning mkstemps does not exist, using tempnam
char *tempname(char *dir, char *pfx, char *suff) {
char *temp, *ret;
struct string name;
temp = tempnam(dir, pfx);
if (temp == NULL)
return NULL;
if (!init_string(&name)) {
free(temp);
return NULL;
}
add_to_string(&name, temp);
free(temp);
add_shell_safe_to_string(&name, suff, strlen(suff));
ret = strdup(name.source);
done_string(&name);
return ret;
}
#endif

View File

@ -52,6 +52,7 @@ int resize_window(int, int, int, int);
int can_resize_window(int);
int can_open_os_shell(int);
void set_highpri(void);
char *tempname(char *dir, char *pfx, char *suff);
#ifdef USE_OPEN_PREALLOC
int open_prealloc(char *, int, int, off_t);

View File

@ -800,7 +800,7 @@ lookup_unique_name(struct terminal *term, char *ofile,
}
/* Check if the file already exists (file != ofile). */
file = get_unique_name(ofile);
file = (flags & DOWNLOAD_OVERWRITE) ? ofile : get_unique_name(ofile);
if (!file || overwrite == 1 || file == ofile) {
/* Still nothing special to do... */
@ -885,7 +885,9 @@ create_download_file_do(struct terminal *term, char *file,
* --pasky */
h = open(file, O_CREAT | O_WRONLY
| (flags & DOWNLOAD_RESUME_SELECTED ? 0 : O_TRUNC)
| (sf && !(flags & DOWNLOAD_RESUME_SELECTED) ? O_EXCL : 0),
| (sf &&
!(flags & DOWNLOAD_RESUME_SELECTED) &&
!(flags & DOWNLOAD_OVERWRITE) ? O_EXCL : 0),
sf ? 0600 : 0666);
saved_errno = errno; /* Saved in case of ... --Zas */
@ -999,31 +1001,17 @@ create_download_file(struct terminal *term, char *fi,
static char *
get_temp_name(struct uri *uri)
{
struct string name;
char *extension;
/* FIXME
* We use tempnam() here, which is unsafe (race condition), for now.
* This should be changed at some time, but it needs an in-depth work
* of whole download code. --Zas */
char *nm = tempnam(NULL, ELINKS_TEMPNAME_PREFIX);
if (!nm) return NULL;
if (!init_string(&name)) {
free(nm);
return NULL;
}
add_to_string(&name, nm);
free(nm);
char *nm;
extension = get_extension_from_uri(uri);
if (extension) {
add_shell_safe_to_string(&name, extension, strlen(extension));
mem_free(extension);
}
if (!extension)
extension = stracpy("");
return name.source;
nm = tempname(NULL, ELINKS_TEMPNAME_PREFIX, extension);
mem_free(extension);
return nm;
}
@ -1321,7 +1309,6 @@ continue_download(void *data, char *file)
}
if (type_query->external_handler) {
/* FIXME: get_temp_name() calls tempnam(). --Zas */
file = get_temp_name(type_query->uri);
if (!file) {
mem_free(codw_hop);
@ -1338,7 +1325,9 @@ continue_download(void *data, char *file)
create_download_file(type_query->ses->tab->term, file,
&codw_hop->real_file,
type_query->external_handler
? DOWNLOAD_RESUME_ALLOWED | DOWNLOAD_EXTERNAL
? DOWNLOAD_RESUME_ALLOWED |
DOWNLOAD_EXTERNAL |
DOWNLOAD_OVERWRITE
: DOWNLOAD_RESUME_ALLOWED,
continue_download_do, codw_hop);
}

View File

@ -39,7 +39,12 @@ enum download_flags {
DOWNLOAD_RESUME_SELECTED = 2,
/** The file will be opened in an external handler. */
DOWNLOAD_EXTERNAL = 4
DOWNLOAD_EXTERNAL = 4,
/** File overwriting is allowed. This is for temp names, since
* the file is created by the same function that chooses its
* name. */
DOWNLOAD_OVERWRITE = 8
};
struct download {