ZipStream-PHP icon indicating copy to clipboard operation
ZipStream-PHP copied to clipboard

Invalid file name in zip file

Open ilicmsreten opened this issue 5 years ago • 9 comments

Description of the problem

Hi, if I try to use no-ASCII characters in addFileFromStream/addFile methods invalid name is generated in zip file.

Example code

$zip->addFileFromStream('љњељњечћш.txt', someMethodToGetStream()); produce different filename from љњељњечћш.txt

  • ZipStream-PHP version: 2.0.0
  • PHP version: 7.3.14

ilicmsreten avatar Apr 23 '20 16:04 ilicmsreten

Yes, this is a bug in PHP AFAIK.

https://bugs.php.net/bug.php?id=65815 https://bugs.php.net/bug.php?id=53948

There is no clear work-for-all-cases workaround if you need to support a wide range of languages.

NicolasCARPi avatar Apr 23 '20 19:04 NicolasCARPi

@NicolasCARPi I'm not sure is this PHP issue because if I use plain PHP functions

            $zip = new \ZipArchive();
            $zip->open('test.zip', \ZipArchive::CREATE);
            $zip->addFromString('љњељњечћш.txt', getSomeContent());
            $zip->close();

filenames are generated correctly

ilicmsreten avatar Apr 23 '20 20:04 ilicmsreten

Yes you're right!

NicolasCARPi avatar Apr 23 '20 22:04 NicolasCARPi

@maennchen I'm thinking the strlen functions in File.php should maybe be mb_strlen if the filename is in UTF-8.

With љњељњечћш.txt unzip -Zv reports a filename length of 22 characters instead of 13. I'm not sure if that is causing the issue described here, but that's an issue.

NicolasCARPi avatar Apr 23 '20 23:04 NicolasCARPi

Note: I'm wondering if this is not an unarchiver issue.

Try to extract with 7z x example.zip and the filename is good!

For information this is the code dealing with setting the EFS flag in the archive.

NicolasCARPi avatar Apr 24 '20 01:04 NicolasCARPi

#147 is adding a note to the readme about this issue.

NicolasCARPi avatar Apr 26 '20 01:04 NicolasCARPi

Hi there,

According to my research, just putting an entry to extra field solve this issue. I also make such patch to python zip module.

In File.php, find function buildZip64ExtraBlock, and modify as

    protected function buildZip64ExtraBlock(bool $force = false): string
    {
....
        if (!empty($fields)) {
            if (!$this->zip->opt->isEnableZip64()) {
                throw new OverflowException();
            }

            array_unshift(
                $fields,
                ['v', 0x0001],                      // 64 bit extension
                ['v', count($fields) * 8]             // Length of data block
            );
            $this->version = Version::ZIP64();
        }
        // from here 
        if ($this->bits & self::BIT_EFS_UTF8) {
            // Put the tricky entry to
            // force Linux unzip to lookup EFS flag.
            $fields[] = ['v', 0x5653];  // Choose 'ZS' for proprietary usage
            $fields[] = ['v', 0x0000];  // zero length
        }
       // end modification
        return ZipStream::packFields($fields);

BTW, I also apply such issue to python zip module, and works well, ( I add comments with samxiao in it), https://gist.github.com/Xiao-Chong/b6bf1fc99fcfd2a1aa442588b049fb96?fbclid=IwAR0UcNVz64hw09KTC5sgrXrynnjdhYEnl2b2gcaeHVLKDKDp31J4LK6ck5w

So I'd like you team can patch this to official release next time. Thank you very much.

Xiao-Chong avatar Oct 13 '21 03:10 Xiao-Chong

@Xiao-Chong thanks. Could you open a PR for that?

maennchen avatar Oct 13 '21 08:10 maennchen

@maennchen , OKay. Will open a PR later. Thank you.

Xiao-Chong avatar Oct 13 '21 12:10 Xiao-Chong

Solved with #222

maennchen avatar Nov 25 '22 04:11 maennchen