[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: help needed with a reformime bug



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;



Reply to: