This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch: out of memory error when reading jar files with zip comments


Hi,

When gcj's CLASSPATH contains a .jar file with a zip-style comment, I
get an error like this:

jc1: out of memory allocating 1663067502 bytes after a total of 135168 bytes

A test case is:

jar -cf test.jar   # create an empty jar file
echo "some comment" | zip -z test.jar  # add a zip comment
gcj -classpath test.jar Foo.java   # fails with above message

The problem is that the code for reading .jar files (which are really
special .zip files) does not handle zip-style comments. I just
submitted PR java/23617 regarding this issue. Attached is my attempt to
fix it by scanning back through the comment from the end, until the
end-central-header section is reached.

Thanks,
Wil

2005-08-29  Wil Mahan  <wmahan@gmail.com>
	PR java/23617
	* zextract.c (read_zip_archive): Fix out of memory error when
	reading jar files with zip-style comments.
Index: zextract.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/java/zextract.c,v
retrieving revision 1.20
diff -u -d -p -r1.20 zextract.c
--- zextract.c	25 Jun 2005 00:33:05 -0000	1.20
+++ zextract.c	29 Aug 2005 05:50:58 -0000
@@ -287,6 +287,21 @@ read_zip_archive (ZipFile *zipf)
     return -1;
   if (read (zipf->fd, buffer, ECREC_SIZE+4) != ECREC_SIZE+4)
     return -2;
+  if (buffer[0] != 'P' || strncmp ((const char *) &buffer[1], END_CENTRAL_SIG, 3)) {
+    /* We could not find the end-central-header signature, probably
+       because a zipfile comment is present. Scan backwards until we
+       find the signature. */
+    if (lseek (zipf->fd, (long)(-ECREC_SIZE), SEEK_END) <= 0)
+      return -2;
+    while (buffer[0] != 'P' || strncmp ((const char *) &buffer[1], END_CENTRAL_SIG, 3)) {
+      if (lseek (zipf->fd, -5, SEEK_CUR) < 0)
+        return -2;
+      if (read (zipf->fd, buffer, 4) != 4)
+        return -2;
+    } 
+    if (read (zipf->fd, buffer + 4, ECREC_SIZE) != ECREC_SIZE)
+      return -2;
+  }
   zipf->count = makeword((const uch *) &buffer[TOTAL_ENTRIES_CENTRAL_DIR]);
   zipf->dir_size = makelong((const uch *) &buffer[SIZE_CENTRAL_DIRECTORY]);
 #define ALLOC xmalloc

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]