Java zip file path

Java ZipFile Tutorial

The Java ZipFile class ( java.util.zip.ZipFile ) can be used to read files from a ZIP file. The ZipFile class is actually quite easy to use. This tutorial will show you how to use the ZipFile class.

Creating a ZipFile Instance

In order to use the Java ZipFile class you must first create a ZipFile instance. Here is an example of creating a Java ZipFile instance:

ZipFile zipFile = new ZipFile("d:\\data\\myzipfile.zip");

As you can see, the ZipFile class takes a single parameter in its constructor. This parameter is the path to the ZIP file to open.

Getting a ZipEntry

Each file in the ZIP file is represented by a ZipEntry ( java.util.zip.ZipEntry ). To extract a file from the ZIP file you can call the method getEntry() method on the ZipFile class. Here is an example of calling getEntry() :

ZipEntry zipEntry = zipFile.getEntry("file1.txt");

This example gets a ZipEntry representing the file file1.txt which is contained in the ZIP file.

If the file you want to extract is located in one or more directories inside the ZIP file, include the directories in the path, like this:

ZipEntry zipEntry = zipFile.getEntry("dir/subdir/file1.txt");

Reading the File

To read the file represented by a ZipEntry you can obtain an InputStream from the ZipFile like this:

ZipEntry zipEntry = zipFile.getEntry("dir/subdir/file1.txt"); InputStream inputStream = this.zipFile.getInputStream(zipEntry);

The InputStream obtained from the getInputStream() of the ZipFile class can be read like any other Java InputStream .

Listing All Entries in a ZipFile

You can list all entries contained in a ZipFile using the entries() method. Here is an example of calling the ZipFile entries() :

Enumeration entries = zipFile.entries();

You can iterate the Enumeration returned by the entries() method like this:

Enumeration entries = zipFile.entries(); while(entries.hasMoreElements()) < ZipEntry entry = entries.nextElement(); if(entry.isDirectory())< System.out.println("dir : " + entry.getName()); >else < System.out.println("file : " + entry.getName()); >>

Unzipping All Entries in ZipFile

There is no easy way to unzip all entries of a ZipFile . You will have to do that yourself. To make it easier for you, I will show you an example of the code needed to unzip all entries in a Java ZipFile . Here is the code:

import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; public class FileUnzipper < private String zipFileDir = null; private String zipFileName = null; private String unzipDir = null; public FileUnzipper(String zipFileDir, String zipFileName, String unzipDir) < this.zipFileDir = zipFileDir; this.zipFileName = zipFileName; this.unzipDir = unzipDir; >public void unzip() < String zipFilePath = this.zipFileDir + File.separator + this.zipFileName; try< System.out.println("zipFilePath = " + zipFilePath); ZipFile zipFile = new ZipFile(zipFilePath); Enumerationentries = zipFile.entries(); while(entries.hasMoreElements()) < ZipEntry entry = entries.nextElement(); if(entry.isDirectory())< System.out.print("dir : " + entry.getName()); String destPath = this.unzipDir + File.separator + entry.getName(); System.out.println(" =>" + destPath); //todo check destPath for Zip Slip problem - see further down this page. File file = new File(destPath); file.mkdirs(); > else < String destPath = this.unzipDir + File.separator + entry.getName(); //todo check destPath for Zip Slip problem - see further down this page. try(InputStream inputStream = zipFile.getInputStream(entry); FileOutputStream outputStream = new FileOutputStream(destPath); )< int data = inputStream.read(); while(data != -1)< outputStream.write(data); data = inputStream.read(); >> System.out.println("file : " + entry.getName() + " => " + destPath); > > > catch(IOException e) < throw new RuntimeException("Error unzipping file " + zipFilePath, e); >> private boolean isValidDestPath(String destPath) < // validate the destination path of a ZipFile entry, // and return true or false telling if it's valid or not. >>

The Zip Slip Problem

The example of unzipping all entries of a ZipFile into a directory is vulnerable to the Zip Slip attack. The Zip Slip attack consists of adding entries to a ZipFile that contains relative file paths with one or more /.. sections in the path. This way the final path of the file could end up being outside the directory into which the ZipFile is requested unzipped to. Let’s look at an example:

Читайте также:  Csrf token django html

You request a ZipFile to be unzipped to the directory /apps/myapp/data/unzipped-file . An entry in the ZipFile has the relative path ../../../../etc/hosts . The final path of that entry becomes: /apps/myapp/data/unzipped-file/../../../../etc/hosts which is equivalent of /etc/hosts .

Unzipping this file could potentially overwrite hour hosts file (on a Linux OS), enabling the attacker to point e.g. www.facebook.com to an IP address of their own choice. The next time you try to access Facebook from that computer, it won’t be the real Facebook you are accessing, but the attacker’s spoofed version. Once you login, the attacker now has your username and password, and your Facebook account can be hacked.

The way to avoid a Zip Slip attack is the check the final output path to see if it is outside the target directory. Here is how you can do that:

Path destPath = Paths.get(destPath); Path destPathNormalized = destPath.normalize(); //remove ../../ etc. boolean isWithinTargetDir = destPathNormalized.toString().startsWith(targetDir + File.separator);

What you do if the ZipFile entry target path is outside the target directory is up to you to decide. You could throw an exception, or just ignore that file, and maybe write out to the console or log that this file was ignored because of invalid entry path.

