/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.commons.compress.archivers.zip;

import static org.apache.commons.compress.AbstractTestCase.getFile;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.SeekableByteChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.CRC32;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;

import org.apache.commons.compress.utils.ByteUtils;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.compress.utils.SeekableInMemoryByteChannel;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;

public class ZipFileTest {
    private ZipFile zf = null;

    @After
    public void tearDown() {
        ZipFile.closeQuietly(zf);
    }

    @Test
    public void testCDOrder() throws Exception {
        readOrderTest();
        final ArrayList<ZipArchiveEntry> l = Collections.list(zf.getEntries());
        assertEntryName(l, 0, "AbstractUnicodeExtraField");
        assertEntryName(l, 1, "AsiExtraField");
        assertEntryName(l, 2, "ExtraFieldUtils");
        assertEntryName(l, 3, "FallbackZipEncoding");
        assertEntryName(l, 4, "GeneralPurposeBit");
        assertEntryName(l, 5, "JarMarker");
        assertEntryName(l, 6, "NioZipEncoding");
        assertEntryName(l, 7, "Simple8BitZipEncoding");
        assertEntryName(l, 8, "UnicodeCommentExtraField");
        assertEntryName(l, 9, "UnicodePathExtraField");
        assertEntryName(l, 10, "UnixStat");
        assertEntryName(l, 11, "UnparseableExtraFieldData");
        assertEntryName(l, 12, "UnrecognizedExtraField");
        assertEntryName(l, 13, "ZipArchiveEntry");
        assertEntryName(l, 14, "ZipArchiveInputStream");
        assertEntryName(l, 15, "ZipArchiveOutputStream");
        assertEntryName(l, 16, "ZipEncoding");
        assertEntryName(l, 17, "ZipEncodingHelper");
        assertEntryName(l, 18, "ZipExtraField");
        assertEntryName(l, 19, "ZipUtil");
        assertEntryName(l, 20, "ZipLong");
        assertEntryName(l, 21, "ZipShort");
        assertEntryName(l, 22, "ZipFile");
    }

    @Test
    public void testCDOrderInMemory() throws Exception {
        byte[] data = null;
        try (InputStream fis = Files.newInputStream(getFile("ordertest.zip").toPath())) {
            data = IOUtils.toByteArray(fis);
        }

        zf = new ZipFile(new SeekableInMemoryByteChannel(data), ZipEncodingHelper.UTF8);
        final ArrayList<ZipArchiveEntry> l = Collections.list(zf.getEntries());
        assertEntryName(l, 0, "AbstractUnicodeExtraField");
        assertEntryName(l, 1, "AsiExtraField");
        assertEntryName(l, 2, "ExtraFieldUtils");
        assertEntryName(l, 3, "FallbackZipEncoding");
        assertEntryName(l, 4, "GeneralPurposeBit");
        assertEntryName(l, 5, "JarMarker");
        assertEntryName(l, 6, "NioZipEncoding");
        assertEntryName(l, 7, "Simple8BitZipEncoding");
        assertEntryName(l, 8, "UnicodeCommentExtraField");
        assertEntryName(l, 9, "UnicodePathExtraField");
        assertEntryName(l, 10, "UnixStat");
        assertEntryName(l, 11, "UnparseableExtraFieldData");
        assertEntryName(l, 12, "UnrecognizedExtraField");
        assertEntryName(l, 13, "ZipArchiveEntry");
        assertEntryName(l, 14, "ZipArchiveInputStream");
        assertEntryName(l, 15, "ZipArchiveOutputStream");
        assertEntryName(l, 16, "ZipEncoding");
        assertEntryName(l, 17, "ZipEncodingHelper");
        assertEntryName(l, 18, "ZipExtraField");
        assertEntryName(l, 19, "ZipUtil");
        assertEntryName(l, 20, "ZipLong");
        assertEntryName(l, 21, "ZipShort");
        assertEntryName(l, 22, "ZipFile");
    }

    @Test
    public void testPhysicalOrder() throws Exception {
        readOrderTest();
        final ArrayList<ZipArchiveEntry> l = Collections.list(zf.getEntriesInPhysicalOrder());
        assertEntryName(l, 0, "AbstractUnicodeExtraField");
        assertEntryName(l, 1, "AsiExtraField");
        assertEntryName(l, 2, "ExtraFieldUtils");
        assertEntryName(l, 3, "FallbackZipEncoding");
        assertEntryName(l, 4, "GeneralPurposeBit");
        assertEntryName(l, 5, "JarMarker");
        assertEntryName(l, 6, "NioZipEncoding");
        assertEntryName(l, 7, "Simple8BitZipEncoding");
        assertEntryName(l, 8, "UnicodeCommentExtraField");
        assertEntryName(l, 9, "UnicodePathExtraField");
        assertEntryName(l, 10, "UnixStat");
        assertEntryName(l, 11, "UnparseableExtraFieldData");
        assertEntryName(l, 12, "UnrecognizedExtraField");
        assertEntryName(l, 13, "ZipArchiveEntry");
        assertEntryName(l, 14, "ZipArchiveInputStream");
        assertEntryName(l, 15, "ZipArchiveOutputStream");
        assertEntryName(l, 16, "ZipEncoding");
        assertEntryName(l, 17, "ZipEncodingHelper");
        assertEntryName(l, 18, "ZipExtraField");
        assertEntryName(l, 19, "ZipFile");
        assertEntryName(l, 20, "ZipLong");
        assertEntryName(l, 21, "ZipShort");
        assertEntryName(l, 22, "ZipUtil");
    }

