cvs: pear-core / install-pear.php /Archive Tar.php /PEAR DependencyDB.php

From: Date: Sat, 06 Jan 2007 04:03:32 +0000
Subject: cvs: pear-core / install-pear.php /Archive Tar.php /PEAR DependencyDB.php
Groups: php.pear.cvs php.pear.core 
Request: Send a blank email to pear-core+get-5330@lists.php.net to get a copy of this message
cellog Sat Jan 6 04:03:32 2007 UTC Modified files: /pear-core install-pear.php /pear-core/Archive Tar.php /pear-core/PEAR DependencyDB.php Log: fix weird warnings in the generated install-pear-phar

http://cvs.php.net/viewvc.cgi/pear-core/install-pear.php?r1=1.27&r2=1.28&diff_format=u Index: pear-core/install-pear.php diff -u pear-core/install-pear.php:1.27 pear-core/install-pear.php:1.28 --- pear-core/install-pear.php:1.27 Sun Aug 13 21:11:48 2006 +++ pear-core/install-pear.php Sat Jan 6 04:03:32 2007 @@ -1,6 +1,6 @@ <?php -/* $Id: install-pear.php,v 1.27 2006/08/13 21:11:48 cellog Exp $ */ +/* $Id: install-pear.php,v 1.28 2007/01/06 04:03:32 cellog Exp $ */ error_reporting(E_ALL); $pear_dir = dirname(__FILE__); @@ -191,6 +191,7 @@ if (isset($oldcachedir)) { $config->set('cache_dir', $oldcachedir); } + $data = array(); foreach ($config->getKeys() as $key) { $data[$key] = $config->get($key); } http://cvs.php.net/viewvc.cgi/pear-core/Archive/Tar.php?r1=1.23&r2=1.24&diff_format=u Index: pear-core/Archive/Tar.php diff -u pear-core/Archive/Tar.php:1.23 pear-core/Archive/Tar.php:1.24 --- pear-core/Archive/Tar.php:1.23 Fri May 12 02:38:58 2006 +++ pear-core/Archive/Tar.php Sat Jan 6 04:03:32 2007 @@ -16,18 +16,19 @@ // | Author: Vincent Blavet <vincent@phpconcept.net> | // +----------------------------------------------------------------------+ // -// $Id: Tar.php,v 1.23 2006/05/12 02:38:58 cellog Exp $ +// $Id: Tar.php,v 1.24 2007/01/06 04:03:32 cellog Exp $ require_once 'PEAR.php'; define ('ARCHIVE_TAR_ATT_SEPARATOR', 90001); +define ('ARCHIVE_TAR_END_BLOCK', pack("a512", '')); /** * Creates a (compressed) Tar archive * * @author Vincent Blavet <vincent@phpconcept.net> -* @version $Revision: 1.23 $ +* @version $Revision: 1.24 $ * @package Archive */ class Archive_Tar extends PEAR @@ -797,14 +798,14 @@ $p_len = 1; if ($this->_compress_type == 'gz') { - @gzseek($this->_file, @gztell($this->_file)+($p_len*512)); + @gzseek($this->_file, gztell($this->_file)+($p_len*512)); } else if ($this->_compress_type == 'bz2') { // ----- Replace missing bztell() and bzseek() for ($i=0; $i<$p_len; $i++) $this->_readBlock(); } else if ($this->_compress_type == 'none') - @fseek($this->_file, @ftell($this->_file)+($p_len*512)); + @fseek($this->_file, ftell($this->_file)+($p_len*512)); else $this->_error('Unknown or missing compression type (' .$this->_compress_type.')'); @@ -819,7 +820,7 @@ { if (is_resource($this->_file)) { // ----- Write the last 0 filled block for end of archive - $v_binary_data = pack("a512", ''); + $v_binary_data = pack('a1024', ''); $this->_writeBlock($v_binary_data); } return true; @@ -973,7 +974,7 @@ $p_filename = $this->_translateWinPath($p_filename, false);; if (!$this->_writeHeaderBlock($p_filename, strlen($p_string), - 0, 0, "", 0, 0)) + time(), 384, "", 0, 0)) return false; $i=0; @@ -1217,6 +1218,9 @@ return false; } + if (!is_array($v_header)) { + $v_header = array(); + } // ----- Calculate the checksum $v_checksum = 0; // ..... First part of the header @@ -1251,6 +1255,11 @@ // ----- Extract the properties $v_header['filename'] = trim($v_data['filename']); + if ($this->_maliciousFilename($v_header['filename'])) { + $this->_error('Malicious .tar detected, file "' . $v_header['filename'] . + '" will not install in desired directory tree'); + return false; + } $v_header['mode'] = OctDec(trim($v_data['mode'])); $v_header['uid'] = OctDec(trim($v_data['uid'])); $v_header['gid'] = OctDec(trim($v_data['gid'])); @@ -1259,9 +1268,9 @@ if (($v_header['typeflag'] = $v_data['typeflag']) == "5") { $v_header['size'] = 0; } + $v_header['link'] = trim($v_data['link']); /* ----- All these fields are removed form the header because they do not carry interesting info - $v_header[link] = trim($v_data[link]); $v_header[magic] = trim($v_data[magic]); $v_header[version] = trim($v_data[version]); $v_header[uname] = trim($v_data[uname]); @@ -1274,6 +1283,26 @@ } // }}} + // {{{ _maliciousFilename() + /** + * Detect and report a malicious file name + * + * @param string $file + * @return bool + * @access private + */ + function _maliciousFilename($file) + { + if (strpos($file, '/../') !== false) { + return true; + } + if (strpos($file, '../') === 0) { + return true; + } + return false; + } + // }}} + // {{{ _readLongHeader() function _readLongHeader(&$v_header) { @@ -1295,6 +1324,11 @@ return false; $v_header['filename'] = $v_filename; + if ($this->_maliciousFilename($v_filename)) { + $this->_error('Malicious .tar detected, file "' . $v_filename . + '" will not install in desired directory tree'); + return false; + } return true; } @@ -1495,6 +1529,12 @@ return false; } } + } elseif ($v_header['typeflag'] == "2") { + if (!@symlink($v_header['link'], $v_header['filename'])) { + $this->_error('Unable to extract symbolic link {' + .$v_header['filename'].'}'); + return false; + } } else { if (($v_dest_file = @fopen($v_header['filename'], "wb")) == 0) { $this->_error('Error while opening {'.$v_header['filename'] @@ -1515,8 +1555,11 @@ // ----- Change the file mode, mtime @touch($v_header['filename'], $v_header['mtime']); - // To be completed - //chmod($v_header[filename], DecOct($v_header[mode])); + if ($v_header['mode'] & 0111) { + // make file executable, obey umask + $mode = fileperms($v_header['filename']) | (~umask() & 0111); + @chmod($v_header['filename'], $mode); + } } // ----- Check the file size @@ -1553,6 +1596,9 @@ $v_file_dir = '/'; $p_list_detail[$v_nb++] = $v_header; + if (is_array($p_file_list) && (count($p_list_detail) == count($p_file_list))) { + return true; + } } } @@ -1594,29 +1640,25 @@ } if ($this->_compress_type == 'gz') { - $v_buffer = @gzread($v_temp_tar, 512); - - // ----- Read the following blocks but not the last one - if (!@gzeof($v_temp_tar)) { - do{ - $v_binary_data = pack("a512", $v_buffer); - $this->_writeBlock($v_binary_data); - $v_buffer = @gzread($v_temp_tar, 512); - - } while (!@gzeof($v_temp_tar)); + while (!@gzeof($v_temp_tar)) { + $v_buffer = @gzread($v_temp_tar, 512); + if ($v_buffer == ARCHIVE_TAR_END_BLOCK) { + // do not copy end blocks, we will re-make them + // after appending + continue; + } + $v_binary_data = pack("a512", $v_buffer); + $this->_writeBlock($v_binary_data); } @gzclose($v_temp_tar); } elseif ($this->_compress_type == 'bz2') { - $v_buffered_lines = array(); - $v_buffered_lines[] = @bzread($v_temp_tar, 512); - - // ----- Read the following blocks but not the last one - while (strlen($v_buffered_lines[] - = @bzread($v_temp_tar, 512)) > 0) { - $v_binary_data = pack("a512", - array_shift($v_buffered_lines)); + while (strlen($v_buffer = @bzread($v_temp_tar, 512)) > 0) { + if ($v_buffer == ARCHIVE_TAR_END_BLOCK) { + continue; + } + $v_binary_data = pack("a512", $v_buffer); $this->_writeBlock($v_binary_data); } @@ -1630,13 +1672,23 @@ } else { // ----- For not compressed tar, just add files before the last - // 512 bytes block + // one or two 512 bytes block if (!$this->_openReadWrite()) return false; clearstatcache(); $v_size = filesize($this->_tarname); - fseek($this->_file, $v_size-512); + + // We might have zero, one or two end blocks. + // The standard is two, but we should try to handle + // other cases. + fseek($this->_file, $v_size - 1024); + if (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) { + fseek($this->_file, $v_size - 1024); + } + elseif (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) { + fseek($this->_file, $v_size - 512); + } } return true; @@ -1670,6 +1722,7 @@ */ function _dirCheck($p_dir) { + clearstatcache(); if ((@is_dir($p_dir)) || ($p_dir == '')) return true; @@ -1743,7 +1796,7 @@ // {{{ _translateWinPath() function _translateWinPath($p_path, $p_remove_disk_letter=true) { - if (OS_WINDOWS) { + if (defined('OS_WINDOWS') && OS_WINDOWS) { // ----- Look for potential disk letter if ( ($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { http://cvs.php.net/viewvc.cgi/pear-core/PEAR/DependencyDB.php?r1=1.34&r2=1.35&diff_format=u Index: pear-core/PEAR/DependencyDB.php diff -u pear-core/PEAR/DependencyDB.php:1.34 pear-core/PEAR/DependencyDB.php:1.35 --- pear-core/PEAR/DependencyDB.php:1.34 Tue Oct 31 02:54:40 2006 +++ pear-core/PEAR/DependencyDB.php Sat Jan 6 04:03:32 2007 @@ -16,7 +16,7 @@ * @author Greg Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version CVS: $Id: DependencyDB.php,v 1.34 2006/10/31 02:54:40 cellog Exp $ + * @version CVS: $Id: DependencyDB.php,v 1.35 2007/01/06 04:03:32 cellog Exp $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -227,6 +227,12 @@ foreach ($temp as $dep) { if (strtolower($dep['dep']['channel']) == strtolower($channel) && strtolower($dep['dep']['name']) == strtolower($package)) { + if (!isset($dependencies[$info['channel']])) { + $dependencies[$info['channel']] = array(); + } + if (!isset($dependencies[$info['channel']][$info['package']])) { + $dependencies[$info['channel']][$info['package']] = array(); + } $dependencies[$info['channel']][$info['package']][] = $dep; } }
« previous php.pear.core (#5330) next »