fix for ZIP/JAR file loading bug

Archie Cobbs kaffe@rufus.w3.org
Thu, 16 Jul 1998 12:31:49 -0700 (PDT)


The patch below fixes a bug where kaffe was incorrectly locating
file data inside JAR/ZIP files. The bug was that it was adding
the extra field length from the central directory entry, instead
of the extra field length local directory entry, to compute the
file data offset.

-Archie

___________________________________________________________________________
Archie Cobbs   *   Whistle Communications, Inc.  *   http://www.whistle.com

Index: kaffe/kaffevm/jar.c
===================================================================
RCS file: /cvs/mod/net/kaffe/kaffe/kaffevm/jar.c,v
retrieving revision 1.1.1.1.4.1
diff -c -r1.1.1.1.4.1 jar.c
*** jar.c	1998/07/16 00:24:43	1.1.1.1.4.1
--- jar.c	1998/07/16 19:31:00
***************
*** 35,41 ****
  	INITREADS();
  	jarCentralDirectoryRecord head;
  	jarEntry* ret;
! 	int len;
  
  	head.signature = READ32(file->fp);
  	head.versionMade = READ16(file->fp);
--- 35,42 ----
  	INITREADS();
  	jarCentralDirectoryRecord head;
  	jarEntry* ret;
! 	int len, extra;
! 	off_t pos;
  
  	head.signature = READ32(file->fp);
  	head.versionMade = READ16(file->fp);
***************
*** 76,87 ****
  DBG(JARFILES,	
  	dprintf("Central record filename: %s\n", ret->fileName);	)
  
! 	ret->dataPos = head.relativeLocalHeaderOffset + SIZEOFLOCALHEADER + head.fileNameLength + head.extraFieldLength;
! 	/* HACK HACK HACK */
! 	if (head.extraFieldLength != 0) {
! 		ret->dataPos += 4;
! 	}
  
  	return (ret);
  }
  
--- 77,91 ----
  DBG(JARFILES,	
  	dprintf("Central record filename: %s\n", ret->fileName);	)
  
! 	/* Compute file data location using local header info */
! 	pos = lseek(file->fp, (off_t)0, SEEK_CUR);
! 	(void)lseek(file->fp, (off_t)(head.relativeLocalHeaderOffset + 28), SEEK_SET);
! 	extra = READ16(file->fp);
! 	ret->dataPos = head.relativeLocalHeaderOffset
! 		+ SIZEOFLOCALHEADER + head.fileNameLength + extra;
  
+ 	/* Jump back to original central directory position */
+ 	(void)lseek(file->fp, pos, SEEK_SET);
  	return (ret);
  }