    @Test
    public void testPhysicalOrderOfSpecificFile() throws Exception {
        readOrderTest();
        final String entryName = "src/main/java/org/apache/commons/compress/archivers/zip/ZipExtraField.java";
        final Iterable<ZipArchiveEntry> entries = zf.getEntriesInPhysicalOrder(entryName);
        final Iterator<ZipArchiveEntry> iter = entries.iterator();
        final ZipArchiveEntry entry = iter.next();

        assertEquals(entryName, entry.getName());
        assertFalse(iter.hasNext());
    }

    @Test
    public void testDoubleClose() throws Exception {
        readOrderTest();
        zf.close();
        try {
            zf.close();
        } catch (final Exception ex) {
            fail("Caught exception of second close");
        }
    }

    @Test
    public void testReadingOfStoredEntry() throws Exception {
        final File f = File.createTempFile("commons-compress-zipfiletest", ".zip");
        f.deleteOnExit();
        OutputStream o = null;
        InputStream i = null;
        try {
            o = Files.newOutputStream(f.toPath());
            final ZipArchiveOutputStream zo = new ZipArchiveOutputStream(o);
            ZipArchiveEntry ze = new ZipArchiveEntry("foo");
            ze.setMethod(ZipEntry.STORED);
            ze.setSize(4);
            ze.setCrc(0xb63cfbcdL);
            zo.putArchiveEntry(ze);
            zo.write(new byte[] { 1, 2, 3, 4 });
            zo.closeArchiveEntry();
            zo.close();
            o.close();
            o  = null;

            zf = new ZipFile(f);
            ze = zf.getEntry("foo");
            assertNotNull(ze);
            i = zf.getInputStream(ze);
            final byte[] b = new byte[4];
            assertEquals(4, i.read(b));
            assertEquals(-1, i.read());
        } finally {
            if (o != null) {
                o.close();
            }
            if (i != null) {
                i.close();
            }
            f.delete();
        }
    }

    /**
     * @see "https://issues.apache.org/jira/browse/COMPRESS-176"
     */
    @Test
    public void testWinzipBackSlashWorkaround() throws Exception {
        final File archive = getFile("test-winzip.zip");
        zf = new ZipFile(archive);
        assertNull(zf.getEntry("\u00e4\\\u00fc.txt"));
        assertNotNull(zf.getEntry("\u00e4/\u00fc.txt"));
    }

    /**
     * Test case for
     * <a href="https://issues.apache.org/jira/browse/COMPRESS-208"
     * >COMPRESS-208</a>.
     */
    @Test
    public void testSkipsPK00Prefix() throws Exception {
        final File archive = getFile("COMPRESS-208.zip");
        zf = new ZipFile(archive);
        assertNotNull(zf.getEntry("test1.xml"));
        assertNotNull(zf.getEntry("test2.xml"));
    }

    @Test
    public void testUnixSymlinkSampleFile() throws Exception {
        final String entryPrefix = "COMPRESS-214_unix_symlinks/";
        final TreeMap<String, String> expectedVals = new TreeMap<>();

        // I threw in some Japanese characters to keep things interesting.
        expectedVals.put(entryPrefix + "link1", "../COMPRESS-214_unix_symlinks/./a/b/c/../../../\uF999");
        expectedVals.put(entryPrefix + "link2", "../COMPRESS-214_unix_symlinks/./a/b/c/../../../g");
        expectedVals.put(entryPrefix + "link3", "../COMPRESS-214_unix_symlinks/././a/b/c/../../../\u76F4\u6A39");
        expectedVals.put(entryPrefix + "link4", "\u82B1\u5B50/\u745B\u5B50");
        expectedVals.put(entryPrefix + "\uF999", "./\u82B1\u5B50/\u745B\u5B50/\u5897\u8C37/\uF999");
        expectedVals.put(entryPrefix + "g", "./a/b/c/d/e/f/g");
        expectedVals.put(entryPrefix + "\u76F4\u6A39", "./g");

        // Notice how a directory link might contain a trailing slash, or it might not.
        // Also note:  symlinks are always stored as files, even if they link to directories.
        expectedVals.put(entryPrefix + "link5", "../COMPRESS-214_unix_symlinks/././a/b");
        expectedVals.put(entryPrefix + "link6", "../COMPRESS-214_unix_symlinks/././a/b/");

        // I looked into creating a test with hard links, but zip does not appear to
        // support hard links, so nevermind.

        final File archive = getFile("COMPRESS-214_unix_symlinks.zip");

        zf = new ZipFile(archive);
        final Enumeration<ZipArchiveEntry> en = zf.getEntries();
        while (en.hasMoreElements()) {
            final ZipArchiveEntry zae = en.nextElement();
            final String link = zf.getUnixSymlink(zae);
            if (zae.isUnixSymlink()) {
                final String name = zae.getName();
                final String expected = expectedVals.get(name);
                assertEquals(expected, link);
            } else {
                // Should be null if it's not a symlink!
                assertNull(link);
            }
        }
    }

    /**
     * @see "https://issues.apache.org/jira/browse/COMPRESS-227"
     */
    @Test
    public void testDuplicateEntry() throws Exception {
        final File archive = getFile("COMPRESS-227.zip");
        zf = new ZipFile(archive);

        final ZipArchiveEntry ze = zf.getEntry("test1.txt");
        assertNotNull(ze);
        assertNotNull(zf.getInputStream(ze));

        int numberOfEntries = 0;
        for (final ZipArchiveEntry entry : zf.getEntries("test1.txt")) {
            numberOfEntries++;
            assertNotNull(zf.getInputStream(entry));
        }
        assertEquals(2, numberOfEntries);
    }

    /**
     * @see "https://issues.apache.org/jira/browse/COMPRESS-228"
     */
    @Test
    public void testExcessDataInZip64ExtraField() throws Exception {
        final File archive = getFile("COMPRESS-228.zip");
        zf = new ZipFile(archive);
        // actually, if we get here, the test already has passed

        final ZipArchiveEntry ze = zf.getEntry("src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java");
        assertEquals(26101, ze.getSize());
    }

    @Test
    public void testUnshrinking() throws Exception {
        zf = new ZipFile(getFile("SHRUNK.ZIP"));
        ZipArchiveEntry test = zf.getEntry("TEST1.XML");
        InputStream original = Files.newInputStream(getFile("test1.xml").toPath());
        try {
            assertArrayEquals(IOUtils.toByteArray(original),
                              IOUtils.toByteArray(zf.getInputStream(test)));
        } finally {
            original.close();
        }
        test = zf.getEntry("TEST2.XML");
        original = Files.newInputStream(getFile("test2.xml").toPath());
        try {
            assertArrayEquals(IOUtils.toByteArray(original),
                              IOUtils.toByteArray(zf.getInputStream(test)));
        } finally {
            original.close();
        }
    }

    /**
     * Test case for
     * <a href="https://issues.apache.org/jira/browse/COMPRESS-264"
     * >COMPRESS-264</a>.
     */
    @Test
    public void testReadingOfFirstStoredEntry() throws Exception {
        final File archive = getFile("COMPRESS-264.zip");
        zf = new ZipFile(archive);
        final ZipArchiveEntry ze = zf.getEntry("test.txt");
        assertEquals(5, ze.getSize());
        assertArrayEquals(new byte[] {'d', 'a', 't', 'a', '\n'},
                          IOUtils.toByteArray(zf.getInputStream(ze)));
    }

    @Test
    public void testUnzipBZip2CompressedEntry() throws Exception {
        final File archive = getFile("bzip2-zip.zip");
        zf = new ZipFile(archive);
        final ZipArchiveEntry ze = zf.getEntry("lots-of-as");
        assertEquals(42, ze.getSize());
        final byte[] expected = new byte[42];
        Arrays.fill(expected , (byte)'a');
        assertArrayEquals(expected, IOUtils.toByteArray(zf.getInputStream(ze)));
    }

    @Test
    public void testConcurrentReadSeekable() throws Exception {
        // mixed.zip contains both inflated and stored files
        byte[] data = null;
        try (InputStream fis = Files.newInputStream(getFile("mixed.zip").toPath())) {
            data = IOUtils.toByteArray(fis);
        }
        zf = new ZipFile(new SeekableInMemoryByteChannel(data), ZipEncodingHelper.UTF8);

        final Map<String, byte[]> content = new HashMap<>();
        for (final ZipArchiveEntry entry: Collections.list(zf.getEntries())) {
            content.put(entry.getName(), IOUtils.toByteArray(zf.getInputStream(entry)));
        }

        final AtomicInteger passedCount = new AtomicInteger();
        final Runnable run = () -> {
            for (final ZipArchiveEntry entry: Collections.list(zf.getEntries())) {
                assertAllReadMethods(content.get(entry.getName()), zf, entry);
            }
            passedCount.incrementAndGet();
        };
        final Thread t0 = new Thread(run);
        final Thread t1 = new Thread(run);
        t0.start();
        t1.start();
        t0.join();
        t1.join();
        assertEquals(2, passedCount.get());
    }

    @Test
    public void testConcurrentReadFile() throws Exception {
        // mixed.zip contains both inflated and stored files
        final File archive = getFile("mixed.zip");
        zf = new ZipFile(archive);

        final Map<String, byte[]> content = new HashMap<>();
        for (final ZipArchiveEntry entry: Collections.list(zf.getEntries())) {
            content.put(entry.getName(), IOUtils.toByteArray(zf.getInputStream(entry)));
        }

        final AtomicInteger passedCount = new AtomicInteger();
        final Runnable run = () -> {
            for (final ZipArchiveEntry entry: Collections.list(zf.getEntries())) {
                assertAllReadMethods(content.get(entry.getName()), zf, entry);
            }
            passedCount.incrementAndGet();
        };
        final Thread t0 = new Thread(run);
        final Thread t1 = new Thread(run);
        t0.start();
        t1.start();
        t0.join();
        t1.join();
        assertEquals(2, passedCount.get());
    }

    /**
     * Test correct population of header and data offsets.
     */
    @Test
    public void testOffsets() throws Exception {
        // mixed.zip contains both inflated and stored files
        final File archive = getFile("mixed.zip");
        try (ZipFile zf = new ZipFile(archive)) {
            final ZipArchiveEntry inflatedEntry = zf.getEntry("inflated.txt");
            Assert.assertEquals(0x0000, inflatedEntry.getLocalHeaderOffset());
            Assert.assertEquals(0x0046, inflatedEntry.getDataOffset());
            Assert.assertTrue(inflatedEntry.isStreamContiguous());
            final ZipArchiveEntry storedEntry = zf.getEntry("stored.txt");
            Assert.assertEquals(0x5892, storedEntry.getLocalHeaderOffset());
            Assert.assertEquals(0x58d6, storedEntry.getDataOffset());
            Assert.assertTrue(inflatedEntry.isStreamContiguous());
        }
    }

    /**
     * Test correct population of header and data offsets when they are written after stream.
     */
    @Test
    public void testDelayedOffsetsAndSizes() throws Exception {
        final ByteArrayOutputStream zipContent = new ByteArrayOutputStream();
        try (ZipArchiveOutputStream zipOutput = new ZipArchiveOutputStream(zipContent)) {
            final ZipArchiveEntry inflatedEntry = new ZipArchiveEntry("inflated.txt");
            inflatedEntry.setMethod(ZipEntry.DEFLATED);
            zipOutput.putArchiveEntry(inflatedEntry);
            zipOutput.write("Hello Deflated\n".getBytes());
            zipOutput.closeArchiveEntry();

            final byte[] storedContent = "Hello Stored\n".getBytes();
            final ZipArchiveEntry storedEntry = new ZipArchiveEntry("stored.txt");
            storedEntry.setMethod(ZipEntry.STORED);
            storedEntry.setSize(storedContent.length);
            storedEntry.setCrc(calculateCrc32(storedContent));
            zipOutput.putArchiveEntry(storedEntry);
            zipOutput.write("Hello Stored\n".getBytes());
            zipOutput.closeArchiveEntry();

        }

        try (ZipFile zf = new ZipFile(new SeekableInMemoryByteChannel(zipContent.toByteArray()))) {
            final ZipArchiveEntry inflatedEntry = zf.getEntry("inflated.txt");
            Assert.assertNotEquals(-1L, inflatedEntry.getLocalHeaderOffset());
            Assert.assertNotEquals(-1L, inflatedEntry.getDataOffset());
            Assert.assertTrue(inflatedEntry.isStreamContiguous());
            Assert.assertNotEquals(-1L, inflatedEntry.getCompressedSize());
            Assert.assertNotEquals(-1L, inflatedEntry.getSize());
            final ZipArchiveEntry storedEntry = zf.getEntry("stored.txt");
            Assert.assertNotEquals(-1L, storedEntry.getLocalHeaderOffset());
            Assert.assertNotEquals(-1L, storedEntry.getDataOffset());
            Assert.assertTrue(inflatedEntry.isStreamContiguous());
            Assert.assertNotEquals(-1L, storedEntry.getCompressedSize());
            Assert.assertNotEquals(-1L, storedEntry.getSize());
        }
    }

