You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@harmony.apache.org by Tim Ellison <t....@gmail.com> on 2009/11/30 11:32:32 UTC
Re: [classlib][archive] problems with ZipFile
On 27/Nov/2009 11:30, Oliver Deakin wrote:
> Tim Ellison wrote:
>> <snip>
>> FYI here is my hacked available() impl, which needs some testing before
>> it is good to go in..
>>
>
> With this patch for available() applied the ASN1Exception no longer gets
> thrown in BerInputStream.read(), but instead an ASN1Exception is thrown
> in BerInputStream.readSequence() at line 671. The message from this
> exception is "Mandatory value is missing at [3255]".
>
> Looking in the byte buffer contents, I see that after index 3255 all its
> values are 0, whereas in M11 they are all populated as expected. It
> looks like DTD.read() is assuming that its stream.read(enc) call (around
> line 149) will return a full buffer, but with the new zip changes it
> does not. Applying a patch something like this (along with Tim's ZipFile
> patch below) fixes the test failures and I get a clean run of the full
> swing test suite:
>
> Index: DTD.java
> ===================================================================
> --- DTD.java (revision 884214)
> +++ DTD.java (working copy)
> @@ -142,8 +142,12 @@
>
> public void read(final DataInputStream stream) throws IOException {
> // converts from DataInputStream into a byte array
> - byte[] enc = new byte[stream.available()];
> - stream.read(enc);
> + int available = stream.available();
> + byte[] enc = new byte[available];
> + int readBytes = 0;
> + while (readBytes != available) {
> + readBytes += stream.read(enc, readBytes, available -
> readBytes);
> + }
> // decode the byte array
> Asn1Dtd asn1 = new Asn1Dtd(enc);
While I agree that using available is wrong (just wanted to say that in
every mail!), consider...
JarFile jar = new JarFile("swing.jar");
ZipEntry ze = jar.getEntry(NAME);
InputStream is = jar.getInputStream(ze);
is.available();
System.out.println("Size = " + ze.getSize());
while (is.available() > 0) {
int avail = is.available();
int i = is.read(new byte[avail]);
System.out.printf(
"Bytes requested = %d, got = %d, remaining = %d\n",
avail, i, is.available());
}
jar.close();
On harmony (with patches) it prints:
Size = 51140
Bytes requested = 51140, got = 3256, remaining = 47884
Bytes requested = 47884, got = 5072, remaining = 42812
Bytes requested = 42812, got = 19083, remaining = 23729
Bytes requested = 23729, got = 17749, remaining = 5980
Bytes requested = 5980, got = 5980, remaining = 0
On the RI it prints:
Size = 51140
Bytes requested = 51140, got = 51140, remaining = 0
Regards,
Tim
Re: [classlib][archive] problems with ZipFile
Posted by Tim Ellison <t....@gmail.com>.
On 30/Nov/2009 10:32, Tim Ellison wrote:
> On 27/Nov/2009 11:30, Oliver Deakin wrote:
>> Tim Ellison wrote:
>>> <snip>
>>> FYI here is my hacked available() impl, which needs some testing before
>>> it is good to go in..
>>>
>> With this patch for available() applied the ASN1Exception no longer gets
>> thrown in BerInputStream.read(), but instead an ASN1Exception is thrown
>> in BerInputStream.readSequence() at line 671. The message from this
>> exception is "Mandatory value is missing at [3255]".
>>
>> Looking in the byte buffer contents, I see that after index 3255 all its
>> values are 0, whereas in M11 they are all populated as expected. It
>> looks like DTD.read() is assuming that its stream.read(enc) call (around
>> line 149) will return a full buffer, but with the new zip changes it
>> does not. Applying a patch something like this (along with Tim's ZipFile
>> patch below) fixes the test failures and I get a clean run of the full
>> swing test suite:
>>
>> Index: DTD.java
>> ===================================================================
>> --- DTD.java (revision 884214)
>> +++ DTD.java (working copy)
>> @@ -142,8 +142,12 @@
>>
>> public void read(final DataInputStream stream) throws IOException {
>> // converts from DataInputStream into a byte array
>> - byte[] enc = new byte[stream.available()];
>> - stream.read(enc);
>> + int available = stream.available();
>> + byte[] enc = new byte[available];
>> + int readBytes = 0;
>> + while (readBytes != available) {
>> + readBytes += stream.read(enc, readBytes, available -
>> readBytes);
>> + }
>> // decode the byte array
>> Asn1Dtd asn1 = new Asn1Dtd(enc);
>
>
>
> While I agree that using available is wrong (just wanted to say that in
> every mail!), consider...
>
>
> JarFile jar = new JarFile("swing.jar");
> ZipEntry ze = jar.getEntry(NAME);
> InputStream is = jar.getInputStream(ze);
>
> is.available();
> System.out.println("Size = " + ze.getSize());
>
> while (is.available() > 0) {
> int avail = is.available();
> int i = is.read(new byte[avail]);
> System.out.printf(
> "Bytes requested = %d, got = %d, remaining = %d\n",
> avail, i, is.available());
> }
> jar.close();
>
>
> On harmony (with patches) it prints:
> Size = 51140
> Bytes requested = 51140, got = 3256, remaining = 47884
> Bytes requested = 47884, got = 5072, remaining = 42812
> Bytes requested = 42812, got = 19083, remaining = 23729
> Bytes requested = 23729, got = 17749, remaining = 5980
> Bytes requested = 5980, got = 5980, remaining = 0
>
>
> On the RI it prints:
> Size = 51140
> Bytes requested = 51140, got = 51140, remaining = 0
The Harmony behavior is courtesy of me choosing a random 1024 byte
working buffer in the ZipInflaterInputStream hack. We can get the data
in fewer reads by increasing it. I updated my patch and attached it to
HARMONY-6394.
Regards,
Tim