ZipStream-PHP
ZipStream-PHP copied to clipboard
Invalid file name in zip file
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
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 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
Yes you're right!
@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.
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.
#147 is adding a note to the readme about this issue.
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 thanks. Could you open a PR for that?
@maennchen , OKay. Will open a PR later. Thank you.
Solved with #222