    /**
     * Test entries alignment.
     */
    @Test
    public void testEntryAlignment() throws Exception {
        final SeekableInMemoryByteChannel zipContent = new SeekableInMemoryByteChannel();
        try (ZipArchiveOutputStream zipOutput = new ZipArchiveOutputStream(zipContent)) {
            final ZipArchiveEntry inflatedEntry = new ZipArchiveEntry("inflated.txt");
            inflatedEntry.setMethod(ZipEntry.DEFLATED);
            inflatedEntry.setAlignment(1024);
            zipOutput.putArchiveEntry(inflatedEntry);
            zipOutput.write("Hello Deflated\n".getBytes(StandardCharsets.UTF_8));
            zipOutput.closeArchiveEntry();

            final ZipArchiveEntry storedEntry = new ZipArchiveEntry("stored.txt");
            storedEntry.setMethod(ZipEntry.STORED);
            storedEntry.setAlignment(1024);
            zipOutput.putArchiveEntry(storedEntry);
            zipOutput.write("Hello Stored\n".getBytes(StandardCharsets.UTF_8));
            zipOutput.closeArchiveEntry();

            final ZipArchiveEntry storedEntry2 = new ZipArchiveEntry("stored2.txt");
            storedEntry2.setMethod(ZipEntry.STORED);
            storedEntry2.setAlignment(1024);
            storedEntry2.addExtraField(new ResourceAlignmentExtraField(1));
            zipOutput.putArchiveEntry(storedEntry2);
            zipOutput.write("Hello overload-alignment Stored\n".getBytes(StandardCharsets.UTF_8));
            zipOutput.closeArchiveEntry();

            final ZipArchiveEntry storedEntry3 = new ZipArchiveEntry("stored3.txt");
            storedEntry3.setMethod(ZipEntry.STORED);
            storedEntry3.addExtraField(new ResourceAlignmentExtraField(1024));
            zipOutput.putArchiveEntry(storedEntry3);
            zipOutput.write("Hello copy-alignment Stored\n".getBytes(StandardCharsets.UTF_8));
            zipOutput.closeArchiveEntry();

        }

        try (ZipFile zf = new ZipFile(new SeekableInMemoryByteChannel(
                        Arrays.copyOfRange(zipContent.array(), 0, (int)zipContent.size())
        ))) {
            final ZipArchiveEntry inflatedEntry = zf.getEntry("inflated.txt");
            final ResourceAlignmentExtraField inflatedAlignmentEx =
                            (ResourceAlignmentExtraField)inflatedEntry.getExtraField(ResourceAlignmentExtraField.ID);
            assertNotEquals(-1L, inflatedEntry.getCompressedSize());
            assertNotEquals(-1L, inflatedEntry.getSize());
            assertEquals(0L, inflatedEntry.getDataOffset()%1024);
            assertNotNull(inflatedAlignmentEx);
            assertEquals(1024, inflatedAlignmentEx.getAlignment());
            assertFalse(inflatedAlignmentEx.allowMethodChange());
            try (InputStream stream = zf.getInputStream(inflatedEntry)) {
                Assert.assertEquals("Hello Deflated\n",
                                new String(IOUtils.toByteArray(stream), StandardCharsets.UTF_8));
            }
            final ZipArchiveEntry storedEntry = zf.getEntry("stored.txt");
            final ResourceAlignmentExtraField storedAlignmentEx =
                            (ResourceAlignmentExtraField)storedEntry.getExtraField(ResourceAlignmentExtraField.ID);
            assertNotEquals(-1L, storedEntry.getCompressedSize());
            assertNotEquals(-1L, storedEntry.getSize());
            assertEquals(0L, storedEntry.getDataOffset()%1024);
            assertNotNull(storedAlignmentEx);
            assertEquals(1024, storedAlignmentEx.getAlignment());
            assertFalse(storedAlignmentEx.allowMethodChange());
            try (InputStream stream = zf.getInputStream(storedEntry)) {
                Assert.assertEquals("Hello Stored\n",
                                new String(IOUtils.toByteArray(stream), StandardCharsets.UTF_8));
            }

            final ZipArchiveEntry storedEntry2 = zf.getEntry("stored2.txt");
            final ResourceAlignmentExtraField stored2AlignmentEx =
                            (ResourceAlignmentExtraField)storedEntry2.getExtraField(ResourceAlignmentExtraField.ID);
            assertNotEquals(-1L, storedEntry2.getCompressedSize());
            assertNotEquals(-1L, storedEntry2.getSize());
            assertEquals(0L, storedEntry2.getDataOffset()%1024);
            assertNotNull(stored2AlignmentEx);
            assertEquals(1024, stored2AlignmentEx.getAlignment());
            assertFalse(stored2AlignmentEx.allowMethodChange());
            try (InputStream stream = zf.getInputStream(storedEntry2)) {
                Assert.assertEquals("Hello overload-alignment Stored\n",
                                new String(IOUtils.toByteArray(stream), StandardCharsets.UTF_8));
            }

            final ZipArchiveEntry storedEntry3 = zf.getEntry("stored3.txt");
            final ResourceAlignmentExtraField stored3AlignmentEx =
                            (ResourceAlignmentExtraField)storedEntry3.getExtraField(ResourceAlignmentExtraField.ID);
            assertNotEquals(-1L, storedEntry3.getCompressedSize());
            assertNotEquals(-1L, storedEntry3.getSize());
            assertEquals(0L, storedEntry3.getDataOffset()%1024);
            assertNotNull(stored3AlignmentEx);
            assertEquals(1024, stored3AlignmentEx.getAlignment());
            assertFalse(stored3AlignmentEx.allowMethodChange());
            try (InputStream stream = zf.getInputStream(storedEntry3)) {
                Assert.assertEquals("Hello copy-alignment Stored\n",
                                new String(IOUtils.toByteArray(stream), StandardCharsets.UTF_8));
            }
        }
    }

    /**
     * Test too big alignment, resulting into exceeding extra field limit.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testEntryAlignmentExceed() throws Exception {
        final SeekableInMemoryByteChannel zipContent = new SeekableInMemoryByteChannel();
        try (ZipArchiveOutputStream zipOutput = new ZipArchiveOutputStream(zipContent)) {
            final ZipArchiveEntry inflatedEntry = new ZipArchiveEntry("inflated.txt");
            inflatedEntry.setMethod(ZipEntry.STORED);
            inflatedEntry.setAlignment(0x20000);
        }
    }

    /**
     * Test non power of 2 alignment.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testInvalidAlignment() throws Exception {
        final ZipArchiveEntry entry = new ZipArchiveEntry("dummy");
        entry.setAlignment(3);
    }

    @Test
    public void nameSourceDefaultsToName() throws Exception {
        nameSource("bla.zip", "test1.xml", ZipArchiveEntry.NameSource.NAME);
    }

    @Test
    public void nameSourceIsSetToUnicodeExtraField() throws Exception {
        nameSource("utf8-winzip-test.zip", "\u20AC_for_Dollar.txt",
                   ZipArchiveEntry.NameSource.UNICODE_EXTRA_FIELD);
    }

    @Test
    public void nameSourceIsSetToEFS() throws Exception {
        nameSource("utf8-7zip-test.zip", "\u20AC_for_Dollar.txt",
                   ZipArchiveEntry.NameSource.NAME_WITH_EFS_FLAG);
    }

    /**
     * @see "https://issues.apache.org/jira/browse/COMPRESS-380"
     */
    @Test
    public void readDeflate64CompressedStream() throws Exception {
        final File input = getFile("COMPRESS-380/COMPRESS-380-input");
        final File archive = getFile("COMPRESS-380/COMPRESS-380.zip");
        try (InputStream in = Files.newInputStream(input.toPath());
             ZipFile zf = new ZipFile(archive)) {
            final byte[] orig = IOUtils.toByteArray(in);
            final ZipArchiveEntry e = zf.getEntry("input2");
            try (InputStream s = zf.getInputStream(e)) {
                final byte[] fromZip = IOUtils.toByteArray(s);
                assertArrayEquals(orig, fromZip);
            }
        }
    }

