delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2003/05/03/08:48:42

Date: Sat, 03 May 2003 13:21:57 +0100
From: "Richard Dawe" <rich AT phekda DOT freeserve DOT co DOT uk>
Sender: rich AT phekda DOT freeserve DOT co DOT uk
To: djgpp-workers AT delorie DOT com
X-Mailer: Emacs 21.3.50 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6
Subject: djtar and slightly weirdly formatted ZIPs, revision 2 [PATCH]
Message-Id: <E19Bvwx-0000zi-00@phekda.freeserve.co.uk>
Reply-To: djgpp-workers AT delorie DOT com

Hello.

Below is revision 2 of my patch for djtar, to make it cope with
v2gnu/flx254b.zip on Simtel.NET. This archive has a spanning marker
that indicates the archive has been split into one, i.e.: not at all.

Changes from the previous patch:

* Parse strictly. It fails if the archive doesn't start with
  the one-span spanning marker or a local header.

* Generate an error, if multiple-span spanning is found.

* Generate an error, when we don't understand the header type.
  This seems better than reporting that the ZIP file is invalid.

OK to commit?

Thanks, bye, Rich =]

Index: src/utils/djtar/epunzip.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/utils/djtar/epunzip.c,v
retrieving revision 1.4
diff -p -c -3 -r1.4 epunzip.c
*** src/utils/djtar/epunzip.c	17 Oct 2002 23:00:26 -0000	1.4
--- src/utils/djtar/epunzip.c	3 May 2003 12:14:11 -0000
*************** int epcopy(char *, long);
*** 37,42 ****
--- 37,45 ----
  void
  epunzip_read(char *zipfilename)
  {
+   int dont_understand = 0;
+   int at_local_header = 0;
+ 
    clear_bufs();
    errno = 0;
    ifd = oread_open(zipfilename);
*************** epunzip_read(char *zipfilename)
*** 46,74 ****
        return;
      }
  
    while(1)
      {
!       int buffer, ext_header, timedate, crc, size, length, name_length,
! 	extra_length, should_be_written, count, real_file = 0;
!       char filename[2048];
  
        ((char *)&buffer)[0] = (char)get_byte();
        ((char *)&buffer)[1] = (char)get_byte();
  
        if(*(short *)&buffer != *(short *)"PK")
! 	{
! 	  fprintf(log_out, "%s: invalid zip file structure\n", zipfilename);
! 	  break;
! 	}
  
        ((char *)&buffer)[0] = (char)get_byte();
        ((char *)&buffer)[1] = (char)get_byte();
  
!       if(*(short *)&buffer != *(short *)"\3\4")
  	{
! 	  /* not a local header - all done */
  	  break;
  	}
  
        /* version info - ignore it */
        get_byte();
--- 49,132 ----
        return;
      }
  
+   /* Find the first local header. Skip over spanning markers
+    * for a one-segment ZIP, but fail on other headers. */
    while(1)
      {
!       int buffer = 0;
  
        ((char *)&buffer)[0] = (char)get_byte();
        ((char *)&buffer)[1] = (char)get_byte();
  
        if(*(short *)&buffer != *(short *)"PK")
! 	break;
  
        ((char *)&buffer)[0] = (char)get_byte();
        ((char *)&buffer)[1] = (char)get_byte();
  
!       if(*(short *)&buffer == *(short *)"\x3\x4")
! 	{
! 	  /* local header */
! 	  at_local_header = 1;
! 	  break;
! 	}
!       else if(*(short *)&buffer == *(short *)"\x30\x30")
  	{
! 	  /* spanning marker, but only one segment
! 	   * => need to find local header. */
! 	  continue;
! 	}
!       else if(*(short *)&buffer == *(short *)"\x7\x8")
! 	{
! 	  /* spanning marker, multiple segments. */
! 	  fprintf(log_out, "%s: spanning is not supported\n", zipfilename);
! 	  dont_understand = 1;
! 	  break;
! 	}
!       else
! 	{
! 	  /* unknown header */
! 	  fprintf(log_out,
! 		  "%s: don't understand header type 0x%x%x\n",
! 		  zipfilename, ((char *)&buffer)[0], ((char *)&buffer)[1]);
! 	  dont_understand = 1;
  	  break;
  	}
+     }
+ 
+   if (!at_local_header && !dont_understand)
+     fprintf(log_out, "%s: invalid zip file structure\n", zipfilename);
+ 
+   if (at_local_header) while(1)
+     {
+       int buffer, ext_header, timedate, crc, size, length, name_length,
+ 	extra_length, should_be_written, count, real_file = 0;
+       char filename[2048];
+ 
+       if (!at_local_header)
+ 	{
+ 	  ((char *)&buffer)[0] = (char)get_byte();
+ 	  ((char *)&buffer)[1] = (char)get_byte();
+ 
+ 	  if(*(short *)&buffer != *(short *)"PK")
+ 	    {
+ 	      fprintf(log_out, "%s: invalid zip file structure\n", zipfilename);
+ 	      break;
+ 	    }
+ 
+ 	  ((char *)&buffer)[0] = (char)get_byte();
+ 	  ((char *)&buffer)[1] = (char)get_byte();
+ 
+ 	  if(*(short *)&buffer != *(short *)"\x3\x4")
+ 	    {
+ 	      /* not a local header - all done */
+ 	      break;
+ 	    }
+ 	}
+       else
+ 	{
+ 	  at_local_header = 0;
+ 	}
  
        /* version info - ignore it */
        get_byte();
*************** epunzip_read(char *zipfilename)
*** 222,228 ****
  	      ((char *)&buffer)[1] = (char)get_byte();
  	      ((char *)&buffer)[2] = (char)get_byte();
  	      ((char *)&buffer)[3] = (char)get_byte();
! 	      if(buffer != *(int *)"PK\7\x8")
  		{
  		  fprintf(log_out, "%s: invalid zip file structure\n",
  			  zipfilename);
--- 280,286 ----
  	      ((char *)&buffer)[1] = (char)get_byte();
  	      ((char *)&buffer)[2] = (char)get_byte();
  	      ((char *)&buffer)[3] = (char)get_byte();
! 	      if(buffer != *(int *)"PK\x7\x8")
  		{
  		  fprintf(log_out, "%s: invalid zip file structure\n",
  			  zipfilename);

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019