Is this a ZipInputStream Bug?  
Author Message
License Manager





PostPosted: 2004-8-10 7:58:00 Top

java-programmer, Is this a ZipInputStream Bug?
I just got thru tracking down what was happening, but I still don't know
WHY.
Im using ZipInput & Output Stream classes to make a compressed file
(actually it's an image). I create it via ZipOutputStream using a 1K
buffer for writing i.e.:

...
try { // Create the ZIP file
zos = new ZipOutputStream(new FileOutputStream(zipfname)); }
catch (IOException e) {
System.out.println("ZipOutputStream error on open.");
return null; }

try { zos.putNextEntry(new ZipEntry(imgfname)); }
catch (IOException e) {
System.out.println("ZipOutputStream error on put-entry.");
return null; }

...
try { zos.write(bbuf, 0, bix); }
catch(IOException e) {
System.out.println("ZipOutputStream error on write.");
error = true;
break;
}
...

Here bbuf is 1K.

All is ok - WinZip can extract it and the image is fine. Then I try to
read it back via ZipInputStream - i.e.:

...
try { zis = new ZipInputStream(new FileInputStream(filespec)); }
catch (IOException e) {
System.out.println("ZipInputStream error on open.");
return pixels; }

try { zent = zis.getNextEntry(); }
catch (IOException e) {
System.out.println("ZipInputStream error on get-entry.");
return pixels; }

...
while ( cnt > 0 ) {
try { rcnt = zis.read(bbuf, rcnt, cnt); }
catch(IOException ex) {
System.out.println("ex: " +ex.getMessage());
error = true; }
cnt -= rcnt;
}
...

Here is where the problem occurs. If bbuf is 128 or 256 bytes the image
returns just like it should. But if I increase it to 1K junk starts to
show up within the picture at 4K the picture is barely viewable because
of the junk and at 32K I get ArrayOutOfBounds exception during the read
(NOT related to my code). I've verified that the "junk" is data that did
not come out of the zip, the way it went in.

I'm running JDK 1.3.1 on an NT4.0 platform.

Have others seen this behavior ?
Any ideas on why ?

TIA
Don Sykes

 
Lee Fesperman





PostPosted: 2004-8-10 9:32:00 Top

java-programmer >> Is this a ZipInputStream Bug? License Manager wrote:
>
> I just got thru tracking down what was happening, but I still don't know
> WHY.
> Im using ZipInput & Output Stream classes to make a compressed file
> (actually it's an image). I create it via ZipOutputStream using a 1K
> buffer for writing i.e.:
>
> ...
>
> All is ok - WinZip can extract it and the image is fine. Then I try to
> read it back via ZipInputStream - i.e.:
>
> ...
> try { zis = new ZipInputStream(new FileInputStream(filespec)); }
> catch (IOException e) {
> System.out.println("ZipInputStream error on open.");
> return pixels; }
>
> try { zent = zis.getNextEntry(); }
> catch (IOException e) {
> System.out.println("ZipInputStream error on get-entry.");
> return pixels; }
>
> ...
> while ( cnt > 0 ) {
> try { rcnt = zis.read(bbuf, rcnt, cnt); }
> catch(IOException ex) {
> System.out.println("ex: " +ex.getMessage());
> error = true; }
> cnt -= rcnt;
> }
> ...
>
> Here is where the problem occurs. If bbuf is 128 or 256 bytes the image
> returns just like it should. But if I increase it to 1K junk starts to
> show up within the picture at 4K the picture is barely viewable because
> of the junk and at 32K I get ArrayOutOfBounds exception during the read
> (NOT related to my code). I've verified that the "junk" is data that did
> not come out of the zip, the way it went in.
>
> I'm running JDK 1.3.1 on an NT4.0 platform.
>
> Have others seen this behavior ?
> Any ideas on why ?

It's a bug in your code. You'll need another variable to track the offset into 'bbuf'.
In your code above, 'rcnt' used in zis.read() only contains the count of the last set of
bytes read in. With 3 reads, you'll get this kind of result:

1) read into bbuf at offset=0 for 500 bytes (rcnt set to 500),
2) read into bbuf at offset=500 (from rcnt) for 600 (rcnt set to 600),
3) read into bbuf at offset=600 (from rcnt) for 700 ....

Oops! The offset for the third read should be 1100.

--
Lee Fesperman, FFE Software, Inc. (http://www.firstsql.com)
==============================================================
* The Ultimate DBMS is here!
* FirstSQL/J Object/Relational DBMS (http://www.firstsql.com)
 
License Manager





PostPosted: 2004-8-10 11:30:00 Top

java-programmer >> Is this a ZipInputStream Bug?

Lee Fesperman wrote:
> License Manager wrote:
>
>>I just got thru tracking down what was happening, but I still don't know
>>WHY.
>>Im using ZipInput & Output Stream classes to make a compressed file
>>(actually it's an image). I create it via ZipOutputStream using a 1K
>>buffer for writing i.e.:
>>
>> ...
>>
>>All is ok - WinZip can extract it and the image is fine. Then I try to
>>read it back via ZipInputStream - i.e.:
>>
>> ...
>> try { zis = new ZipInputStream(new FileInputStream(filespec)); }
>> catch (IOException e) {
>> System.out.println("ZipInputStream error on open.");
>> return pixels; }
>>
>> try { zent = zis.getNextEntry(); }
>> catch (IOException e) {
>> System.out.println("ZipInputStream error on get-entry.");
>> return pixels; }
>>
>> ...
>> while ( cnt > 0 ) {
>> try { rcnt = zis.read(bbuf, rcnt, cnt); }
>> catch(IOException ex) {
>> System.out.println("ex: " +ex.getMessage());
>> error = true; }
>> cnt -= rcnt;
>> }
>> ...
>>
>>Here is where the problem occurs. If bbuf is 128 or 256 bytes the image
>>returns just like it should. But if I increase it to 1K junk starts to
>>show up within the picture at 4K the picture is barely viewable because
>>of the junk and at 32K I get ArrayOutOfBounds exception during the read
>>(NOT related to my code). I've verified that the "junk" is data that did
>>not come out of the zip, the way it went in.
>>
>>I'm running JDK 1.3.1 on an NT4.0 platform.
>>
>>Have others seen this behavior ?
>>Any ideas on why ?
>
>
> It's a bug in your code. You'll need another variable to track the offset into 'bbuf'.
> In your code above, 'rcnt' used in zis.read() only contains the count of the last set of
> bytes read in. With 3 reads, you'll get this kind of result:
>
> 1) read into bbuf at offset=0 for 500 bytes (rcnt set to 500),
> 2) read into bbuf at offset=500 (from rcnt) for 600 (rcnt set to 600),
> 3) read into bbuf at offset=600 (from rcnt) for 700 ....
>
> Oops! The offset for the third read should be 1100.

OCH! How did I miss that!?!?
Thanks Lee

>