    @Test
    public void singleByteReadConsistentlyReturnsMinusOneAtEofUsingDeflate() throws Exception {
        singleByteReadConsistentlyReturnsMinusOneAtEof(getFile("bla.zip"));
    }

    @Test
    public void singleByteReadConsistentlyReturnsMinusOneAtEofUsingStore() throws Exception {
        singleByteReadConsistentlyReturnsMinusOneAtEof(getFile("COMPRESS-264.zip"));
    }

    @Test
    public void singleByteReadConsistentlyReturnsMinusOneAtEofUsingUnshrink() throws Exception {
        singleByteReadConsistentlyReturnsMinusOneAtEof(getFile("SHRUNK.ZIP"));
    }

    @Test
    public void singleByteReadConsistentlyReturnsMinusOneAtEofUsingExplode() throws Exception {
        singleByteReadConsistentlyReturnsMinusOneAtEof(getFile("imploding-8Kdict-3trees.zip"));
    }

    @Test
    public void singleByteReadConsistentlyReturnsMinusOneAtEofUsingDeflate64() throws Exception {
        singleByteReadConsistentlyReturnsMinusOneAtEof(getFile("COMPRESS-380/COMPRESS-380.zip"));
    }

    @Test
    public void singleByteReadConsistentlyReturnsMinusOneAtEofUsingBzip2() throws Exception {
        singleByteReadConsistentlyReturnsMinusOneAtEof(getFile("bzip2-zip.zip"));
    }

    private void singleByteReadConsistentlyReturnsMinusOneAtEof(final File file) throws Exception {
        try (ZipFile archive = new ZipFile(file)) {
            final ZipArchiveEntry e = archive.getEntries().nextElement();
            try (InputStream is = archive.getInputStream(e)) {
                IOUtils.toByteArray(is);
                assertEquals(-1, is.read());
                assertEquals(-1, is.read());
            }
        }
    }

    @Test
    public void multiByteReadConsistentlyReturnsMinusOneAtEofUsingDeflate() throws Exception {
        multiByteReadConsistentlyReturnsMinusOneAtEof(getFile("bla.zip"));
    }

    @Test
    public void multiByteReadConsistentlyReturnsMinusOneAtEofUsingStore() throws Exception {
        multiByteReadConsistentlyReturnsMinusOneAtEof(getFile("COMPRESS-264.zip"));
    }

    @Test
    public void multiByteReadConsistentlyReturnsMinusOneAtEofUsingUnshrink() throws Exception {
        multiByteReadConsistentlyReturnsMinusOneAtEof(getFile("SHRUNK.ZIP"));
    }

    @Test
    public void multiByteReadConsistentlyReturnsMinusOneAtEofUsingExplode() throws Exception {
        multiByteReadConsistentlyReturnsMinusOneAtEof(getFile("imploding-8Kdict-3trees.zip"));
    }

    @Test
    public void multiByteReadConsistentlyReturnsMinusOneAtEofUsingDeflate64() throws Exception {
        multiByteReadConsistentlyReturnsMinusOneAtEof(getFile("COMPRESS-380/COMPRESS-380.zip"));
    }

    @Test
    public void multiByteReadConsistentlyReturnsMinusOneAtEofUsingBzip2() throws Exception {
        multiByteReadConsistentlyReturnsMinusOneAtEof(getFile("bzip2-zip.zip"));
    }

    @Test
    public void extractFileLiesAcrossSplitZipSegmentsCreatedByZip() throws Exception {
        final File lastFile = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip.zip");
        final SeekableByteChannel channel = ZipSplitReadOnlySeekableByteChannel.buildFromLastSplitSegment(lastFile);
        zf = new ZipFile(channel);

        // the compressed content of UnsupportedCompressionAlgorithmException.java lies between .z01 and .z02
        ZipArchiveEntry zipEntry = zf.getEntry("commons-compress/src/main/java/org/apache/commons/compress/archivers/dump/UnsupportedCompressionAlgorithmException.java");
        File fileToCompare = getFile("COMPRESS-477/split_zip_created_by_zip/file_to_compare_1");
        assertFileEqualsToEntry(fileToCompare, zipEntry, zf);

        // the compressed content of DeflateParameters.java lies between .z02 and .zip
        zipEntry = zf.getEntry("commons-compress/src/main/java/org/apache/commons/compress/compressors/deflate/DeflateParameters.java");
        fileToCompare = getFile("COMPRESS-477/split_zip_created_by_zip/file_to_compare_2");
        assertFileEqualsToEntry(fileToCompare, zipEntry, zf);
    }

