open($destination, \ZipArchive::CREATE); $zip->addFile($source); $zip->close(); return $destination; } /** * Unpack file. * * @param string $source * @param string $destination * * @return string */ public function unpack($source, $destination) { $zip = new \ZipArchive(); if ($zip->open($source) === true) { $filename = $this->filterRelativePaths($zip->getNameIndex(0) ?: ''); if ($filename) { $zip->extractTo(dirname($destination), $filename); rename(dirname($destination).'/'.$filename, $destination); } else { $destination = ''; } $zip->close(); } else { $destination = ''; } return $destination; } /** * Filter file names with relative paths. * * @param string $path * @return string */ private function filterRelativePaths(string $path): string { if ($path && preg_match('#^\s*(../)|(/../)#i', $path)) { $path = ''; } return $path; } }