$NetBSD: patch-ap,v 1.1 2005/06/14 18:10:37 jlam Exp $

--- lib/WrFFrI.c.orig	1998-03-19 14:51:00.000000000 -0500
+++ lib/WrFFrI.c
@@ -37,6 +37,8 @@
  * Lorens Younes (d93-hyo@nada.kth.se) 4/96
  */
 
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
 #include "XpmI.h"
 #if !defined(NO_ZPIPE) && defined(WIN32)
 # define popen _popen
@@ -97,7 +99,7 @@ XpmWriteFileFromXpmImage(filename, image
     XpmInfo *info;
 {
     xpmData mdata;
-    char *name, *dot, *s, new_name[BUFSIZ];
+    char *name, *dot, *s, new_name[BUFSIZ] = {0};
     int ErrorStatus;
 
     /* open file to write */
@@ -119,8 +121,9 @@ XpmWriteFileFromXpmImage(filename, image
 	    name++;
 #endif
 	/* let's try to make a valid C syntax name */
-	if (dot = index(name, '.')) {
-	    strcpy(new_name, name);
+	if (index(name, '.')) {
+	    strncpy(new_name, name, sizeof(new_name));
+	    new_name[sizeof(new_name)-1] = 0;
 	    /* change '.' to '_' */
 	    name = s = new_name;
 	    while (dot = index(s, '.')) {
@@ -130,7 +133,8 @@ XpmWriteFileFromXpmImage(filename, image
 	}
 	if (dot = index(name, '-')) {
 	    if (name != new_name) {
-		strcpy(new_name, name);
+		strncpy(new_name, name, sizeof(new_name));
+		new_name[sizeof(new_name)-1] = 0;
 		name = new_name;
 	    }
 	    /* change '-' to '_' */
@@ -247,6 +251,8 @@ WritePixels(file, width, height, cpp, pi
     unsigned int x, y, h;
 
     h = height - 1;
+    if (cpp != 0 && width >= (UINT_MAX - 3)/cpp)
+	return XpmNoMemory;    
     p = buf = (char *) XpmMalloc(width * cpp + 3);
     if (!buf)
 	return (XpmNoMemory);
@@ -297,6 +303,11 @@ WriteExtensions(file, ext, num)
 /*
  * open the given file to be written as an xpmData which is returned
  */
+#ifndef NO_ZPIPE
+	FILE *s_popen(char *cmd, const char *type);
+#else
+#	define s_popen popen
+#endif
 static int
 OpenWriteFile(filename, mdata)
     char *filename;
@@ -312,16 +323,23 @@ OpenWriteFile(filename, mdata)
 	mdata->type = XPMFILE;
     } else {
 #ifndef NO_ZPIPE
-	int len = strlen(filename);
+	size_t len = strlen(filename);
+
+	if(len == 0                        ||
+	   filename[0] == '/'              ||
+	   strstr(filename, "../") != NULL ||
+	   filename[len-1] == '/')
+		return(XpmOpenFailed);
+
 	if (len > 2 && !strcmp(".Z", filename + (len - 2))) {
-	    sprintf(buf, "compress > \"%s\"", filename);
-	    if (!(mdata->stream.file = popen(buf, "w")))
+	    snprintf(buf, sizeof(buf), "compress > \"%s\"", filename);
+	    if (!(mdata->stream.file = s_popen(buf, "w")))
 		return (XpmOpenFailed);
 
 	    mdata->type = XPMPIPE;
 	} else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
-	    sprintf(buf, "gzip -q > \"%s\"", filename);
-	    if (!(mdata->stream.file = popen(buf, "w")))
+	    snprintf(buf, sizeof(buf), "gzip -q > \"%s\"", filename);
+	    if (!(mdata->stream.file = s_popen(buf, "w")))
 		return (XpmOpenFailed);
 
 	    mdata->type = XPMPIPE;
@@ -352,7 +370,7 @@ xpmDataClose(mdata)
 	break;
 #ifndef NO_ZPIPE
     case XPMPIPE:
-	pclose(mdata->stream.file);
+	fclose(mdata->stream.file);
 	break;
 #endif
     }
