javac doesn't work with jar files with >64k entries
Kumar Srinivasan
kumar.x.srinivasan at oracle.COM
Wed Nov 7 13:24:31 PST 2012
On 11/7/2012 10:59 AM, Martin Buchholz wrote:
>
>
> On Wed, Nov 7, 2012 at 10:20 AM, Kumar Srinivasan
> <kumar.x.srinivasan at oracle.com <mailto:kumar.x.srinivasan at oracle.com>>
> wrote:
>
> Hi Martin!,
>
> I believe I fixed this in jdk7 the changesets that you might find
> interesting are:
> http://hg.openjdk.java.net/jdk7/jdk7/langtools/rev/6970d9fb8e02
> http://hg.openjdk.java.net/jdk7/jdk7/langtools/rev/3d45cc94ee0f
>
> We use javac's fast zip implementation first if it fails then we
> use the
> platforms Zip implementation, by using a flag you can control
> which one to use.
>
>
> I tried to reproduce the bug with latest jdk7 (7u10-ea) and jdk8 (b62)
> and it appears to still be there as well.
>
> Fallback may indeed be working for ZIP64 input jars (I haven't tried
> it) but it does *not* work for zip files with >64k entries, because
> javac's zip implementation believes it has correctly read all the
> entries, when in fact it has only read ENDTOT entries.
Talking about tests, take a look at
langtools/test/tools/javac/file/zip/T6836682.java
Scenario A, that does not cut it ?
Kumar
>
> I haven't tried to create a minimal test (we have a non-minimal one),
> but it should be easy to create an input zip with 64k bogus empty file
> entries followed by some real class files at the end.
> Martin
>
> Hope this helps.
>
> Kumar
>
>
>
>> Hi compiler folk,
>>
>> You don't like someone else's zip implementation, cuz it's too
>> SLOOOW, so you write your own. Now you have two problems.
>>
>> ./share/classes/com/sun/tools/javac/file/ZipFileIndex.java:571:
>> int entryCount = get2ByteLittleEndian(zipDir, 0);
>>
>> The ZIP specification includes ENDTOT, a field that contains the
>> number of entries in a zip file.
>> Unfortunately, all high quality zip implementations ignore this
>> field (or more accurately, treat it as a hint).
>> Read zip_util.c and be enlightened:
>>
>> /* Initialize zip file data structures based on the total number
>> * of central directory entries as stored in ENDTOT. Since this
>> * is a 2-byte field, but we (and other zip implementations)
>> * support approx. 2**31 entries, we do not trust ENDTOT, but
>> * treat it only as a strong hint. When we call ourselves
>>
>> This needs fixing. Since you are iterating through the CEN
>> already, just stop when you hit the end header, whose location
>> you know.
>>
>> You can imagine the painful frustrating failure mode of javac
>> starting to very mysteriously fail as the size of an input jar
>> creeps over 64k entries.
>>
>> jdk6 javac has the same problem, but disabling the "optimized"
>> zip implementation requires different mechanisms.
>>
>> The sources could be more readable. Probably your source code is
>> haunted by Phil Katz' ghost because you are using hex constants
>> instead of 'P' and 'K' as Phil Katz intended.
>>
>> !(endbuf[i] == 0x50 &&
>> endbuf[i + 1] == 0x4b &&
>>
>> You get points for noticing that the input zip file is in ZIP64
>> format
>>
>> if (sz < 0 || get2ByteLittleEndian(zipDir, 0)
>> == 0xffff) {
>> throw new ZipFormatException("detected a
>> zip64 archive");
>> }
>>
>> but the only proper reaction is to either add full ZIP64 support
>> or fallback to the "unoptimized but actually working" implementation.
>>
>> Martin
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20121107/59cf73ae/attachment.html
More information about the compiler-dev
mailing list