| /* |
| * 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; |
| |
| import static org.apache.commons.compress.AbstractTestCase.getFile; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.io.BufferedInputStream; |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.lang.reflect.Field; |
| |
| import org.apache.commons.compress.archivers.arj.ArjArchiveInputStream; |
| import org.apache.commons.compress.archivers.cpio.CpioArchiveInputStream; |
| import org.apache.commons.compress.archivers.dump.DumpArchiveInputStream; |
| import org.apache.commons.compress.archivers.jar.JarArchiveInputStream; |
| import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; |
| import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; |
| import org.junit.Test; |
| |
| public class ArchiveStreamFactoryTest { |
| |
| private static final String UNKNOWN = "??"; |
| |
| /** |
| * see https://issues.apache.org/jira/browse/COMPRESS-171 |
| */ |
| @Test |
| public void shortTextFilesAreNoTARs() throws Exception { |
| try { |
| new ArchiveStreamFactory() |
| .createArchiveInputStream(new ByteArrayInputStream("This certainly is not a tar archive, really, no kidding".getBytes())); |
| fail("created an input stream for a non-archive"); |
| } catch (final ArchiveException ae) { |
| assertTrue(ae.getMessage().startsWith("No Archiver found")); |
| } |
| } |
| |
| /** |
| * see https://issues.apache.org/jira/browse/COMPRESS-191 |
| */ |
| @Test |
| public void aiffFilesAreNoTARs() throws Exception { |
| try (FileInputStream fis = new FileInputStream("src/test/resources/testAIFF.aif")) { |
| try (InputStream is = new BufferedInputStream(fis)) { |
| new ArchiveStreamFactory().createArchiveInputStream(is); |
| fail("created an input stream for a non-archive"); |
| } catch (final ArchiveException ae) { |
| assertTrue(ae.getMessage().startsWith("No Archiver found")); |
| } |
| } |
| } |
| |
| @Test |
| public void testCOMPRESS209() throws Exception { |
| try (FileInputStream fis = new FileInputStream("src/test/resources/testCompress209.doc")) { |
| try (InputStream bis = new BufferedInputStream(fis)) { |
| new ArchiveStreamFactory().createArchiveInputStream(bis); |
| fail("created an input stream for a non-archive"); |
| } catch (final ArchiveException ae) { |
| assertTrue(ae.getMessage().startsWith("No Archiver found")); |
| } |
| } |
| } |
| |
| @Test(expected = StreamingNotSupportedException.class) |
| public void cantRead7zFromStream() throws Exception { |
| new ArchiveStreamFactory() |
| .createArchiveInputStream(ArchiveStreamFactory.SEVEN_Z, |
| new ByteArrayInputStream(new byte[0])); |
| } |
| |
| @Test(expected = StreamingNotSupportedException.class) |
| public void cantWrite7zToStream() throws Exception { |
| new ArchiveStreamFactory() |
| .createArchiveOutputStream(ArchiveStreamFactory.SEVEN_Z, |
| new ByteArrayOutputStream()); |
| } |
| |
| /** |
| * Test case for |
| * <a href="https://issues.apache.org/jira/browse/COMPRESS-267" |
| * >COMPRESS-267</a>. |
| */ |
| @Test |
| public void detectsAndThrowsFor7z() throws Exception { |
| try (FileInputStream fis = new FileInputStream("src/test/resources/bla.7z")) { |
| try (InputStream bis = new BufferedInputStream(fis)) { |
| new ArchiveStreamFactory().createArchiveInputStream(bis); |
| fail("Expected a StreamingNotSupportedException"); |
| } catch (final StreamingNotSupportedException ex) { |
| assertEquals(ArchiveStreamFactory.SEVEN_Z, ex.getFormat()); |
| } |
| } |
| } |
| |
| /** |
| * Test case for |
| * <a href="https://issues.apache.org/jira/browse/COMPRESS-208" |
| * >COMPRESS-208</a>. |
| */ |
| @Test |
| public void skipsPK00Prefix() throws Exception { |
| try (FileInputStream fis = new FileInputStream("src/test/resources/COMPRESS-208.zip")) { |
| try (InputStream bis = new BufferedInputStream(fis)) { |
| try (ArchiveInputStream ais = new ArchiveStreamFactory().createArchiveInputStream(bis)) { |
| assertTrue(ais instanceof ZipArchiveInputStream); |
| } |
| } |
| } |
| } |
| |
| @Test |
| public void testEncodingCtor() { |
| ArchiveStreamFactory fac = new ArchiveStreamFactory(); |
| assertNull(fac.getEntryEncoding()); |
| fac = new ArchiveStreamFactory(null); |
| assertNull(fac.getEntryEncoding()); |
| fac = new ArchiveStreamFactory("UTF-8"); |
| assertEquals("UTF-8", fac.getEntryEncoding()); |
| } |
| |
| @Test |
| @SuppressWarnings("deprecation") |
| public void testEncodingDeprecated() { |
| ArchiveStreamFactory fac = new ArchiveStreamFactory(); |
| assertNull(fac.getEntryEncoding()); |
| fac.setEntryEncoding("UTF-8"); |
| assertEquals("UTF-8", fac.getEntryEncoding()); |
| fac.setEntryEncoding("US_ASCII"); |
| assertEquals("US_ASCII", fac.getEntryEncoding()); |
| fac = new ArchiveStreamFactory("UTF-8"); |
| assertEquals("UTF-8", fac.getEntryEncoding()); |
| try { |
| fac.setEntryEncoding("US_ASCII"); |
| fail("Expected IllegalStateException"); |
| } catch (final IllegalStateException ise) { |
| // expected |
| } |
| } |
| |
| static class TestData { |
| final String testFile; |
| final String expectedEncoding; |
| final ArchiveStreamFactory fac; |
| final String fieldName; |
| final String type; |
| final boolean hasOutputStream; |
| TestData(final String testFile, final String type, final boolean hasOut, final String expectedEncoding, final ArchiveStreamFactory fac, final String fieldName) { |
| this.testFile = testFile; |
| this.expectedEncoding = expectedEncoding; |
| this.fac = fac; |
| this.fieldName = fieldName; |
| this.type = type; |
| this.hasOutputStream = hasOut; |
| } |
| } |
| |
| @SuppressWarnings("deprecation") // test of deprecated method |
| static ArchiveStreamFactory getFactory(final String entryEncoding) { |
| final ArchiveStreamFactory fac = new ArchiveStreamFactory(); |
| fac.setEntryEncoding(entryEncoding); |
| return fac; |
| } |
| // The different factory types |
| private static final ArchiveStreamFactory FACTORY = new ArchiveStreamFactory(); |
| private static final ArchiveStreamFactory FACTORY_UTF8 = new ArchiveStreamFactory("UTF-8"); |
| private static final ArchiveStreamFactory FACTORY_ASCII = new ArchiveStreamFactory("ASCII"); |
| private static final ArchiveStreamFactory FACTORY_SET_UTF8 = getFactory("UTF-8"); |
| private static final ArchiveStreamFactory FACTORY_SET_ASCII = getFactory("ASCII"); |
| |
| // Default encoding if none is provided (not even null) |
| // The test currently assumes that the output default is the same as the input default |
| private static final String ARJ_DEFAULT; |
| private static final String DUMP_DEFAULT; |
| |
| private static final String ZIP_DEFAULT = getField(new ZipArchiveInputStream(null),"encoding"); |
| private static final String CPIO_DEFAULT = getField(new CpioArchiveInputStream(null),"encoding"); |
| private static final String TAR_DEFAULT = getField(new TarArchiveInputStream(null),"encoding"); |
| private static final String JAR_DEFAULT = getField(new JarArchiveInputStream(null),"encoding"); |
| |
| static { |
| String dflt; |
| dflt = UNKNOWN; |
| try { |
| dflt = getField(new ArjArchiveInputStream(new FileInputStream(getFile("bla.arj"))), "charsetName"); |
| } catch (final Exception e) { |
| e.printStackTrace(); |
| } |
| ARJ_DEFAULT = dflt; |
| dflt = UNKNOWN; |
| try { |
| dflt = getField(new DumpArchiveInputStream(new FileInputStream(getFile("bla.dump"))), "encoding"); |
| } catch (final Exception e) { |
| e.printStackTrace(); |
| } |
| DUMP_DEFAULT = dflt; |
| } |
| |
| static final TestData[] TESTS = { |
| new TestData("bla.arj", ArchiveStreamFactory.ARJ, false, ARJ_DEFAULT, FACTORY, "charsetName"), |
| new TestData("bla.arj", ArchiveStreamFactory.ARJ, false, "UTF-8", FACTORY_UTF8, "charsetName"), |
| new TestData("bla.arj", ArchiveStreamFactory.ARJ, false, "ASCII", FACTORY_ASCII, "charsetName"), |
| new TestData("bla.arj", ArchiveStreamFactory.ARJ, false, "UTF-8", FACTORY_SET_UTF8, "charsetName"), |
| new TestData("bla.arj", ArchiveStreamFactory.ARJ, false, "ASCII", FACTORY_SET_ASCII, "charsetName"), |
| |
| new TestData("bla.cpio", ArchiveStreamFactory.CPIO, true, CPIO_DEFAULT, FACTORY, "encoding"), |
| new TestData("bla.cpio", ArchiveStreamFactory.CPIO, true, "UTF-8", FACTORY_UTF8, "encoding"), |
| new TestData("bla.cpio", ArchiveStreamFactory.CPIO, true, "ASCII", FACTORY_ASCII, "encoding"), |
| new TestData("bla.cpio", ArchiveStreamFactory.CPIO, true, "UTF-8", FACTORY_SET_UTF8, "encoding"), |
| new TestData("bla.cpio", ArchiveStreamFactory.CPIO, true, "ASCII", FACTORY_SET_ASCII, "encoding"), |
| |
| new TestData("bla.dump", ArchiveStreamFactory.DUMP, false, DUMP_DEFAULT, FACTORY, "encoding"), |
| new TestData("bla.dump", ArchiveStreamFactory.DUMP, false, "UTF-8", FACTORY_UTF8, "encoding"), |
| new TestData("bla.dump", ArchiveStreamFactory.DUMP, false, "ASCII", FACTORY_ASCII, "encoding"), |
| new TestData("bla.dump", ArchiveStreamFactory.DUMP, false, "UTF-8", FACTORY_SET_UTF8, "encoding"), |
| new TestData("bla.dump", ArchiveStreamFactory.DUMP, false, "ASCII", FACTORY_SET_ASCII, "encoding"), |
| |
| new TestData("bla.tar", ArchiveStreamFactory.TAR, true, TAR_DEFAULT, FACTORY, "encoding"), |
| new TestData("bla.tar", ArchiveStreamFactory.TAR, true, "UTF-8", FACTORY_UTF8, "encoding"), |
| new TestData("bla.tar", ArchiveStreamFactory.TAR, true, "ASCII", FACTORY_ASCII, "encoding"), |
| new TestData("bla.tar", ArchiveStreamFactory.TAR, true, "UTF-8", FACTORY_SET_UTF8, "encoding"), |
| new TestData("bla.tar", ArchiveStreamFactory.TAR, true, "ASCII", FACTORY_SET_ASCII, "encoding"), |
| |
| new TestData("bla.jar", ArchiveStreamFactory.JAR, true, JAR_DEFAULT, FACTORY, "encoding"), |
| new TestData("bla.jar", ArchiveStreamFactory.JAR, true, "UTF-8", FACTORY_UTF8, "encoding"), |
| new TestData("bla.jar", ArchiveStreamFactory.JAR, true, "ASCII", FACTORY_ASCII, "encoding"), |
| new TestData("bla.jar", ArchiveStreamFactory.JAR, true, "UTF-8", FACTORY_SET_UTF8, "encoding"), |
| new TestData("bla.jar", ArchiveStreamFactory.JAR, true, "ASCII", FACTORY_SET_ASCII, "encoding"), |
| |
| new TestData("bla.zip", ArchiveStreamFactory.ZIP, true, ZIP_DEFAULT, FACTORY, "encoding"), |
| new TestData("bla.zip", ArchiveStreamFactory.ZIP, true, "UTF-8", FACTORY_UTF8, "encoding"), |
| new TestData("bla.zip", ArchiveStreamFactory.ZIP, true, "ASCII", FACTORY_ASCII, "encoding"), |
| new TestData("bla.zip", ArchiveStreamFactory.ZIP, true, "UTF-8", FACTORY_SET_UTF8, "encoding"), |
| new TestData("bla.zip", ArchiveStreamFactory.ZIP, true, "ASCII", FACTORY_SET_ASCII, "encoding"), |
| }; |
| |
| @Test |
| public void testEncodingInputStreamAutodetect() throws Exception { |
| int failed = 0; |
| for(int i = 1; i <= TESTS.length; i++) { |
| final TestData test = TESTS[i-1]; |
| final ArchiveInputStream ais = getInputStreamFor(test.testFile, test.fac); |
| final String field = getField(ais,test.fieldName); |
| if (!eq(test.expectedEncoding,field)) { |
| System.out.println("Failed test " + i + ". expected: " + test.expectedEncoding + " actual: " + field + " type: " + test.type); |
| failed++; |
| } |
| } |
| if (failed > 0) { |
| fail("Tests failed: " + failed); |
| } |
| } |
| |
| @Test |
| public void testEncodingInputStream() throws Exception { |
| int failed = 0; |
| for(int i = 1; i <= TESTS.length; i++) { |
| final TestData test = TESTS[i-1]; |
| final ArchiveInputStream ais = getInputStreamFor(test.type, test.testFile, test.fac); |
| final String field = getField(ais,test.fieldName); |
| if (!eq(test.expectedEncoding,field)) { |
| System.out.println("Failed test " + i + ". expected: " + test.expectedEncoding + " actual: " + field + " type: " + test.type); |
| failed++; |
| } |
| } |
| if (failed > 0) { |
| fail("Tests failed: " + failed); |
| } |
| } |
| |
| @Test |
| public void testEncodingOutputStream() throws Exception { |
| int failed = 0; |
| for(int i = 1; i <= TESTS.length; i++) { |
| final TestData test = TESTS[i-1]; |
| if (test.hasOutputStream) { |
| final ArchiveOutputStream ais = getOutputStreamFor(test.type, test.fac); |
| final String field = getField(ais, test.fieldName); |
| if (!eq(test.expectedEncoding, field)) { |
| System.out.println("Failed test " + i + ". expected: " + test.expectedEncoding + " actual: " + field + " type: " + test.type); |
| failed++; |
| } |
| } |
| } |
| if (failed > 0) { |
| fail("Tests failed: " + failed); |
| } |
| } |
| |
| // equals allowing null |
| private static boolean eq(final String exp, final String act) { |
| if (exp == null) { |
| return act == null; |
| } |
| return exp.equals(act); |
| } |
| |
| private static String getField(final Object instance, final String name) { |
| final Class<?> cls = instance.getClass(); |
| Field fld; |
| try { |
| fld = cls.getDeclaredField(name); |
| } catch (final NoSuchFieldException nsfe) { |
| try { |
| fld = cls.getSuperclass().getDeclaredField(name); |
| } catch (final NoSuchFieldException e) { |
| System.out.println("Cannot find " + name + " in class " + instance.getClass().getSimpleName()); |
| return UNKNOWN; |
| } |
| } |
| final boolean isAccessible = fld.isAccessible(); |
| try { |
| if (!isAccessible) { |
| fld.setAccessible(true); |
| } |
| final Object object = fld.get(instance); |
| if (object instanceof String || object == null) { |
| return (String) object; |
| } |
| System.out.println("Wrong type: " + object.getClass().getCanonicalName() + " for " + name + " in class " + instance.getClass().getSimpleName()); |
| return UNKNOWN; |
| } catch (final Exception e) { |
| e.printStackTrace(); |
| return UNKNOWN; |
| } finally { |
| if (!isAccessible) { |
| fld.setAccessible(isAccessible); |
| } |
| } |
| } |
| |
| private ArchiveInputStream getInputStreamFor(final String resource, final ArchiveStreamFactory factory) |
| throws IOException, ArchiveException { |
| return factory.createArchiveInputStream( |
| new BufferedInputStream(new FileInputStream( |
| getFile(resource)))); |
| } |
| |
| private ArchiveInputStream getInputStreamFor(final String type, final String resource, final ArchiveStreamFactory factory) |
| throws IOException, ArchiveException { |
| return factory.createArchiveInputStream( |
| type, |
| new BufferedInputStream(new FileInputStream( |
| getFile(resource)))); |
| } |
| |
| private ArchiveOutputStream getOutputStreamFor(final String type, final ArchiveStreamFactory factory) |
| throws IOException, ArchiveException { |
| return factory.createArchiveOutputStream(type, new ByteArrayOutputStream()); |
| } |
| } |