Here is an ZipFile unzip example that throws an exception if the target path of an entry is invalid:

import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; public class FileUnzipper < private String zipFileDir = null; private String zipFileName = null; private String unzipDir = null; public FileUnzipper(String zipFileDir, String zipFileName, String unzipDir) < this.zipFileDir = zipFileDir; this.zipFileName = zipFileName; this.unzipDir = unzipDir; >public void unzip() < String zipFilePath = this.zipFileDir + File.separator + this.zipFileName; try< System.out.println("zipFilePath = " + zipFilePath); ZipFile zipFile = new ZipFile(zipFilePath); Enumerationentries = zipFile.entries(); while(entries.hasMoreElements()) < ZipEntry entry = entries.nextElement(); if(entry.isDirectory())< System.out.print("dir : " + entry.getName()); String destPath = this.unzipDir + File.separator + entry.getName(); System.out.println(" =>" + destPath); if(! isValidDestPath(zipFileDir, destPath)) < throw new IOException("Final directory output path is invalid: " + destPath); >File file = new File(destPath); file.mkdirs(); > else < String destPath = this.unzipDir + File.separator + entry.getName(); if(! isValidDestPath(zipFileDir, destPath))< throw new IOException("Final file output path is invalid: " + destPath); >try(InputStream inputStream = zipFile.getInputStream(entry); FileOutputStream outputStream = new FileOutputStream(destPath); ) < int data = inputStream.read(); while(data != -1)< outputStream.write(data); data = inputStream.read(); >> System.out.println("file : " + entry.getName() + " => " + destPath); > > > catch(IOException e) < throw new RuntimeException("Error unzipping file " + zipFilePath, e); >> private boolean isValidDestPath(String targetDir, String destPathStr) < // validate the destination path of a ZipFile entry, // and return true or false telling if it's valid or not. Path destPath = Paths.get(destPathStr); Path destPathNormalized = destPath.normalize(); //remove ../../ etc. return destPathNormalized.toString().startsWith(targetDir + File.separator); >>

Источник

Читайте также:  Html and css academy

Class ZipFile

Unless otherwise noted, passing a null argument to a constructor or method in this class will cause a NullPointerException to be thrown.

Field Summary

Constructor Summary

Method Summary

Methods declared in class java.lang.Object

Field Details

OPEN_READ

OPEN_DELETE

Mode flag to open a zip file and mark it for deletion. The file will be deleted some time between the moment that it is opened and the moment that it is closed, but its contents will remain accessible via the ZipFile object until either the close method is invoked or the virtual machine exits.

LOCSIG

EXTSIG

CENSIG

ENDSIG

LOCHDR

EXTHDR

CENHDR

ENDHDR

LOCVER

LOCFLG

LOCHOW

LOCTIM

LOCCRC

LOCSIZ

LOCLEN

LOCNAM

LOCEXT

EXTCRC

EXTSIZ

EXTLEN

CENVEM

CENVER

CENFLG

CENHOW

CENTIM

CENCRC

CENSIZ

CENLEN

CENNAM

CENEXT

CENCOM

CENDSK

CENATT

CENATX

CENOFF

ENDSUB

ENDTOT

ENDSIZ

ENDOFF

ENDCOM

Constructor Details

ZipFile

Opens a zip file for reading. First, if there is a security manager, its checkRead method is called with the name argument as its argument to ensure the read is allowed. The UTF-8 charset is used to decode the entry names and comments.

ZipFile

Opens a new ZipFile to read from the specified File object in the specified mode. The mode argument must be either OPEN_READ or OPEN_READ | OPEN_DELETE . First, if there is a security manager, its checkRead method is called with the name argument as its argument to ensure the read is allowed. The UTF-8 charset is used to decode the entry names and comments

ZipFile

Opens a ZIP file for reading given the specified File object. The UTF-8 charset is used to decode the entry names and comments.

Читайте также:  Java дата по гринвичу

ZipFile

Opens a new ZipFile to read from the specified File object in the specified mode. The mode argument must be either OPEN_READ or OPEN_READ | OPEN_DELETE . First, if there is a security manager, its checkRead method is called with the name argument as its argument to ensure the read is allowed.

ZipFile

Opens a zip file for reading. First, if there is a security manager, its checkRead method is called with the name argument as its argument to ensure the read is allowed.

ZipFile

Method Details

getComment

getEntry

getInputStream

Returns an input stream for reading the contents of the specified zip file entry. Closing this ZIP file will, in turn, close all input streams that have been returned by invocations of this method.

getName

entries

stream

Returns an ordered Stream over the ZIP file entries. Entries appear in the Stream in the order they appear in the central directory of the ZIP file.

size

close

Closes the ZIP file. Closing this ZIP file will close all of the input streams previously returned by invocations of the getInputStream method.

Report a bug or suggest an enhancement
For further API reference and developer documentation see the Java SE Documentation, which contains more detailed, developer-targeted descriptions with conceptual overviews, definitions of terms, workarounds, and working code examples. Other versions.
Java is a trademark or registered trademark of Oracle and/or its affiliates in the US and other countries.
Copyright © 1993, 2023, Oracle and/or its affiliates, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
All rights reserved. Use is subject to license terms and the documentation redistribution policy.

Источник

Оцените статью