    @Test
    public void extractFileLiesAcrossSplitZipSegmentsCreatedByZipOfZip64() throws Exception {
        final File lastFile = getFile("COMPRESS-477/split_zip_created_by_zip/split_zip_created_by_zip_zip64.zip");
        final SeekableByteChannel channel = ZipSplitReadOnlySeekableByteChannel.buildFromLastSplitSegment(lastFile);
        zf = new ZipFile(channel);

        // the compressed content of UnsupportedCompressionAlgorithmException.java lies between .z01 and .z02
        ZipArchiveEntry zipEntry = zf.getEntry("commons-compress/src/main/java/org/apache/commons/compress/archivers/dump/UnsupportedCompressionAlgorithmException.java");
        File fileToCompare = getFile("COMPRESS-477/split_zip_created_by_zip/file_to_compare_1");
        assertFileEqualsToEntry(fileToCompare, zipEntry, zf);

        // the compressed content of DeflateParameters.java lies between .z02 and .zip
        zipEntry = zf.getEntry("commons-compress/src/main/java/org/apache/commons/compress/compressors/deflate/DeflateParameters.java");
        fileToCompare = getFile("COMPRESS-477/split_zip_created_by_zip/file_to_compare_2");
        assertFileEqualsToEntry(fileToCompare, zipEntry, zf);
    }

