$OpenBSD: patch-external_gcc_fastjar_jartool_c,v 1.2 2006/04/20 04:42:38 kurt Exp $
--- external/gcc/fastjar/jartool.c.orig	Tue Jan  3 10:27:01 2006
+++ external/gcc/fastjar/jartool.c	Fri Apr 14 01:07:57 2006
@@ -1591,6 +1591,31 @@ int create_central_header(int fd){
   return 0;
 }
 
+static void canonical_filename(char *filename)
+{
+    char *iterator, *iterator2;
+
+    for (;;) {
+	if (*filename == '/')
+	    memmove(filename, filename + 1, strlen(filename));
+	else if (filename[0] == '.' && filename[1] == '/')
+	    memmove(filename, filename + 2, strlen(filename) - 1);
+	else if (filename[0] == '.' && filename[1] == '.' && filename[2] == '/')
+	    memmove(filename, filename + 3, strlen(filename) - 2);
+	else if ((iterator = strstr(filename, "//")) != NULL)
+	    memmove(iterator, iterator + 1, strlen(iterator));
+	else if ((iterator = strstr(filename, "/./")) != NULL)
+	    memmove(iterator, iterator + 2, strlen(iterator) - 1);
+	else if ((iterator = strstr(filename, "/../")) != NULL) {
+	    for (iterator2 = iterator - 1; iterator2 > filename && *iterator2 != '/'; --iterator2)
+		continue;
+	    /* iterator2 >= filename, handle the initial slash above, if necessary */
+	    memmove(iterator2, iterator + 3, strlen(iterator) - 2);
+	} else
+	    break;
+    }
+}
+
 int extract_jar(int fd, char **files, int file_num){
   int rdamt;
   int out_a, in_a;
@@ -1699,6 +1724,13 @@ int extract_jar(int fd, char **files, in
     pb_read(&pbf, filename, fnlen);
     filename[fnlen] = '\0';
 
+    canonical_filename((char *)filename);
+
+    if (*filename == '\0') {
+       fprintf(stderr, "Error extracting JAR archive, empty file name!\n");
+       exit(1);
+     }
+
 #ifdef DEBUG    
     printf("filename is %s\n", filename);
 #endif
@@ -1706,11 +1738,13 @@ int extract_jar(int fd, char **files, in
     if(file_num > 0){
       handle = FALSE;
       
-      for(j = 0; j < file_num; j++)
-        if(strcmp(files[j], (const char *)filename) == 0){
+      for(j = 0; j < file_num; j++) {
+        size_t len = strlen(files[j]);
+        if(strncmp(files[j], (const char *)filename, len) == 0){
           handle = TRUE;
           break;
         }
+      }
     }
 
     if(!handle)
@@ -2007,17 +2041,25 @@ int list_jar(int fd, char **files, int f
       }
       filename[fnlen] = '\0';
     
+      canonical_filename((char *)filename);
+      if (*filename == '\0') {
+          fprintf(stderr, "Error extracting JAR archive, empty file name!\n");
+          exit(1);
+      }
+
       /* if the user specified a list of files on the command line,
          we'll only display those, otherwise we'll display everything */
       if(file_num > 0){
-        for(j = 0; j < file_num; j++)
-          if(strcmp(files[j], (const char *)filename) == 0){
+        for(j = 0; j < file_num; j++) {
+          size_t len = strlen(files[j]);
+          if(strncmp(files[j], (const char *)filename, len) == 0){
             if(verbose)
               printf("%6d %s %s\n", usize, ascii_date, filename);
             else
               printf("%s\n", filename);
             break;
           }
+        }
       } else {
         if(verbose)
           printf("%6d %s %s\n", usize, ascii_date, filename);
