ZipInputStream bug
I was going to make a farm of data files that mostly contain
bytes, but I wanted to make it possible to store 32-bit ints
just in case. So I tried to use zip-encoding to make the
sizes smaller in the usual case. Unfortunately, *some* of the
data files don't read back correctly.
Here is an example of a 4096-byte file that writes correctly
with ZipOutputStream, but does not read back correctly with
ZipInputStream. If I manually extract the zipped file, the
data is correct.
Is anyone maintaining the Zip utilities?
Dan Hoey
haoyuep at aol.com
============================> cut here <=======================
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import java.util.zip.ZipEntry;
class ZipFail
{
static int[] testData =
{17,33,16,17,33,16,17,33,23,22,33,23,22,33,16,22,38,3,37,
38,16,37,38,23,34,51,16,32,2,5,32,17,23,32,17,23,34,17,16,
39,17,23,32,17,23,32,17,23,32,17,23,32,20,23,32,17,33,32,
17,33,32,17,33,31,17,33,31,17,33,16,22,33,16,32,33,16,32,
33,16,32,33,16,32,46,16,32,46,16,32,17,16,32,17,16,32,22,
23,32,27,23,32,27,33,32,20,16,32,20,33,32,20,33,32,5,33,
32,3,33,32,17,33,16,17,33,4,60,33,4,51,33,4,32,33,2,32,33,
4,32,17,2,32,17,16,32,17,16,32,17,2,32,17,16,37,17,16,34,
5,16,34,5,16,23,5,16,23,17,35,32,17,33,32,17,33,23,17,33,
23,17,33,23,3,33,23,17,33,23,17,33,16,17,33,16,17,33,16,
17,33,23,9,33,16,39,22,16,34,22,16,32,22,16,32,17,16,32,
17,23,37,17,31,37,17,8,32,19,23,39,19,31,16,17,10,16,17,
31,16,17,33,23,17,33,5,9,8,5,9,35,18,9,36,18,17,33,5,17,
36,16,30,38,18,34,22,16,34,22,3,32,22,3,32,22,3,37,22,16,
34,22,16,9,17,16,34,2,38,34,17,38,39,17,38,42,2,8,23,17,
33,16,17,35,16,17,36,16,39,33,3,39,33,3,37,33,3,37,33,16,
37,38,16,34,8,16,34,17,16,34,17,16,34,17,16,34,17,8,32,17,
16,32,17,23,32,17,23,39,17,43,32,17,36,16,17,23,16,17,38,
16,17,51,16,17,38,29,17,38,16,22,33,21,22,52,16,17,2,16,
22,33,16,22,51,16,14,52,16,32,17,23,32,17,23,32,17,23,12,
17,16,32,2,23,14,17,16,32,17,16,32,5,33,32,17,33,32,17,33,
32,17,33,16,17,33,16,17,15,16,17,33,16,17,33,16,32,13,16,
32,13,16,32,33,9,32,17,9,14,17,16,32,17,16,14,17,16,14,17,
23,14,17,53,32,5,38,32,17,33,16,17,33,16,17,33,32,17,33,
14,17,33,16,17,33,23,17,33,16,17,33,16,32,33,16,17,33,16,
3,33,21,32,15,16,32,33,9,32,22,16,42,22,31,42,22,16,34,17,
16,37,22,2,32,22,31,32,22,2,39,22,16,39,17,8,23,17,8,23,
17,8,14,17,8,16,17,38,23,17,8,14,32,38,14,17,10,16,17,36,
16,52,33,16,45,38,16,32,22,16,34,17,16,45,17,16,39,17,16,
11,17,16,32,15,8,9,22,8,34,17,8,37,2,8,23,17,8,23,17,8,23,
17,38,16,22,8,23,27,33,23,17,33,23,30,36,18,30,22,3,34,22,
16,47,17,16,47,8,16,9,8,16,39,17,16,34,17,16,39,17,16,32,
17,53,39,17,33,32,17,33,32,17,43,32,17,36,32,17,38,39,17,
38,16,17,38,16,17,51,16,17,51,16,17,43,23,51,43,23,32,35,
16,22,13,16,14,17,16,32,17,16,32,17,16,32,17,16,32,22,16,
32,17,58,32,17,16,32,22,23,32,17,33,9,20,33,32,22,33,16,
22,33,16,22,33,16,17,15,3,17,15,16,22,15,16,52,15,23,32,
33,21,22,17,23,14,17,16,32,17,16,32,33,16,14,33,16,14,52,
16,14,57,16,14,17,16,14,2,16,32,17,33,14,17,15,32,5,15,14,
17,33,32,17,33,23,17,33,23,22,33,23,22,33,23,22,33,16,22,
33,16,32,33,16,14,33,16,32,15,16,32,33,16,14,22,16,14,22,
23,11,22,23,32,22,23,32,22,23,32,17,16,32,17,33,39,17,15,
37,17,15,23,17,33,16,17,35,23,17,38,23,17,33,16,17,33,16,
17,33,16,17,2,16,17,22,16,17,2,16,17,22,16,32,22,16,32,22,
16,11,22,16,9,15,16,9,17,8,9,17,31,11,17,44,3,17,16,39,17,
10,32,17,8,3,59,8,23,17,8,23,17,33,16,17,10,23,17,33,16,
17,38,16,9,38,23,9,13,23,32,38,16,32,22,16,39,15,8,32,17,
8,9,22,16,9,15,16,32,17,8,32,17,8,39,22,8,39,17,8,23,22,
8,23,27,8,16,17,64,16,17,33,16,17,51,23,17,33,14,9,8,16,
9,38,23,9,41,16,9,22,16,32,17,16,9,17,16,9,17,16,32,15,53,
14,15,53,39,22,53,14,17,46,42,17,23,14,17,46,14,17,44,12,
17,15,12,17,15,14,17,15,14,17,15,4,17,13,4,22,15,16,22,33,
23,22,33};
ZipFail()
{
}
static void test(byte[] buf)
{
for(int i=0;i<testData.length;++i)
{
for(int j=0;j<32;j+=8)
{
byte expected=(byte)((testData[i]>>j)&0xff);
if(buf[i*4 + j/8] != expected)
{
throw new RuntimeException
("buf["+i+"*4+"+j+"/8]="+buf[i*4 + j/8]
+" not "+expected);
}
}
}
}
static void usage()
{
System.out.println("Usage: java ZipFail write|readzip|read");
System.out.println(" 'write' creates test.zip with single");
System.out.println(" entry test.dat");
System.out.println(" 'readzip' reads the zip file and");
System.out.println(" compares data with what was");
System.out.println(" written.");
System.out.println(" 'read' reads extracted test.dat file");
System.out.println(" and compares data.");
System.out.println("Bug is demonstrated by success of");
System.out.println("'read' and failure of 'readzip'.");
}
public static void main(String[] args)
{
if(args.length != 1)
{
usage();
return;
}
if(args[0].equalsIgnoreCase("write"))
{
try
{
ZipOutputStream zo = new ZipOutputStream
(new FileOutputStream("test.zip"));
zo.setLevel(9);
zo.putNextEntry(new ZipEntry("test.dat"));
byte[] buf=new byte[4*testData.length];
for(int i=0;i<testData.length;++i)
{
for(int j=0;j<32;j+=8)
{
buf[i*4 + j/8]
= (byte)((testData[i]>>j)&0xff);
}
}
zo.write(buf,0,4*testData.length);
zo.close();
}
catch (Exception ex)
{
throw new RuntimeException (ex);
}
return;
}
if(args[0].equalsIgnoreCase("readzip"))
{
try
{
ZipInputStream zi = new ZipInputStream
(new FileInputStream("test.zip"));
zi.getNextEntry();
byte[]buf = new byte[4*testData.length];
zi.read(buf,0,4*testData.length);
zi.close();
test(buf);
}
catch (Exception ex)
{
throw new RuntimeException (ex);
}
}
if(args[0].equalsIgnoreCase("read"))
{
try
{
FileInputStream fi =
new FileInputStream("test.dat");
byte[]buf = new byte[4*testData.length];
fi.read(buf,0,4*testData.length);
fi.close();
test(buf);
}
catch (Exception ex)
{
throw new RuntimeException (ex);
}
return;
}
usage();
}
}
============================> cut here <=======================