1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17package org.apache.harmony.tests.java.util.zip;
18
19import java.io.ByteArrayInputStream;
20import java.io.ByteArrayOutputStream;
21import java.io.File;
22import java.io.FileInputStream;
23import java.io.IOException;
24import java.io.InputStream;
25import java.util.zip.DeflaterOutputStream;
26import java.util.zip.Inflater;
27import java.util.zip.InflaterInputStream;
28import libcore.junit.junit3.TestCaseWithRules;
29import libcore.junit.util.ResourceLeakageDetector;
30import org.junit.Rule;
31import org.junit.rules.TestRule;
32import tests.support.resource.Support_Resources;
33
34public class InflaterInputStreamTest extends TestCaseWithRules {
35    @Rule
36    public TestRule guardRule = ResourceLeakageDetector.getRule();
37
38    // files hyts_construO,hyts_construOD,hyts_construODI needs to be
39    // included as resources
40    byte outPutBuf[] = new byte[500];
41
42    class MyInflaterInputStream extends InflaterInputStream {
43        MyInflaterInputStream(InputStream in) {
44            super(in);
45        }
46
47        MyInflaterInputStream(InputStream in, Inflater infl) {
48            super(in, infl);
49        }
50
51        MyInflaterInputStream(InputStream in, Inflater infl, int size) {
52            super(in, infl, size);
53        }
54
55        void myFill() throws IOException {
56            fill();
57        }
58    }
59
60    /**
61     * java.util.zip.InflaterInputStream#InflaterInputStream(java.io.InputStream)
62     */
63    public void test_ConstructorLjava_io_InputStream() throws IOException {
64        //FIXME This test doesn't pass in Harmony classlib or Sun 5.0_7 RI
65        /*
66		int result = 0;
67		int buffer[] = new int[500];
68		InputStream infile = Support_Resources
69				.getStream("hyts_construO.bin");
70
71		InflaterInputStream inflatIP = new InflaterInputStream(infile);
72
73		int i = 0;
74		while ((result = inflatIP.read()) != -1) {
75			buffer[i] = result;
76			i++;
77		}
78		inflatIP.close();
79        */
80    }
81
82    /**
83     * java.util.zip.InflaterInputStream#InflaterInputStream(java.io.InputStream,
84     *java.util.zip.Inflater)
85     */
86    public void test_ConstructorLjava_io_InputStreamLjava_util_zip_Inflater() throws IOException {
87        byte byteArray[] = new byte[100];
88        InputStream infile = Support_Resources.getStream("hyts_construOD.bin");
89        Inflater inflate = new Inflater();
90        InflaterInputStream inflatIP = new InflaterInputStream(infile,
91                inflate);
92
93        inflatIP.read(byteArray, 0, 5);// only suppose to read in 5 bytes
94        inflatIP.close();
95    }
96
97    /**
98     * java.util.zip.InflaterInputStream#InflaterInputStream(java.io.InputStream,
99     *java.util.zip.Inflater, int)
100     */
101    public void test_ConstructorLjava_io_InputStreamLjava_util_zip_InflaterI() throws IOException {
102        int result = 0;
103        int buffer[] = new int[500];
104        InputStream infile = Support_Resources.getStream("hyts_construODI.bin");
105        Inflater inflate = new Inflater();
106        InflaterInputStream inflatIP = new InflaterInputStream(infile,
107                inflate, 1);
108
109        int i = 0;
110        while ((result = inflatIP.read()) != -1) {
111            buffer[i] = result;
112            i++;
113        }
114        inflatIP.close();
115    }
116
117    /**
118     * java.util.zip.InflaterInputStream#InflaterInputStream(java.io.InputStream,
119     *java.util.zip.Inflater, int)
120     */
121    public void test_ConstructorLjava_io_InputStreamLjava_util_zip_InflaterI_1() throws IOException {
122        try (InputStream infile = Support_Resources.getStream("hyts_construODI.bin")) {
123            Inflater inflate = new Inflater();
124            try {
125                new InflaterInputStream(infile, null, 1);
126                fail("NullPointerException expected");
127            } catch (NullPointerException NPE) {
128                //expected
129            }
130
131            try {
132                new InflaterInputStream(null, inflate, 1);
133                fail("NullPointerException expected");
134            } catch (NullPointerException NPE) {
135                //expected
136            }
137
138            try {
139                new InflaterInputStream(infile, inflate, -1);
140                fail("IllegalArgumentException expected");
141            } catch (IllegalArgumentException iae) {
142                //expected
143            }
144            inflate.end();
145        }
146    }
147
148    /**
149     * java.util.zip.InflaterInputStream#mark(int)
150     */
151    public void test_markI() throws IOException {
152        InputStream is = new ByteArrayInputStream(new byte[10]);
153        try (InflaterInputStream iis = new InflaterInputStream(is)) {
154            // mark do nothing, do no check
155            iis.mark(0);
156            iis.mark(-1);
157            iis.mark(10000000);
158        }
159    }
160
161    /**
162     * java.util.zip.InflaterInputStream#markSupported()
163     */
164    public void test_markSupported() throws IOException {
165        InputStream is = new ByteArrayInputStream(new byte[10]);
166        try (InflaterInputStream iis = new InflaterInputStream(is)) {
167            assertFalse(iis.markSupported());
168            assertTrue(is.markSupported());
169        }
170    }
171
172    /**
173     * java.util.zip.InflaterInputStream#read()
174     */
175    public void test_read() throws IOException {
176        int result = 0;
177        int buffer[] = new int[500];
178        byte orgBuffer[] = { 1, 3, 4, 7, 8 };
179        InputStream infile = Support_Resources
180                .getStream("hyts_construOD.bin");
181        Inflater inflate = new Inflater();
182        InflaterInputStream inflatIP = new InflaterInputStream(infile,
183                inflate);
184
185        int i = 0;
186        while ((result = inflatIP.read()) != -1) {
187            buffer[i] = result;
188            i++;
189        }
190        inflatIP.close();
191
192        for (int j = 0; j < orgBuffer.length; j++) {
193            assertEquals(
194                    "original compressed data did not equal decompressed data",
195                    orgBuffer[j], buffer[j]);
196        }
197    }
198
199    /**
200     * java.util.zip.InflaterInputStream#read(byte [], int, int)
201     */
202    public void test_read_LBII() throws IOException {
203        int result = 0;
204        InputStream infile = Support_Resources.getStream("hyts_construOD.bin");
205        Inflater inflate = new Inflater();
206        InflaterInputStream inflatIP = new InflaterInputStream(infile, inflate);
207
208        byte[] b = new byte[3];
209        try {
210            result = inflatIP.read(null, 0, 1);
211            fail("NullPointerException expected");
212        } catch (NullPointerException npe) {
213            //expected
214        }
215
216        assertEquals(0, inflatIP.read(b, 0, 0));
217
218        try {
219            result = inflatIP.read(b, 5, 2); //offset higher
220            fail("IndexOutOfBoundsException expected");
221        } catch (IndexOutOfBoundsException iobe) {
222            //expected
223        }
224
225        inflatIP.close();
226        try {
227            inflatIP.read(b, 0, 1); //read after close
228            fail("IOException expected");
229        } catch (IOException ioe) {
230            //expected
231        }
232    }
233
234    public void testAvailableNonEmptySource() throws Exception {
235        // this byte[] is a deflation of these bytes: { 1, 3, 4, 6 }
236        byte[] deflated = { 72, -119, 99, 100, 102, 97, 3, 0, 0, 31, 0, 15, 0 };
237        try (InputStream in = new InflaterInputStream(new ByteArrayInputStream(deflated))) {
238            // InflaterInputStream.available() returns either 1 or 0, even though
239            // that contradicts the behavior defined in InputStream.available()
240            assertEquals(1, in.read());
241            assertEquals(1, in.available());
242            assertEquals(3, in.read());
243            assertEquals(1, in.available());
244            assertEquals(4, in.read());
245            assertEquals(1, in.available());
246            assertEquals(6, in.read());
247            assertEquals(0, in.available());
248            assertEquals(-1, in.read());
249            assertEquals(-1, in.read());
250        }
251    }
252
253    public void testAvailableSkip() throws Exception {
254        // this byte[] is a deflation of these bytes: { 1, 3, 4, 6 }
255        byte[] deflated = { 72, -119, 99, 100, 102, 97, 3, 0, 0, 31, 0, 15, 0 };
256        try (InputStream in = new InflaterInputStream(new ByteArrayInputStream(deflated))) {
257            assertEquals(1, in.available());
258            assertEquals(4, in.skip(4));
259            assertEquals(0, in.available());
260        }
261    }
262
263    public void testAvailableEmptySource() throws Exception {
264        // this byte[] is a deflation of the empty file
265        byte[] deflated = { 120, -100, 3, 0, 0, 0, 0, 1 };
266        try (InputStream in = new InflaterInputStream(new ByteArrayInputStream(deflated))) {
267            assertEquals(-1, in.read());
268            assertEquals(-1, in.read());
269            assertEquals(0, in.available());
270        }
271    }
272
273    /**
274     * java.util.zip.InflaterInputStream#read(byte[], int, int)
275     */
276    public void test_read$BII() throws IOException {
277        byte[] test = new byte[507];
278        for (int i = 0; i < 256; i++) {
279            test[i] = (byte) i;
280        }
281        for (int i = 256; i < test.length; i++) {
282            test[i] = (byte) (256 - i);
283        }
284        ByteArrayOutputStream baos = new ByteArrayOutputStream();
285        try (DeflaterOutputStream dos = new DeflaterOutputStream(baos)) {
286            dos.write(test);
287        }
288        try (InflaterInputStream iis = new InflaterInputStream(
289                new ByteArrayInputStream(baos.toByteArray()))) {
290            byte[] outBuf = new byte[530];
291            int result = 0;
292            while (true) {
293                result = iis.read(outBuf, 0, 5);
294                if (result == -1) {
295                    //"EOF was reached";
296                    break;
297                }
298            }
299            try {
300                iis.read(outBuf, -1, 10);
301                fail("should throw IOOBE.");
302            } catch (IndexOutOfBoundsException e) {
303                // expected;
304            }
305        }
306    }
307
308    public void test_read$BII2() throws IOException {
309        File resources = Support_Resources.createTempFolder();
310        Support_Resources.copyFile(resources, null, "Broken_manifest.jar");
311        FileInputStream fis = new FileInputStream(new File(resources,
312                "Broken_manifest.jar"));
313        InflaterInputStream iis = new InflaterInputStream(fis);
314        byte[] outBuf = new byte[530];
315
316        iis.close();
317        try {
318            iis.read(outBuf, 0, 5);
319            fail("IOException expected");
320        } catch (IOException ee) {
321            // expected.
322        }
323    }
324
325    public void test_read$BII3() throws IOException {
326        File resources = Support_Resources.createTempFolder();
327        Support_Resources.copyFile(resources, null, "Broken_manifest.jar");
328        FileInputStream fis = new FileInputStream(new File(resources,
329                "Broken_manifest.jar"));
330        try (InflaterInputStream iis = new InflaterInputStream(fis)) {
331            try {
332                iis.read();
333                fail("IOException expected.");
334            } catch (IOException ee) {
335                // expected
336            }
337        }
338    }
339
340    /**
341     * java.util.zip.InflaterInputStream#reset()
342     */
343    public void test_reset() throws IOException {
344        InputStream is = new ByteArrayInputStream(new byte[10]);
345        try (InflaterInputStream iis = new InflaterInputStream(is)) {
346            try {
347                iis.reset();
348                fail("Should throw IOException");
349            } catch (IOException e) {
350                // correct
351            }
352        }
353    }
354
355    /**
356     * java.util.zip.InflaterInputStream#skip(long)
357     */
358    public void test_skipJ() throws IOException {
359        InputStream is = Support_Resources.getStream("hyts_available.tst");
360        InflaterInputStream iis = new InflaterInputStream(is);
361
362        // Tests for skipping a negative number of bytes.
363        try {
364            iis.skip(-3);
365            fail("IllegalArgumentException not thrown");
366        } catch (IllegalArgumentException e) {
367            // Expected
368        }
369        assertEquals("Incorrect Byte Returned.", 5, iis.read());
370
371        try {
372            iis.skip(Integer.MIN_VALUE);
373            fail("IllegalArgumentException not thrown");
374        } catch (IllegalArgumentException e) {
375            // Expected
376        }
377        assertEquals("Incorrect Byte Returned.", 4, iis.read());
378
379        // Test to make sure the correct number of bytes were skipped
380        assertEquals("Incorrect Number Of Bytes Skipped.", 3, iis.skip(3));
381
382        // Test to see if the number of bytes skipped returned is true.
383        assertEquals("Incorrect Byte Returned.", 7, iis.read());
384
385        assertEquals("Incorrect Number Of Bytes Skipped.", 0, iis.skip(0));
386        assertEquals("Incorrect Byte Returned.", 0, iis.read());
387
388        // Test for skipping more bytes than available in the stream
389        assertEquals("Incorrect Number Of Bytes Skipped.", 2, iis.skip(4));
390        assertEquals("Incorrect Byte Returned.", -1, iis.read());
391        iis.close();
392    }
393
394    /**
395     * java.util.zip.InflaterInputStream#skip(long)
396     */
397    public void test_skipJ2() throws IOException {
398        int result = 0;
399        int buffer[] = new int[100];
400        byte orgBuffer[] = { 1, 3, 4, 7, 8 };
401
402        // testing for negative input to skip
403        InputStream infile = Support_Resources.getStream("hyts_construOD.bin");
404        Inflater inflate = new Inflater();
405        InflaterInputStream inflatIP = new InflaterInputStream(infile, inflate, 10);
406        long skip;
407        try {
408            skip = inflatIP.skip(Integer.MIN_VALUE);
409            fail("Expected IllegalArgumentException when skip() is called with negative parameter");
410        } catch (IllegalArgumentException e) {
411            // Expected
412        }
413        inflatIP.close();
414
415        // testing for number of bytes greater than input.
416        InputStream infile2 = Support_Resources.getStream("hyts_construOD.bin");
417        try (InflaterInputStream inflatIP2 = new InflaterInputStream(infile2)) {
418
419            // looked at how many bytes the skip skipped. It is
420            // 5 and its supposed to be the entire input stream.
421
422            skip = inflatIP2.skip(Integer.MAX_VALUE);
423            // System.out.println(skip);
424            assertEquals("method skip() returned wrong number of bytes skipped",
425                    5, skip);
426            inflatIP2.close();
427        }
428
429        // test for skipping of 2 bytes
430        InputStream infile3 = Support_Resources.getStream("hyts_construOD.bin");
431        try (InflaterInputStream inflatIP3 = new InflaterInputStream(infile3)) {
432            skip = inflatIP3.skip(2);
433            assertEquals(
434                    "the number of bytes returned by skip did not correspond with its input parameters",
435                    2, skip);
436            int i = 0;
437            result = 0;
438            while ((result = inflatIP3.read()) != -1) {
439                buffer[i] = result;
440                i++;
441            }
442        }
443
444        for (int j = 2; j < orgBuffer.length; j++) {
445            assertEquals(
446                    "original compressed data did not equal decompressed data",
447                    orgBuffer[j], buffer[j - 2]);
448        }
449    }
450
451    /**
452     * java.util.zip.InflaterInputStream#available()
453     */
454    public void test_available() throws IOException {
455        InputStream is = Support_Resources.getStream("hyts_available.tst");
456        InflaterInputStream iis = new InflaterInputStream(is);
457
458        int available;
459        for (int i = 0; i < 11; i++) {
460            iis.read();
461            available = iis.available();
462            if (available == 0) {
463                assertEquals("Expected no more bytes to read", -1, iis.read());
464            } else {
465                assertEquals("Bytes Available Should Return 1.", 1, available);
466            }
467        }
468
469        iis.close();
470        try {
471            iis.available();
472            fail("available after close should throw IOException.");
473        } catch (IOException e) {
474            // Expected
475        }
476    }
477
478    /**
479     * java.util.zip.InflaterInputStream#close()
480     */
481    public void test_close() throws IOException {
482        InflaterInputStream iin = new InflaterInputStream(
483                new ByteArrayInputStream(new byte[0]));
484        iin.close();
485
486        // test for exception
487        iin.close();
488    }
489
490    // http://b/26462400
491    public void testInflaterInputStreamWithExternalInflater() throws Exception {
492        InputStream base = new ByteArrayInputStream(new byte[] { 'h', 'i'});
493        Inflater inf = new Inflater();
494
495        InflaterInputStream iis = new InflaterInputStream(base, inf, 512);
496        iis.close();
497        try {
498            inf.reset();
499            fail();
500        } catch (IllegalStateException espected) {
501            // Expected because the inflater should've been closed when the stream was.
502        }
503
504        inf = new Inflater();
505        iis = new InflaterInputStream(base, inf);
506        iis.close();
507        try {
508            inf.reset();
509            fail();
510        } catch (IllegalStateException espected) {
511            // Expected because the inflater should've been closed when the stream was.
512        }
513    }
514}
515