All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.plexus.archiver.zip.AbstractZipUnArchiver Maven / Gradle / Ivy

/**
 *
 * Copyright 2004 The Apache Software Foundation
 *
 * Licensed 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.codehaus.plexus.archiver.zip;

import javax.annotation.Nonnull;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.Enumeration;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.input.BoundedInputStream;
import org.apache.commons.io.input.CountingInputStream;
import org.codehaus.plexus.archiver.AbstractUnArchiver;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.components.io.resources.PlexusIoResource;

/**
 * @author Emmanuel Venisse
 */
public abstract class AbstractZipUnArchiver extends AbstractUnArchiver {

    private static final String NATIVE_ENCODING = "native-encoding";

    private String encoding = "UTF8";

    private long maxOutputSize = Long.MAX_VALUE;

    public AbstractZipUnArchiver() {}

    public AbstractZipUnArchiver(final File sourceFile) {
        super(sourceFile);
    }

    /**
     * Sets the encoding to assume for file names and comments.
     * 

* Set to native-encoding if you want your platform's native encoding, defaults to UTF8. *

*/ public void setEncoding(String encoding) { if (NATIVE_ENCODING.equals(encoding)) { encoding = null; } this.encoding = encoding; } /** * Set maximum allowed size of the produced output. * * It may be used as a protection against zip bombs. * * @param maxOutputSize max size of the produced output, in bytes. Must be greater than 0 * @throws IllegalArgumentException if specified output size is less or equal to 0 */ public void setMaxOutputSize(long maxOutputSize) { if (maxOutputSize <= 0) { throw new IllegalArgumentException("Invalid max output size specified: " + maxOutputSize); } this.maxOutputSize = maxOutputSize; } private static class ZipEntryFileInfo implements PlexusIoResource { private final org.apache.commons.compress.archivers.zip.ZipFile zipFile; private final ZipArchiveEntry zipEntry; ZipEntryFileInfo( final org.apache.commons.compress.archivers.zip.ZipFile zipFile, final ZipArchiveEntry zipEntry) { this.zipFile = zipFile; this.zipEntry = zipEntry; } public String getName() { return zipEntry.getName(); } @Override public boolean isDirectory() { return zipEntry.isDirectory(); } @Override public boolean isFile() { return !zipEntry.isDirectory() && !zipEntry.isUnixSymlink(); } @Override public boolean isSymbolicLink() { return zipEntry.isUnixSymlink(); } @Nonnull @Override public InputStream getContents() throws IOException { return zipFile.getInputStream(zipEntry); } @Override public long getLastModified() { final long l = zipEntry.getTime(); return l == 0 ? PlexusIoResource.UNKNOWN_MODIFICATION_DATE : l; } @Override public long getSize() { final long l = zipEntry.getSize(); return l == -1 ? PlexusIoResource.UNKNOWN_RESOURCE_SIZE : l; } @Override public URL getURL() throws IOException { return null; } @Override public boolean isExisting() { return true; } } @Override protected void execute() throws ArchiverException { execute("", getDestDirectory()); } private String resolveSymlink(ZipFile zf, ZipArchiveEntry ze) throws IOException { if (ze.isUnixSymlink()) { return zf.getUnixSymlink(ze); } else { return null; } } @Override protected void execute(final String path, final File outputDirectory) throws ArchiverException { getLogger().debug("Expanding: " + getSourceFile() + " into " + outputDirectory); try (ZipFile zipFile = new ZipFile(getSourceFile(), encoding, true)) { long remainingSpace = maxOutputSize; final Enumeration e = zipFile.getEntriesInPhysicalOrder(); while (e.hasMoreElements()) { final ZipArchiveEntry ze = e.nextElement(); final ZipEntryFileInfo fileInfo = new ZipEntryFileInfo(zipFile, ze); if (!isSelected(ze.getName(), fileInfo)) { continue; } if (ze.getName().startsWith(path)) { try (InputStream in = zipFile.getInputStream(ze)) { BoundedInputStream bis = new BoundedInputStream(in, remainingSpace + 1); CountingInputStream cis = new CountingInputStream(bis); extractFile( getSourceFile(), outputDirectory, cis, ze.getName(), new Date(ze.getTime()), ze.isDirectory(), ze.getUnixMode() != 0 ? ze.getUnixMode() : null, resolveSymlink(zipFile, ze), getFileMappers()); remainingSpace -= cis.getByteCount(); if (remainingSpace < 0) { throw new ArchiverException("Maximum output size limit reached"); } } } } getLogger().debug("expand complete"); } catch (final IOException ioe) { throw new ArchiverException( "Error while expanding " + getSourceFile().getAbsolutePath(), ioe); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy