zfcampus / zf-deploy

BSD 3-Clause "New" or "Revised" License
66 stars 24 forks source link

Directory separator issue with ZIP package created under Windows #35

Closed mikemix closed 9 years ago

mikemix commented 9 years ago

There's a major issue with zip packages created under Windows system. Paths to files inside the archive are using backslash \ as directory separator.

Unpacking such archive under Linux can lead to archive's tree of files being flattened and extracted to current linux directory without preserving the directory tree.

Consider this directory tree inside example zip package:

example_directory
|___inside_file1.txt
|___inside_file2.txt

Extraction to /var/www ends up in having 2 files without any directories (notice the backslash) /var/www/example_directory\inside_file1.txt /var/www/example_directory\inside_file2.txt

Instead of a directory containing 2 files (notice no backslash) /var/www/example_directory/inside_file1.txt /var/www/example_directory/inside_file2.txt

I'm using the ZipArchive library to extract the archive. To solve this, when adding file to the archive, the path needs to have backslash symbols replaced with slashes. This will work under Linux and continue to work under Windows as well (I tested this behavior).

The code of Deploy.php:

        switch ($format) {
            case 'zip':
            case 'zpk':
                foreach ($files as $name => $file) {
                    $packager->addFile($file, substr($file, $dirPos));
                }
                break;
            case 'tar':
            case 'tar.gz':
            case 'tgz':
                $packager->buildFromIterator($files, $dir);
                break;
        }

should be written as follows:

        switch ($format) {
            case 'zip':
                foreach ($files as $name => $file) {
                    $escapedFile = str_replace('\\', '/', $file);
                    $escapedPath = substr($escapedFile, $dirPos);

                    $packager->addFile($escapedFile , $escapedPath);
                }
                break;
            case 'zpk':
                foreach ($files as $name => $file) {
                    $packager->addFile($file, substr($file, $dirPos));
                }
                break;
            case 'tar':
            case 'tar.gz':
            case 'tgz':
                $packager->buildFromIterator($files, $dir);
                break;
        }
weierophinney commented 9 years ago

@mikemix Only change I'd make is that the zip and zpk are supposed to be the same case; I'll do that when I introduce your changes.

mikemix commented 9 years ago

Looking great :+1: