Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zip file created with Password on iOS can't unzip on Windows #55

Closed
dttrinh opened this issue Oct 6, 2016 · 11 comments
Closed

Zip file created with Password on iOS can't unzip on Windows #55

dttrinh opened this issue Oct 6, 2016 · 11 comments

Comments

@dttrinh
Copy link

dttrinh commented Oct 6, 2016

Hi, I'm using your lib in my iOS project. My problem is the zip file that is created with password on iOS 10.0 (Both Simulator and Real iPhone) can't unzip on Windows. I've tried many unzip tools (WinRAR, 7Zip...) but all failed with a message "Wrong password". (The problem is only occurred on my password protected zip file, if password is null, it is perfectly unzipped on Windows)

Here is the zipped file https://dl.dropboxusercontent.com/u/38691130/image_pass_123.zip
Password is "123"

Thankyou so much!

@mostafaberg
Copy link
Collaborator

Can you show a code snippet on how you create that ?

@dttrinh
Copy link
Author

dttrinh commented Oct 11, 2016

I'm just use the latest version of this library, here is the zip method:

public class func zipFiles(paths: [URL], zipFilePath: URL, password: String?, compression: ZipCompression = .DefaultCompression, progress: ((_ progress: Double) -> ())?) throws {

        // File manager
        let fileManager = FileManager.default

        // Check whether a zip file exists at path.
        let destinationPath = zipFilePath.path

        // Process zip paths
        let processedPaths = ZipUtilities().processZipPaths(paths)

        // Zip set up
        let chunkSize: Int = 16384

        // Progress handler set up
        var currentPosition: Double = 0.0
        var totalSize: Double = 0.0
        // Get totalSize for progress handler
        for path in processedPaths {
            do {
                let filePath = path.filePath()
                let fileAttributes = try fileManager.attributesOfItem(atPath: filePath)
                let fileSize = fileAttributes[FileAttributeKey.size] as? Double
                if let fileSize = fileSize {
                    totalSize += fileSize
                }
            }
            catch {}
        }

        let progressTracker = Progress(totalUnitCount: Int64(totalSize))
        progressTracker.isCancellable = false
        progressTracker.isPausable = false
        progressTracker.kind = ProgressKind.file

        // Begin Zipping
        let zip = zipOpen(destinationPath, APPEND_STATUS_CREATE)
        for path in processedPaths {
            let filePath = path.filePath()
            var isDirectory: ObjCBool = false
            fileManager.fileExists(atPath: filePath, isDirectory: &isDirectory)
            if !isDirectory.boolValue {
                let input = fopen(filePath, "r")
                if input == nil {
                    throw ZipError.zipFail
                }
                let fileName = path.fileName
                var zipInfo: zip_fileinfo = zip_fileinfo(tmz_date: tm_zip(tm_sec: 0, tm_min: 0, tm_hour: 0, tm_mday: 0, tm_mon: 0, tm_year: 0), dosDate: 0, internal_fa: 0, external_fa: 0)
                do {
                    let fileAttributes = try fileManager.attributesOfItem(atPath: filePath)
                    if let fileDate = fileAttributes[FileAttributeKey.modificationDate] as? Date {
                        let components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: fileDate)
                        zipInfo.tmz_date.tm_sec = UInt32(components.second!)
                        zipInfo.tmz_date.tm_min = UInt32(components.minute!)
                        zipInfo.tmz_date.tm_hour = UInt32(components.hour!)
                        zipInfo.tmz_date.tm_mday = UInt32(components.day!)
                        zipInfo.tmz_date.tm_mon = UInt32(components.month!) - 1
                        zipInfo.tmz_date.tm_year = UInt32(components.year!)
                    }
                    if let fileSize = fileAttributes[FileAttributeKey.size] as? Double {
                        currentPosition += fileSize
                    }
                }
                catch {}
                let buffer = malloc(chunkSize)
                if let password = password, let fileName = fileName {
                    zipOpenNewFileInZip3(zip, fileName, &zipInfo, nil, 0, nil, 0, nil,Z_DEFLATED, compression.minizipCompression, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, password, 0)
                }
                else if let fileName = fileName {
                    zipOpenNewFileInZip3(zip, fileName, &zipInfo, nil, 0, nil, 0, nil,Z_DEFLATED, compression.minizipCompression, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, nil, 0)
                }
                else {
                    throw ZipError.zipFail
                }
                var length: Int = 0
                while (feof(input) == 0) {
                    length = fread(buffer, 1, chunkSize, input)
                    zipWriteInFileInZip(zip, buffer, UInt32(length))
                }

                // Update progress handler
                if let progressHandler = progress{
                    progressHandler((currentPosition/totalSize))
                }

                progressTracker.completedUnitCount = Int64(currentPosition)

                zipCloseFileInZip(zip)
                free(buffer)
                fclose(input)
            }
        }
        zipClose(zip, nil)

        // Completed. Update progress handler.
        if let progressHandler = progress{
            progressHandler(1.0)
        }

        progressTracker.completedUnitCount = Int64(totalSize)
    }

I don't know the problem is from above method or minizip's method.
Thanks you!

@mostafaberg
Copy link
Collaborator

mostafaberg commented Oct 11, 2016

Interesting, can you breakpoint and see what the value of password is on this line ?

zipOpenNewFileInZip3(zip, fileName, &zipInfo, nil, 0, nil, 0, nil,Z_DEFLATED, compression.minizipCompression, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, password, 0)

@dttrinh
Copy link
Author

dttrinh commented Oct 11, 2016

Yes I have, value of the password is exactly what it does when inputted.
When I zip it and then unzip it also using this library on iOS, it's run perfectly. The problem is only occurred on Windows with third-party unzip softwares.

@mostafaberg
Copy link
Collaborator

I see, well to me it seems like you're doing everything correctly and my initial guess is that something is wrong with Minizip, will need to verify that, if the issue has been resolved in another version of minizp it should probably be updated here
@marmelroy ?

@mostafaberg
Copy link
Collaborator

mostafaberg commented Oct 11, 2016

duplicate of #23, seems to be the same issue

@marmelroy
Copy link
Owner

Thanks @mostafaberg and @dttrinh, indeed there seems to be an issue with Zip and password protection. Will investigate properly over the next few days...

@dttrinh
Copy link
Author

dttrinh commented Oct 14, 2016

Finally I have solved the problem!
Just put #define HAVE_AES into zip.c file and copy aes libraries to the project, all things will be OK.
One thing I'm not clear that if I don't have #define HAVE_AES, it will use DEFLATED compression method as default, isn't it? So why all of the unzip softwares can't even unzip it.
But anyway, the problem has been solved!

Thanks @mostafaberg and @marmelroy so much!

@dttrinh dttrinh closed this as completed Oct 14, 2016
@Wayneb81
Copy link

I am having the same problem, unable to unZip the file if I use a password. I added #define HAVE_AES to the top of the zip.c file, where can I get the aes libraries that are required? I have searched GitHub but can't find them.

@emericspiroux
Copy link

emericspiroux commented Jul 19, 2017

include "aes/aes.h"
include "aes/fileenc.h"
include "aes/prng.h"
include "aes/entropy.h"

They are missing ! =(

@mostafaberg mostafaberg marked this as a duplicate of #23 Jul 19, 2017
@iblacksun
Copy link

@emericspiroux same issue here.

I added #define HAVE_AES to the top of the zip.c file, but compiler report 「'aes/aes.h' file not found」

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants