Here is my code:
String mixtapefilename = "testzip.zip";
String zipname = mixtapefilename;
String path = Environment.getExternalStorageDirectory() + "/download/";
unpackZip(path, zipname);
private boolean unpackZip(String path, String zipname)
{
InputStream is;
ZipInputStream zis;
try
{
is = new FileInputStream(path + zipname);
zis = new ZipInputStream(new BufferedInputStream(is));
ZipEntry ze;
while ((ze = zis.getNextEntry()) != null)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int count;
// zapis do souboru
String filename = ze.getName();
FileOutputStream fout = new FileOutputStream(path + filename);
// cteni zipu a zapis
while ((count = zis.read(buffer)) != -1)
{
baos.write(buffer, 0, count);
byte[] bytes = baos.toByteArray();
fout.write(bytes);
baos.reset();
}
fout.close();
zis.closeEntry();
}
zis.close();
Toast toast = Toast.makeText(getApplicationContext(),"Download Complete", Toast.LENGTH_LONG);
toast.show();
}
catch(IOException e)
{
ProgressDialog dialog;
dialog = new ProgressDialog(Download.this);
dialog.setMessage(e.toString());
dialog.show();
return false;
}
return true;
}
And my error is: /mnt/sdcard/download/testzip/testzip.mp3 (No such file or directory)
So it can't find my MP3? But it is supposed to be unzipping my mp3, do I somehow need to create the directories first?
Yes, you have to create necessary files and directory first before you do unzipping. I believe your sd card already have download directory in it. If so, try this code below. Feel free to adjust to your need.
private boolean unpackZip(String path, String zipname){
InputStream is;
ZipInputStream zis;
try
{
is = new FileInputStream(path + zipname);
zis = new ZipInputStream(new BufferedInputStream(is));
ZipEntry ze;
while ((ze = zis.getNextEntry()) != null)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int count;
// zapis do souboru
String filename = ze.getName();
File innerFile = new File(path, fileName);
if (ze.isDirectory()) {
Log.d("DEBUG", "The Entry is a directory..");
innerFile.mkdirs();
} else {
FileOutputStream fout = new FileOutputStream(path + filename);
// cteni zipu a zapis
while ((count = zis.read(buffer)) != -1)
{
baos.write(buffer, 0, count);
byte[] bytes = baos.toByteArray();
fout.write(bytes);
baos.reset();
}
fout.close();
zis.closeEntry();
}
zis.close();
Toast toast = Toast.makeText(getApplicationContext(),"Download Complete", Toast.LENGTH_LONG);
toast.show();
}
}
catch(IOException e)
{
ProgressDialog dialog;
dialog = new ProgressDialog(Download.this);
dialog.setMessage(e.toString());
dialog.show();
return false;
}
return true;
}
Related
I am getting the "Zip Path Traversal Vulnerability" alert in Google Play Console.
I followed official Google docs (https://support.google.com/faqs/answer/9294009) to fix it but the alert is still there.
Here is the code that handles unzipping. I have even tested using a zip file that has the vulnerability described and the exception is raised as expected.
What am I missing?
private boolean unpackZip(File zipFile, File outputDirectory, IOnResult<Integer> progress) {
InputStream is;
ZipInputStream zis;
ZipInputStream zisCount;
try {
int totalEntries = 0;
int entryCount = 0;
String filename;
ZipEntry ze;
is = new FileInputStream(zipFile);
zisCount = new ZipInputStream(new BufferedInputStream(is));
while ((ze = zisCount.getNextEntry()) != null) {
// Fixing a Zip Path Traversal Vulnerability
// (https://support.google.com/faqs/answer/9294009)
filename = ze.getName();
File targetFile = new File(outputDirectory, filename);
String targetPath = targetFile.getCanonicalPath();
if (!targetPath.startsWith(outputDirectory.getCanonicalPath())) {
throw new SecurityException("Archive security error");
}
// -----------------------------------------------------------------------------
totalEntries++;
zisCount.closeEntry();
}
zisCount.close();
is = new FileInputStream(zipFile);
zis = new ZipInputStream(new BufferedInputStream(is));
byte[] buffer = new byte[1024];
int count;
while ((ze = zis.getNextEntry()) != null) {
filename = ze.getName();
// Fixing a Zip Path Traversal Vulnerability (https://support.google.com/faqs/answer/9294009)
File targetFile = new File(outputDirectory, filename);
String targetPath = targetFile.getCanonicalPath();
if (!targetPath.startsWith(outputDirectory.getCanonicalPath())) {
throw new SecurityException("Archive security error");
}
// Need to create directories if not exists, or
// it will generate an Exception...
if (ze.isDirectory()) {
File fmd = new File(outputDirectory, filename);
fmd.mkdirs();
continue;
}
File outputFile = new File(outputDirectory, filename);
for( File parentFile = outputFile.getParentFile(); !parentFile.exists(); parentFile = parentFile.getParentFile() )
{
parentFile.mkdir();
}
FileOutputStream fout = new FileOutputStream(outputFile);
Log.d(TAG, "unzipped " + filename);
while ((count = zis.read(buffer)) != -1) {
fout.write(buffer, 0, count);
}
fout.close();
zis.closeEntry();
entryCount++;
}
zis.close();
} catch (IOException | SecurityException e) {
Log.e(TAG, "unpackZip", e);
return false;
}
return true;
}
I want to unzip to zip file in same directory,When I try below code it unzipped below target directory not in target folder,how can I unzipped all files in target directory in android
public static void unzip(String zipFilePath, String destDir) {
BufferedOutputStream bufferedOutputStream = null;
FileInputStream fileInputStream;
File dest_file = new File(destDir);
//dest_file.mkdirs(); // creates if destination directory not existed
try {
fileInputStream = new FileInputStream(zipFilePath);
ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(fileInputStream));
ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
String zipEntryName = zipEntry.getName();
File file = new File(destDir + zipEntryName);
if (file.exists()) {
} else if (zipEntry.isDirectory()) {
file.mkdirs();
} else {
byte buffer[] = new byte[1024];
FileOutputStream fileOutputStream = new FileOutputStream(file);
bufferedOutputStream = new BufferedOutputStream(fileOutputStream, 1024);
int count;
while ((count = zipInputStream.read(buffer, 0, 1024)) != -1) {
bufferedOutputStream.write(buffer, 0, count);
}
bufferedOutputStream.flush();
bufferedOutputStream.close();
}
}
zipInputStream.close();
} catch (Exception e) {
Log.e("Decompress", "unzip", e);
}
}
I call unzip File
String source = /storage/emulated/0/Android/data/com.kocsistem.pixageoneandroid/files/Contents/widgetContent + "/" + "123.zip";
String target = /storage/emulated/0/Android/data/com.kocsistem.pixageoneandroid/files/Contents/widgetContent ;
Utils.unzip(source, target);
I am unziping a file based in the official documentation and some examples. My current implementation unzip the file in the same directory where is the zip file. I'd like to unzip to a specific directory in my device. How can I do this? The ZipInputStream allow this feature or do I have to unzip and then move the files to the desired folder?
This is my code:
public static boolean unpackZip(String path, String zipname) {
InputStream is;
ZipInputStream zis;
try {
String filename;
is = new FileInputStream(path + zipname);
zis = new ZipInputStream(new BufferedInputStream(is));
ZipEntry ze;
byte[] buffer = new byte[1024];
int count;
while ((ze = zis.getNextEntry()) != null) {
filename = ze.getName();
if (ze.isDirectory()) {
File fmd = new File(path + filename);
fmd.mkdirs();
continue;
}
FileOutputStream fout = new FileOutputStream(path + filename);
while ((count = zis.read(buffer)) != -1) {
fout.write(buffer, 0, count);
}
fout.close();
zis.closeEntry();
}
zis.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
You need to create the folder by splitting the string:
if (filename.contains("/")){
String[] folders = filename.split("/");
for (String item : folders)
{
File fmd = new File(path + item);
if (!item.contains(".") && !fmd.exists()){
fmd.mkdirs();
Log.d("created folder", item);
}
}
}
FULL CODE:
public static boolean unpackZip(String path, String zipname) {
InputStream is;
ZipInputStream zis;
try {
String filename;
is = new FileInputStream(path + zipname);
zis = new ZipInputStream(new BufferedInputStream(is));
ZipEntry ze;
byte[] buffer = new byte[1024];
int count;
while ((ze = zis.getNextEntry()) != null) {
filename = ze.getName();
if (ze.isDirectory()) {
File fmd = new File(path + filename);
fmd.mkdirs();
continue;
}
//ADD THIS//
if (filename.contains("/")){
String[] folders = filename.split("/");
for (String item : folders)
{
File fmd = new File(path + item);
if (!item.contains(".") && !fmd.exists()){
fmd.mkdirs();
Log.d("created folder", item);
}
}
}
FileOutputStream fout = new FileOutputStream(path + filename);
while ((count = zis.read(buffer)) != -1) {
fout.write(buffer, 0, count);
}
fout.close();
zis.closeEntry();
}
zis.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
Where you open the file as in File fmd = new File(path + filename); and FileOutputStream fout = new FileOutputStream(path + filename); you can simply prepend the target directory as path + filename is simply the path to the file. I'm not sure what you are passing in as path in this case, I assume the path to the zip file, if you wish to extract elsewhere you need to pass in another variable with the target. Something like:
public static boolean unpackZip(String path, String zipname, String outputPath) {
InputStream is;
ZipInputStream zis;
try {
String filename;
is = new FileInputStream(path + zipname);
zis = new ZipInputStream(new BufferedInputStream(is));
ZipEntry ze;
byte[] buffer = new byte[1024];
int count;
while ((ze = zis.getNextEntry()) != null) {
filename = ze.getName();
if (ze.isDirectory()) {
File fmd = new File(outputPath + filename);
fmd.mkdirs();
continue;
}
FileOutputStream fout = new FileOutputStream(outputPath + filename);
while ((count = zis.read(buffer)) != -1) {
fout.write(buffer, 0, count);
}
fout.close();
zis.closeEntry();
}
zis.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
Specify a target directory as a parameter. Apart this, your code seems ok.
public static boolean unpackZip(String path, String zipname, String targetDirectory) {
InputStream is;
ZipInputStream zis;
try {
String filename;
is = new FileInputStream(path + zipname);
zis = new ZipInputStream(new BufferedInputStream(is));
ZipEntry ze;
byte[] buffer = new byte[1024];
int count;
while ((ze = zis.getNextEntry()) != null) {
filename = ze.getName();
if (ze.isDirectory()) {
File fmd = new File(targetDirectory + filename);
fmd.mkdirs();
continue;
}
FileOutputStream fout = new FileOutputStream(targetDirectory + filename);
while ((count = zis.read(buffer)) != -1) {
fout.write(buffer, 0, count);
}
fout.close();
zis.closeEntry();
}
zis.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
This is a code for saving images in SD card if and if not exist.
but i don't know how to read it.
Can anybody help me please.
This is the download file method:
public static String DownLoadFile(String netUrl, String name ) {
try {
//need uses permission WRITE_EXTERNAL_STORAGE
ByteArrayBuffer baf = null;
long startTime = 0;
//get to directory (a File object) from SD Card
File savePath=new File(Environment.getExternalStorageDirectory().getPath()+"/postImages/");
String ext="jpg";
URL url = new URL(netUrl);
//create your specific file for image storage:
File file = new File(savePath, name + "." + ext);
boolean success = true;
if (!savePath.exists()) {
success = savePath.mkdir();
}
if (success) {
if(file.createNewFile())
{
file.createNewFile();
//write the Bitmap
Log.i("file existence", "file does not exist!!!!!!!!!!!");
/* Open a connection to that URL. */
URLConnection ucon = url.openConnection();
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
startTime = System.currentTimeMillis();
baf = new ByteArrayBuffer(5000);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
/* Convert the Bytes read to a String. */
FileOutputStream fos = new FileOutputStream(file);
fos.write(baf.toByteArray());
fos.flush();
fos.close();
Log.d("DownloadManager", "download ready in" + ((System.currentTimeMillis() - startTime) / 1000) + " sec");
return file.getAbsolutePath();
}//end of create file if not exists
}//end of if success
} catch (Exception exx) {
if (exx.getMessage() != null) {
} else {
}
}
return null;
}
Try this,
Uri uri = Uri.parse("file:///sdcard/temporary_file.jpg");
img.setImageURI(uri);
if u have image uri so get path from uri like
String Path = fileUri.getPath();
// read file from sdcard
public static byte[] readFromStream(String path) throws Exception { File
file = new File(path); InputStream inputStream = new
FileInputStream(file); ByteArrayOutputStream baos = new
ByteArrayOutputStream(); DataOutputStream dos = new
DataOutputStream(baos); byte[] data = new byte[(int) file.length()]; int
count = inputStream.read(data); while (count != -1) { dos.write(data, 0,
count); count = inputStream.read(data); } return baos.toByteArray(); }
i'm facing a problem with unzipping files in Android. Here is the code snippet:
public void unzip() {
try {
FileInputStream fin = new FileInputStream(_zipFile);
BufferedInputStream in = new BufferedInputStream(fin);
ZipInputStream zin = new ZipInputStream(in);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
Log.v("Decompress", "Unzipping " + ze.getName());
if(ze.isDirectory()) {
_dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(_location + ze.getName());
BufferedOutputStream out = new BufferedOutputStream(fout);
byte[] buffer = new byte[1024];
int length;
while ((length = zin.read(buffer,0,1024)) >= 0) {
out.write(buffer,0,length);
}
/* while ((length = zin.read(buffer))>0) {
out.write(buffer, 0, length);
}*/
/*for (int c = zin.read(); c != -1; c = zin.read()) {
fout.write(c);
}*/
zin.closeEntry();
fout.close();
}
}
zin.close();
} catch(Exception e) {
Log.e("Decompress", "unzip", e);
}
}
Smaller files (smaller than 10kB) are unzipped like empty - size 0 (html files, .jpg). Other files are ok. If I use this same code, but without buffers all the files are ok - ofcourse, unzipping without buffers is out of the question since it runs too long. Files are stored on SD card on real device. I have already tried setting smaller buffer size ( even new byte[2]). Thanks in advance...
Try this code instead,
public void doUnzip(String inputZipFile, String destinationDirectory)
throws IOException {
int BUFFER = 2048;
List zipFiles = new ArrayList();
File sourceZipFile = new File(inputZip);
File unzipDestinationDirectory = new File(destinationDirectory);
unzipDestinationDirectory.mkdir();
ZipFile zipFile;
// Open Zip file for reading
zipFile = new ZipFile(sourceZipFile, ZipFile.OPEN_READ);
// Create an enumeration of the entries in the zip file
Enumeration zipFileEntries = zipFile.entries();
// Process each entry
while (zipFileEntries.hasMoreElements()) {
// grab a zip file entry
ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
String currentEntry = entry.getName();
File destFile = new File(unzipDestinationDirectory, currentEntry);
// destFile = new File(unzipDestinationDirectory, destFile.getName());
if (currentEntry.endsWith(".zip")) {
zipFiles.add(destFile.getAbsolutePath());
}
// grab file's parent directory structure
File destinationParent = destFile.getParentFile();
// create the parent directory structure if needed
destinationParent.mkdirs();
try {
// extract file if not a directory
if (!entry.isDirectory()) {
BufferedInputStream is =
new BufferedInputStream(zipFile.getInputStream(entry));
int currentByte;
// establish buffer for writing file
byte data[] = new byte[BUFFER];
// write the current file to disk
FileOutputStream fos = new FileOutputStream(destFile);
BufferedOutputStream dest =
new BufferedOutputStream(fos, BUFFER);
// read and write until last byte is encountered
while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, currentByte);
}
dest.flush();
dest.close();
is.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
zipFile.close();
for (Iterator iter = zipFiles.iterator(); iter.hasNext();) {
String zipName = (String)iter.next();
doUnzip(
zipName,
destinationDirectory +
File.separatorChar +
zipName.substring(0,zipName.lastIndexOf(".zip"))
);
}
}