diff --git a/build/libifm.php b/build/libifm.php index 866cd8d..0adfce3 100644 --- a/build/libifm.php +++ b/build/libifm.php @@ -3905,13 +3905,13 @@ f00bar; $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['folder_not_found'] ) ); elseif (!$this->isPathValid($d['filename'])) $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_dir'] ) ); - elseif (!$this->isFilenameValid($d['filename'])) + elseif ($d['filename'] != "." && !$this->isFilenameValid($d['filename'])) $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) ); else { unset( $zip ); $dfile = $this->pathCombine( __DIR__, $this->config['tmp_dir'], uniqid( "ifm-tmp-" ) . ".zip" ); // temporary filename try { - IFMArchive::createZip( realpath( $d['filename'] ), $dfile ); + IFMArchive::createZip(realpath($d['filename']), $dfile, array($this, 'isFilenameValid')); if( $d['filename'] == "." ) { if( getcwd() == $this->getScriptRoot() ) $d['filename'] = "root"; @@ -4340,7 +4340,7 @@ f00bar; } // check if filename is allowed - private function isFilenameValid( $f ) { + public function isFilenameValid( $f ) { if( ! $this->isFilenameAllowed( $f ) ) return false; if( strtoupper( substr( PHP_OS, 0, 3 ) ) == "WIN" ) { @@ -4440,44 +4440,53 @@ class IFMArchive { /** * Add a folder to an archive */ - private static function addFolder( &$archive, $folder, $offset=0 ) { - if( $offset == 0 ) - $offset = strlen( dirname( $folder ) ) + 1; - $archive->addEmptyDir( substr( $folder, $offset ) ); - $handle = opendir( $folder ); - while( false !== $f = readdir( $handle ) ) { - if( $f != '.' && $f != '..' ) { + private static function addFolder(&$archive, $folder, $offset=0, $exclude_callback=null) { + if ($offset == 0) + $offset = strlen(dirname($folder)) + 1; + $archive->addEmptyDir(substr($folder, $offset)); + $handle = opendir($folder); + while (false !== $f = readdir($handle)) { + if ($f != '.' && $f != '..') { $filePath = $folder . '/' . $f; - if( file_exists( $filePath ) && is_readable( $filePath ) ) - if( is_file( $filePath ) ) - $archive->addFile( $filePath, substr( $filePath, $offset ) ); - elseif( is_dir( $filePath ) ) - self::addFolder( $archive, $filePath, $offset ); + if (file_exists($filePath) && is_readable($filePath)) + if (is_file($filePath)) + if (!is_callable($exclude_callback) || $exclude_callback($f)) + $archive->addFile( $filePath, substr( $filePath, $offset ) ); + elseif (is_dir($filePath)) + if (is_callable($exclude_callback)) + self::addFolder($archive, $filePath, $offset, $exclude_callback); + else + self::addFolder($archive, $filePath, $offset); } } - closedir( $handle ); + closedir($handle); } /** * Create a zip file */ - public static function createZip( $src, $out ) - { + public static function createZip($src, $out, $exclude_callback=null) { $a = new ZipArchive(); - $a->open( $out, ZIPARCHIVE::CREATE); + $a->open($out, ZIPARCHIVE::CREATE); - if( ! is_array( $src ) ) - $src = array( $src ); + if (!is_array($src)) + $src = array($src); - foreach( $src as $s ) - if( is_dir( $s ) ) - self::addFolder( $a, $s ); - elseif( is_file( $s ) ) - $a->addFile( $s, substr( $s, strlen( dirname( $s ) ) + 1 ) ); + file_put_contents("debug.ifm.log", var_export(is_callable($exclude_callback), true)."\n"); + + foreach ($src as $s) + if (is_dir($s)) + if (is_callable($exclude_callback)) + self::addFolder( $a, $s, null, $exclude_callback ); + else + self::addFolder( $a, $s ); + elseif (is_file($s)) + if (!is_callable($exclude_callback) || $exclude_callback($s)) + $a->addFile($s, substr($s, strlen(dirname($s)) + 1)); try { return $a->close(); - } catch ( Exception $e ) { + } catch (Exception $e) { return false; } } @@ -4485,13 +4494,13 @@ class IFMArchive { /** * Unzip a zip file */ - public static function extractZip( $file, $destination="./" ) { - if( ! file_exists( $file ) ) + public static function extractZip($file, $destination="./") { + if (!file_exists($file)) return false; $zip = new ZipArchive; - $res = $zip->open( $file ); - if( $res === true ) { - $zip->extractTo( $destination ); + $res = $zip->open($file); + if ($res === true) { + $zip->extractTo($destination); $zip->close(); return true; } else @@ -4501,32 +4510,32 @@ class IFMArchive { /** * Creates a tar archive */ - public static function createTar( $src, $out, $t ) { - $tmpf = substr( $out, 0, strlen( $out ) - strlen( $t ) ) . "tar"; - $a = new PharData( $tmpf ); + public static function createTar($src, $out, $t) { + $tmpf = substr($out, 0, strlen($out) - strlen($t)) . "tar"; + $a = new PharData($tmpf); try { - if( ! is_array( $src ) ) - $src = array( $src ); + if (!is_array($src)) + $src = array($src); - foreach( $src as $s ) - if( is_dir( $s ) ) - self::addFolder( $a, $s ); - elseif( is_file( $s ) ) - $a->addFile( $s, substr( $s, strlen( dirname( $s ) ) +1 ) ); - switch( $t ) { + foreach ($src as $s) + if (is_dir($s)) + self::addFolder($a, $s); + elseif (is_file($s)) + $a->addFile($s, substr($s, strlen(dirname($s)) +1)); + switch ($t) { case "tar.gz": - $a->compress( Phar::GZ ); - @unlink( $tmpf ); + $a->compress(Phar::GZ); + @unlink($tmpf); break; case "tar.bz2": - $a->compress( Phar::BZ2 ); - @unlink( $tmpf ); + $a->compress(Phar::BZ2); + @unlink($tmpf); break; } return true; - } catch( Exception $e ) { - @unlink( $tmpf ); + } catch (Exception $e) { + @unlink($tmpf); return false; } } @@ -4534,14 +4543,14 @@ class IFMArchive { /** * Extracts a tar archive */ - public static function extractTar( $file, $destination="./" ) { - if( ! file_exists( $file ) ) + public static function extractTar($file, $destination="./") { + if (!file_exists($file)) return false; - $tar = new PharData( $file ); + $tar = new PharData($file); try { - $tar->extractTo( $destination, null, true ); + $tar->extractTo($destination, null, true); return true; - } catch( Exception $e ) { + } catch (Exception $e) { return false; } } diff --git a/ifm.php b/ifm.php index 46b5d8b..9ae7f9b 100644 --- a/ifm.php +++ b/ifm.php @@ -3905,13 +3905,13 @@ f00bar; $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['folder_not_found'] ) ); elseif (!$this->isPathValid($d['filename'])) $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_dir'] ) ); - elseif (!$this->isFilenameValid($d['filename'])) + elseif ($d['filename'] != "." && !$this->isFilenameValid($d['filename'])) $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) ); else { unset( $zip ); $dfile = $this->pathCombine( __DIR__, $this->config['tmp_dir'], uniqid( "ifm-tmp-" ) . ".zip" ); // temporary filename try { - IFMArchive::createZip( realpath( $d['filename'] ), $dfile ); + IFMArchive::createZip(realpath($d['filename']), $dfile, array($this, 'isFilenameValid')); if( $d['filename'] == "." ) { if( getcwd() == $this->getScriptRoot() ) $d['filename'] = "root"; @@ -4340,7 +4340,7 @@ f00bar; } // check if filename is allowed - private function isFilenameValid( $f ) { + public function isFilenameValid( $f ) { if( ! $this->isFilenameAllowed( $f ) ) return false; if( strtoupper( substr( PHP_OS, 0, 3 ) ) == "WIN" ) { @@ -4440,44 +4440,53 @@ class IFMArchive { /** * Add a folder to an archive */ - private static function addFolder( &$archive, $folder, $offset=0 ) { - if( $offset == 0 ) - $offset = strlen( dirname( $folder ) ) + 1; - $archive->addEmptyDir( substr( $folder, $offset ) ); - $handle = opendir( $folder ); - while( false !== $f = readdir( $handle ) ) { - if( $f != '.' && $f != '..' ) { + private static function addFolder(&$archive, $folder, $offset=0, $exclude_callback=null) { + if ($offset == 0) + $offset = strlen(dirname($folder)) + 1; + $archive->addEmptyDir(substr($folder, $offset)); + $handle = opendir($folder); + while (false !== $f = readdir($handle)) { + if ($f != '.' && $f != '..') { $filePath = $folder . '/' . $f; - if( file_exists( $filePath ) && is_readable( $filePath ) ) - if( is_file( $filePath ) ) - $archive->addFile( $filePath, substr( $filePath, $offset ) ); - elseif( is_dir( $filePath ) ) - self::addFolder( $archive, $filePath, $offset ); + if (file_exists($filePath) && is_readable($filePath)) + if (is_file($filePath)) + if (!is_callable($exclude_callback) || $exclude_callback($f)) + $archive->addFile( $filePath, substr( $filePath, $offset ) ); + elseif (is_dir($filePath)) + if (is_callable($exclude_callback)) + self::addFolder($archive, $filePath, $offset, $exclude_callback); + else + self::addFolder($archive, $filePath, $offset); } } - closedir( $handle ); + closedir($handle); } /** * Create a zip file */ - public static function createZip( $src, $out ) - { + public static function createZip($src, $out, $exclude_callback=null) { $a = new ZipArchive(); - $a->open( $out, ZIPARCHIVE::CREATE); + $a->open($out, ZIPARCHIVE::CREATE); - if( ! is_array( $src ) ) - $src = array( $src ); + if (!is_array($src)) + $src = array($src); - foreach( $src as $s ) - if( is_dir( $s ) ) - self::addFolder( $a, $s ); - elseif( is_file( $s ) ) - $a->addFile( $s, substr( $s, strlen( dirname( $s ) ) + 1 ) ); + file_put_contents("debug.ifm.log", var_export(is_callable($exclude_callback), true)."\n"); + + foreach ($src as $s) + if (is_dir($s)) + if (is_callable($exclude_callback)) + self::addFolder( $a, $s, null, $exclude_callback ); + else + self::addFolder( $a, $s ); + elseif (is_file($s)) + if (!is_callable($exclude_callback) || $exclude_callback($s)) + $a->addFile($s, substr($s, strlen(dirname($s)) + 1)); try { return $a->close(); - } catch ( Exception $e ) { + } catch (Exception $e) { return false; } } @@ -4485,13 +4494,13 @@ class IFMArchive { /** * Unzip a zip file */ - public static function extractZip( $file, $destination="./" ) { - if( ! file_exists( $file ) ) + public static function extractZip($file, $destination="./") { + if (!file_exists($file)) return false; $zip = new ZipArchive; - $res = $zip->open( $file ); - if( $res === true ) { - $zip->extractTo( $destination ); + $res = $zip->open($file); + if ($res === true) { + $zip->extractTo($destination); $zip->close(); return true; } else @@ -4501,32 +4510,32 @@ class IFMArchive { /** * Creates a tar archive */ - public static function createTar( $src, $out, $t ) { - $tmpf = substr( $out, 0, strlen( $out ) - strlen( $t ) ) . "tar"; - $a = new PharData( $tmpf ); + public static function createTar($src, $out, $t) { + $tmpf = substr($out, 0, strlen($out) - strlen($t)) . "tar"; + $a = new PharData($tmpf); try { - if( ! is_array( $src ) ) - $src = array( $src ); + if (!is_array($src)) + $src = array($src); - foreach( $src as $s ) - if( is_dir( $s ) ) - self::addFolder( $a, $s ); - elseif( is_file( $s ) ) - $a->addFile( $s, substr( $s, strlen( dirname( $s ) ) +1 ) ); - switch( $t ) { + foreach ($src as $s) + if (is_dir($s)) + self::addFolder($a, $s); + elseif (is_file($s)) + $a->addFile($s, substr($s, strlen(dirname($s)) +1)); + switch ($t) { case "tar.gz": - $a->compress( Phar::GZ ); - @unlink( $tmpf ); + $a->compress(Phar::GZ); + @unlink($tmpf); break; case "tar.bz2": - $a->compress( Phar::BZ2 ); - @unlink( $tmpf ); + $a->compress(Phar::BZ2); + @unlink($tmpf); break; } return true; - } catch( Exception $e ) { - @unlink( $tmpf ); + } catch (Exception $e) { + @unlink($tmpf); return false; } } @@ -4534,14 +4543,14 @@ class IFMArchive { /** * Extracts a tar archive */ - public static function extractTar( $file, $destination="./" ) { - if( ! file_exists( $file ) ) + public static function extractTar($file, $destination="./") { + if (!file_exists($file)) return false; - $tar = new PharData( $file ); + $tar = new PharData($file); try { - $tar->extractTo( $destination, null, true ); + $tar->extractTo($destination, null, true); return true; - } catch( Exception $e ) { + } catch (Exception $e) { return false; } } diff --git a/src/ifmarchive.php b/src/ifmarchive.php index b19d448..2140606 100644 --- a/src/ifmarchive.php +++ b/src/ifmarchive.php @@ -23,44 +23,53 @@ class IFMArchive { /** * Add a folder to an archive */ - private static function addFolder( &$archive, $folder, $offset=0 ) { - if( $offset == 0 ) - $offset = strlen( dirname( $folder ) ) + 1; - $archive->addEmptyDir( substr( $folder, $offset ) ); - $handle = opendir( $folder ); - while( false !== $f = readdir( $handle ) ) { - if( $f != '.' && $f != '..' ) { + private static function addFolder(&$archive, $folder, $offset=0, $exclude_callback=null) { + if ($offset == 0) + $offset = strlen(dirname($folder)) + 1; + $archive->addEmptyDir(substr($folder, $offset)); + $handle = opendir($folder); + while (false !== $f = readdir($handle)) { + if ($f != '.' && $f != '..') { $filePath = $folder . '/' . $f; - if( file_exists( $filePath ) && is_readable( $filePath ) ) - if( is_file( $filePath ) ) - $archive->addFile( $filePath, substr( $filePath, $offset ) ); - elseif( is_dir( $filePath ) ) - self::addFolder( $archive, $filePath, $offset ); + if (file_exists($filePath) && is_readable($filePath)) + if (is_file($filePath)) + if (!is_callable($exclude_callback) || $exclude_callback($f)) + $archive->addFile( $filePath, substr( $filePath, $offset ) ); + elseif (is_dir($filePath)) + if (is_callable($exclude_callback)) + self::addFolder($archive, $filePath, $offset, $exclude_callback); + else + self::addFolder($archive, $filePath, $offset); } } - closedir( $handle ); + closedir($handle); } /** * Create a zip file */ - public static function createZip( $src, $out ) - { + public static function createZip($src, $out, $exclude_callback=null) { $a = new ZipArchive(); - $a->open( $out, ZIPARCHIVE::CREATE); + $a->open($out, ZIPARCHIVE::CREATE); - if( ! is_array( $src ) ) - $src = array( $src ); + if (!is_array($src)) + $src = array($src); - foreach( $src as $s ) - if( is_dir( $s ) ) - self::addFolder( $a, $s ); - elseif( is_file( $s ) ) - $a->addFile( $s, substr( $s, strlen( dirname( $s ) ) + 1 ) ); + file_put_contents("debug.ifm.log", var_export(is_callable($exclude_callback), true)."\n"); + + foreach ($src as $s) + if (is_dir($s)) + if (is_callable($exclude_callback)) + self::addFolder( $a, $s, null, $exclude_callback ); + else + self::addFolder( $a, $s ); + elseif (is_file($s)) + if (!is_callable($exclude_callback) || $exclude_callback($s)) + $a->addFile($s, substr($s, strlen(dirname($s)) + 1)); try { return $a->close(); - } catch ( Exception $e ) { + } catch (Exception $e) { return false; } } @@ -68,13 +77,13 @@ class IFMArchive { /** * Unzip a zip file */ - public static function extractZip( $file, $destination="./" ) { - if( ! file_exists( $file ) ) + public static function extractZip($file, $destination="./") { + if (!file_exists($file)) return false; $zip = new ZipArchive; - $res = $zip->open( $file ); - if( $res === true ) { - $zip->extractTo( $destination ); + $res = $zip->open($file); + if ($res === true) { + $zip->extractTo($destination); $zip->close(); return true; } else @@ -84,32 +93,32 @@ class IFMArchive { /** * Creates a tar archive */ - public static function createTar( $src, $out, $t ) { - $tmpf = substr( $out, 0, strlen( $out ) - strlen( $t ) ) . "tar"; - $a = new PharData( $tmpf ); + public static function createTar($src, $out, $t) { + $tmpf = substr($out, 0, strlen($out) - strlen($t)) . "tar"; + $a = new PharData($tmpf); try { - if( ! is_array( $src ) ) - $src = array( $src ); + if (!is_array($src)) + $src = array($src); - foreach( $src as $s ) - if( is_dir( $s ) ) - self::addFolder( $a, $s ); - elseif( is_file( $s ) ) - $a->addFile( $s, substr( $s, strlen( dirname( $s ) ) +1 ) ); - switch( $t ) { + foreach ($src as $s) + if (is_dir($s)) + self::addFolder($a, $s); + elseif (is_file($s)) + $a->addFile($s, substr($s, strlen(dirname($s)) +1)); + switch ($t) { case "tar.gz": - $a->compress( Phar::GZ ); - @unlink( $tmpf ); + $a->compress(Phar::GZ); + @unlink($tmpf); break; case "tar.bz2": - $a->compress( Phar::BZ2 ); - @unlink( $tmpf ); + $a->compress(Phar::BZ2); + @unlink($tmpf); break; } return true; - } catch( Exception $e ) { - @unlink( $tmpf ); + } catch (Exception $e) { + @unlink($tmpf); return false; } } @@ -117,14 +126,14 @@ class IFMArchive { /** * Extracts a tar archive */ - public static function extractTar( $file, $destination="./" ) { - if( ! file_exists( $file ) ) + public static function extractTar($file, $destination="./") { + if (!file_exists($file)) return false; - $tar = new PharData( $file ); + $tar = new PharData($file); try { - $tar->extractTo( $destination, null, true ); + $tar->extractTo($destination, null, true); return true; - } catch( Exception $e ) { + } catch (Exception $e) { return false; } } diff --git a/src/main.php b/src/main.php index 6fdd182..47c227b 100644 --- a/src/main.php +++ b/src/main.php @@ -829,13 +829,13 @@ f00bar; $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['folder_not_found'] ) ); elseif (!$this->isPathValid($d['filename'])) $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_dir'] ) ); - elseif (!$this->isFilenameValid($d['filename'])) + elseif ($d['filename'] != "." && !$this->isFilenameValid($d['filename'])) $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) ); else { unset( $zip ); $dfile = $this->pathCombine( __DIR__, $this->config['tmp_dir'], uniqid( "ifm-tmp-" ) . ".zip" ); // temporary filename try { - IFMArchive::createZip( realpath( $d['filename'] ), $dfile ); + IFMArchive::createZip(realpath($d['filename']), $dfile, array($this, 'isFilenameValid')); if( $d['filename'] == "." ) { if( getcwd() == $this->getScriptRoot() ) $d['filename'] = "root"; @@ -1264,7 +1264,7 @@ f00bar; } // check if filename is allowed - private function isFilenameValid( $f ) { + public function isFilenameValid( $f ) { if( ! $this->isFilenameAllowed( $f ) ) return false; if( strtoupper( substr( PHP_OS, 0, 3 ) ) == "WIN" ) {