    @Test
    public void extractFileLiesAcrossSplitZipSegmentsCreatedByWinrar() throws Exception {
        final File lastFile = getFile("COMPRESS-477/split_zip_created_by_winrar/split_zip_created_by_winrar.zip");
        final SeekableByteChannel channel = ZipSplitReadOnlySeekableByteChannel.buildFromLastSplitSegment(lastFile);
        zf = new ZipFile(channel);

        // the compressed content of ZipArchiveInputStream.java lies between .z01 and .z02
        final ZipArchiveEntry zipEntry = zf.getEntry("commons-compress/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java");
        final File fileToCompare = getFile("COMPRESS-477/split_zip_created_by_winrar/file_to_compare_1");
        assertFileEqualsToEntry(fileToCompare, zipEntry, zf);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testSetLevelTooSmallForZipArchiveOutputStream() throws Exception {
        final ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(new ByteArrayOutputStream());
        outputStream.setLevel(Deflater.DEFAULT_COMPRESSION - 1);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testSetLevelTooBigForZipArchiveOutputStream() throws Exception {
        final ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(new ByteArrayOutputStream());
        outputStream.setLevel(Deflater.BEST_COMPRESSION + 1);
    }

    @Test(expected = IllegalStateException.class)
    public void throwsExceptionWhenWritingPreamble() throws IOException {
        final ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(new ByteArrayOutputStream());
        outputStream.putArchiveEntry(new ZipArchiveEntry());
        outputStream.writePreamble(ByteUtils.EMPTY_BYTE_ARRAY);
    }

    @Test
    public void testSelfExtractingZipUsingUnzipsfx() throws IOException, InterruptedException {
        final File unzipsfx = new File("/usr/bin/unzipsfx");
        if (!unzipsfx.exists()) {
            return;
        }

        final File testZip = File.createTempFile("commons-compress-selfExtractZipTest", ".zip");
        testZip.deleteOnExit();

        final String testEntryName = "test_self_extract_zip/foo";
        final File extractedFile = new File(testZip.getParentFile(), testEntryName);
        extractedFile.deleteOnExit();

        OutputStream outputStream = null;
        InputStream inputStream = null;
        final byte[] testData = new byte[]{1, 2, 3, 4};
        final byte[] buffer = new byte[512];
        int bytesRead;
        try (InputStream unzipsfxInputStream = Files.newInputStream(unzipsfx.toPath())) {
            outputStream = Files.newOutputStream(testZip.toPath());
            final ZipArchiveOutputStream zo = new ZipArchiveOutputStream(outputStream);

            while ((bytesRead = unzipsfxInputStream.read(buffer)) > 0) {
                zo.writePreamble(buffer, 0, bytesRead);
            }

            final ZipArchiveEntry ze = new ZipArchiveEntry(testEntryName);
            ze.setMethod(ZipEntry.STORED);
            ze.setSize(4);
            ze.setCrc(0xb63cfbcdL);
            zo.putArchiveEntry(ze);
            zo.write(testData);
            zo.closeArchiveEntry();
            zo.close();
            outputStream.close();
            outputStream = null;

            final ProcessBuilder pbChmod = new ProcessBuilder("chmod", "+x", testZip.getPath());
            pbChmod.redirectErrorStream(true);
            final Process processChmod = pbChmod.start();
            assertEquals(new String(IOUtils.toByteArray(processChmod.getInputStream())), 0, processChmod.waitFor());

            final ProcessBuilder pb = new ProcessBuilder(testZip.getPath());
            pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
            pb.directory(testZip.getParentFile());
            pb.redirectErrorStream(true);
            final Process process = pb.start();
            assertEquals(new String(IOUtils.toByteArray(process.getInputStream())), 0, process.waitFor());

            if (!extractedFile.exists()) {
                // fail if extracted file does not exist
                fail("Can not find the extracted file");
            }

            inputStream = Files.newInputStream(extractedFile.toPath());
            bytesRead = IOUtils.readFully(inputStream, buffer);
            assertEquals(testData.length, bytesRead);
            assertArrayEquals(testData, Arrays.copyOfRange(buffer, 0, bytesRead));
        } finally {
            if (outputStream != null) {
                outputStream.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }

            testZip.delete();
            extractedFile.delete();
            extractedFile.getParentFile().delete();
        }
    }

    private void multiByteReadConsistentlyReturnsMinusOneAtEof(final File file) throws Exception {
        final byte[] buf = new byte[2];
        try (ZipFile archive = new ZipFile(file)) {
            final ZipArchiveEntry e = archive.getEntries().nextElement();
            try (InputStream is = archive.getInputStream(e)) {
                IOUtils.toByteArray(is);
                assertEquals(-1, is.read(buf));
                assertEquals(-1, is.read(buf));
            }
        }
    }

    private void assertAllReadMethods(final byte[] expected, final ZipFile zipFile, final ZipArchiveEntry entry) {
        // simple IOUtil read
        try (InputStream stream = zf.getInputStream(entry)) {
            final byte[] full = IOUtils.toByteArray(stream);
            assertArrayEquals(expected, full);
        }
        catch (final IOException ex) {
            throw new RuntimeException(ex);
        }

        // big buffer at the beginning and then chunks by IOUtils read
        try (InputStream stream = zf.getInputStream(entry)) {
            byte[] full;
            final byte[] bytes = new byte[0x40000];
            final int read = stream.read(bytes);
            if (read < 0) {
                full = ByteUtils.EMPTY_BYTE_ARRAY;
            }
            else {
                full = readStreamRest(bytes, read, stream);
            }
            assertArrayEquals(expected, full);
        }
        catch (final IOException ex) {
            throw new RuntimeException(ex);
        }

        // small chunk / single byte and big buffer then
        try (InputStream stream = zf.getInputStream(entry)) {
            byte[] full;
            final int single = stream.read();
            if (single < 0) {
                full = ByteUtils.EMPTY_BYTE_ARRAY;
            }
            else {
                final byte[] big = new byte[0x40000];
                big[0] = (byte)single;
                final int read = stream.read(big, 1, big.length-1);
                if (read < 0) {
                    full = new byte[]{ (byte)single };
                }
                else {
                    full = readStreamRest(big, read+1, stream);
                }
            }
            assertArrayEquals(expected, full);
        }
        catch (final IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * Utility to append the rest of the stream to already read data.
     */
    private byte[] readStreamRest(final byte[] beginning, final int length, final InputStream stream) throws IOException {
        final byte[] rest = IOUtils.toByteArray(stream);
        final byte[] full = new byte[length+rest.length];
        System.arraycopy(beginning, 0, full, 0, length);
        System.arraycopy(rest, 0, full, length, rest.length);
        return full;
    }

    private long calculateCrc32(final byte[] content) {
        final CRC32 crc = new CRC32();
        crc.update(content);
        return crc.getValue();
    }

    /*
     * ordertest.zip has been handcrafted.
     *
     * It contains enough files so any random coincidence of
     * entries.keySet() and central directory order would be unlikely
     * - in fact testCDOrder fails in svn revision 920284.
     *
     * The central directory has ZipFile and ZipUtil swapped so
     * central directory order is different from entry data order.
     */
    private void readOrderTest() throws Exception {
        final File archive = getFile("ordertest.zip");
        zf = new ZipFile(archive);
    }

    private static void assertEntryName(final ArrayList<ZipArchiveEntry> entries,
                                        final int index,
                                        final String expectedName) {
        final ZipArchiveEntry ze = entries.get(index);
        assertEquals("src/main/java/org/apache/commons/compress/archivers/zip/"
                     + expectedName + ".java",
                     ze.getName());
    }

    private static void nameSource(final String archive, final String entry, final ZipArchiveEntry.NameSource expected) throws Exception {
        try (ZipFile zf = new ZipFile(getFile(archive))) {
            final ZipArchiveEntry ze = zf.getEntry(entry);
            assertEquals(entry, ze.getName());
            assertEquals(expected, ze.getNameSource());
        }
    }

    private void assertFileEqualsToEntry(final File fileToCompare, final ZipArchiveEntry entry, final ZipFile zipFile) throws IOException {
        final byte[] buffer = new byte[10240];
        final File tempFile = File.createTempFile("temp","txt");
        final OutputStream outputStream = Files.newOutputStream(tempFile.toPath());
        final InputStream inputStream = zipFile.getInputStream(entry);
        int readLen;
        while((readLen = inputStream.read(buffer)) > 0) {
            outputStream.write(buffer, 0, readLen);
        }

        outputStream.close();
        inputStream.close();

        assertFileEqualIgnoreEndOfLine(fileToCompare, tempFile);
    }

    private void assertFileEqualIgnoreEndOfLine(final File file1, final File file2) throws IOException {
        final List<String> linesOfFile1 = Files.readAllLines(Paths.get(file1.getCanonicalPath()), StandardCharsets.UTF_8);
        final List<String> linesOfFile2 = Files.readAllLines(Paths.get(file2.getCanonicalPath()), StandardCharsets.UTF_8);

        if(linesOfFile1.size() != linesOfFile2.size()) {
            fail("files not equal : " + file1.getName() + " , " + file2.getName());
        }

        String tempLineInFile1;
        String tempLineInFile2;
        for(int i = 0;i < linesOfFile1.size();i++) {
            tempLineInFile1 = linesOfFile1.get(i).replace("\r\n", "\n");
            tempLineInFile2 = linesOfFile2.get(i).replace("\r\n", "\n");
            Assert.assertEquals(tempLineInFile1, tempLineInFile2);
        }
    }
}
