tags 115625 patch thanks I'v adjusted the patch and now it doesn't clobber existing files. Then the bug may be closed, as the forementioned DoS is not feasible, and the clobbering problem is resolved.
If there are any problems related to the patch, please let me know :) kind regards --- reformime.c Tue Nov 30 03:36:21 1999 +++ reformime_patched.c Tue Jan 8 04:23:21 2002 @@ -14,6 +14,7 @@ #include <sys/stat.h> #include <time.h> #include <stdio.h> +#include <errno.h> #include <string.h> #if HAVE_STRINGS_H #include <strings.h> @@ -303,13 +304,15 @@ } } -static char *get_suitable_filename(struct rfc2045 *r, const char *pfix) +static char *get_suitable_filename(struct rfc2045 *r, const char *pfix, + int ignore_filename) { const char *disposition_s; const char *disposition_name_s; const char *disposition_filename_s; const char *content_name_s; char *p, *q; +char *dyn_disp_name=0; rfc2045_dispositioninfo(r, &disposition_s, &disposition_name_s, &disposition_filename_s); @@ -330,6 +333,29 @@ disposition_filename_s=namebuf; } + if (ignore_filename) + { + char numbuf[NUMBUFSIZE]; + static size_t counter=0; + const char *p=str_size_t(++counter, numbuf); + + dyn_disp_name=malloc(strlen(disposition_filename_s) + + strlen(p)+2); + if (!dyn_disp_name) + { + perror("malloc"); + exit(1); + } + disposition_filename_s=strcat(strcat(strcpy( + dyn_disp_name, p), "-"), + disposition_filename_s); + } + else if (!disposition_filename_s || !*disposition_filename_s) + { + dyn_disp_name=tempname("."); + disposition_filename_s=dyn_disp_name+2; /* Skip over ./ */ + } + p=malloc((pfix ? strlen(pfix):0)+strlen(disposition_filename_s)+1); if (!p) { @@ -340,9 +366,11 @@ if (pfix) strcpy(p, pfix); q=p+strlen(p); for (strcpy(q, disposition_filename_s); *q; q++) - if (!isalnum(*q) && *q != '.') + if (!isalnum(*q) && *q != '.' && *q != '-') *q='_'; + if (dyn_disp_name) free(dyn_disp_name); + if (!pfix) { const char *content_type_s; @@ -405,15 +433,38 @@ static void extract_file(struct rfc2045 *p, const char *filename, int argc, char **argv) { -char *f=get_suitable_filename(p, filename); +char *f; FILE *fp; +int ignore=0; - if (!f) return; - - if ((fp=fopen(f, "w")) == 0) + for (;;) { - perror(f); - exit(1); + int fd; + + f=get_suitable_filename(p, filename, ignore); + if (!f) return; + + fd=open(f, O_WRONLY|O_CREAT|O_EXCL, 0666); + if (fd < 0) + { + if (errno == EEXIST) + { + printf("%s exists.\n", f); + free(f); + ignore=1; + continue; + } + + perror(f); + exit(1); + } + fp=fdopen(fd, "w"); + if (!fp) + { + perror("fdopen"); + exit(1); + } + break; } do_print_section(p, fp); @@ -430,7 +481,7 @@ const char *filename, int argc, char **argv) { -char *f=get_suitable_filename(p, "FILENAME="); +char *f=get_suitable_filename(p, "FILENAME=", 0); int pipefd[2]; pid_t pid, p2; FILE *fp;