SA-CORE-2019-012 by samuel.mortenson, larowlan, pwolanin, Sam152, Jasu_M, David_Rothstein, michieltcs, Ayesh, alexpott, xjm, vijaycs85, mcdruid
parent
6f60277f75
commit
75689e47e6
|
@ -38,10 +38,10 @@ class ArchiverTar implements ArchiverInterface {
|
|||
|
||||
public function extract($path, Array $files = array()) {
|
||||
if ($files) {
|
||||
$this->tar->extractList($files, $path);
|
||||
$this->tar->extractList($files, $path, '', FALSE, FALSE);
|
||||
}
|
||||
else {
|
||||
$this->tar->extract($path);
|
||||
$this->tar->extract($path, FALSE, FALSE);
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
|
|
@ -40,35 +40,23 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Note on Drupal 8 porting.
|
||||
* This file origin is Tar.php, release 1.4.5 (stable) with some code
|
||||
* from PEAR.php, release 1.10.5 (stable) both at http://pear.php.net.
|
||||
* Note on Drupal 7 porting.
|
||||
* This file origin is Tar.php, release 1.4.9 (stable) with some code
|
||||
* from PEAR.php, release 1.10.10 (stable) both at http://pear.php.net.
|
||||
* To simplify future porting from pear of this file, you should not
|
||||
* do cosmetic or other non significant changes to this file.
|
||||
* The following changes have been done:
|
||||
* Added namespace Drupal\Core\Archiver.
|
||||
* Removed require_once 'PEAR.php'.
|
||||
* Added defintion of OS_WINDOWS taken from PEAR.php.
|
||||
* Renamed class to ArchiveTar.
|
||||
* Removed extends PEAR from class.
|
||||
* Removed call parent:: __construct().
|
||||
* Changed PEAR::loadExtension($extname) to this->loadExtension($extname).
|
||||
* Added function loadExtension() taken from PEAR.php.
|
||||
* Changed all calls of unlink() to drupal_unlink().
|
||||
* Changed $this->error_object = &$this->raiseError($p_message)
|
||||
* to throw new \Exception($p_message).
|
||||
* to throw new Exception($p_message).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Note on Drupal 7 backporting from Drupal 8.
|
||||
* File origin is core/lib/Drupal/Core/Archiver/ArchiveTar.php from Drupal 8.
|
||||
* The following changes have been done:
|
||||
* Removed namespace Drupal\Core\Archiver.
|
||||
* Renamed class to Archive_Tar.
|
||||
* Changed \Exception to Exception.
|
||||
*/
|
||||
|
||||
|
||||
// Drupal removal require_once 'PEAR.php'.
|
||||
|
||||
// Drupal addition OS_WINDOWS as defined in PEAR.php.
|
||||
|
@ -153,6 +141,18 @@ class Archive_Tar
|
|||
*/
|
||||
public $error_object = null;
|
||||
|
||||
/**
|
||||
* Format for data extraction
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $_fmt = '';
|
||||
|
||||
/**
|
||||
* @var int Length of the read buffer in bytes
|
||||
*/
|
||||
protected $buffer_length;
|
||||
|
||||
/**
|
||||
* Archive_Tar Class constructor. This flavour of the constructor only
|
||||
* declare a new Archive_Tar object, identifying it by the name of the
|
||||
|
@ -165,10 +165,11 @@ class Archive_Tar
|
|||
* parameter indicates if gzip, bz2 or lzma2 compression
|
||||
* is required. For compatibility reason the
|
||||
* boolean value 'true' means 'gz'.
|
||||
* @param int $buffer_length Length of the read buffer in bytes
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function __construct($p_tarname, $p_compress = null)
|
||||
public function __construct($p_tarname, $p_compress = null, $buffer_length = 512)
|
||||
{
|
||||
// Drupal removal parent::__construct().
|
||||
|
||||
|
@ -263,15 +264,16 @@ class Archive_Tar
|
|||
|
||||
if (version_compare(PHP_VERSION, "5.5.0-dev") < 0) {
|
||||
$this->_fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" .
|
||||
"a8checksum/a1typeflag/a100link/a6magic/a2version/" .
|
||||
"a32uname/a32gname/a8devmajor/a8devminor/a131prefix";
|
||||
"a8checksum/a1typeflag/a100link/a6magic/a2version/" .
|
||||
"a32uname/a32gname/a8devmajor/a8devminor/a131prefix";
|
||||
} else {
|
||||
$this->_fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" .
|
||||
"Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" .
|
||||
"Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix";
|
||||
"Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" .
|
||||
"Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix";
|
||||
}
|
||||
|
||||
|
||||
$this->buffer_length = $buffer_length;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
|
@ -371,11 +373,12 @@ class Archive_Tar
|
|||
/**
|
||||
* @param string $p_path
|
||||
* @param bool $p_preserve
|
||||
* @param bool $p_symlinks
|
||||
* @return bool
|
||||
*/
|
||||
public function extract($p_path = '', $p_preserve = false)
|
||||
public function extract($p_path = '', $p_preserve = false, $p_symlinks = true)
|
||||
{
|
||||
return $this->extractModify($p_path, '', $p_preserve);
|
||||
return $this->extractModify($p_path, '', $p_preserve, $p_symlinks);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -616,11 +619,12 @@ class Archive_Tar
|
|||
* removed if present at the beginning of
|
||||
* the file/dir path.
|
||||
* @param boolean $p_preserve Preserve user/group ownership of files
|
||||
* @param boolean $p_symlinks Allow symlinks.
|
||||
*
|
||||
* @return boolean true on success, false on error.
|
||||
* @see extractList()
|
||||
*/
|
||||
public function extractModify($p_path, $p_remove_path, $p_preserve = false)
|
||||
public function extractModify($p_path, $p_remove_path, $p_preserve = false, $p_symlinks = true)
|
||||
{
|
||||
$v_result = true;
|
||||
$v_list_detail = array();
|
||||
|
@ -632,7 +636,8 @@ class Archive_Tar
|
|||
"complete",
|
||||
0,
|
||||
$p_remove_path,
|
||||
$p_preserve
|
||||
$p_preserve,
|
||||
$p_symlinks
|
||||
);
|
||||
$this->_close();
|
||||
}
|
||||
|
@ -676,11 +681,12 @@ class Archive_Tar
|
|||
* removed if present at the beginning of
|
||||
* the file/dir path.
|
||||
* @param boolean $p_preserve Preserve user/group ownership of files
|
||||
* @param boolean $p_symlinks Allow symlinks.
|
||||
*
|
||||
* @return true on success, false on error.
|
||||
* @see extractModify()
|
||||
*/
|
||||
public function extractList($p_filelist, $p_path = '', $p_remove_path = '', $p_preserve = false)
|
||||
public function extractList($p_filelist, $p_path = '', $p_remove_path = '', $p_preserve = false, $p_symlinks = true)
|
||||
{
|
||||
$v_result = true;
|
||||
$v_list_detail = array();
|
||||
|
@ -701,7 +707,8 @@ class Archive_Tar
|
|||
"partial",
|
||||
$v_list,
|
||||
$p_remove_path,
|
||||
$p_preserve
|
||||
$p_preserve,
|
||||
$p_symlinks
|
||||
);
|
||||
$this->_close();
|
||||
}
|
||||
|
@ -1326,8 +1333,15 @@ class Archive_Tar
|
|||
return false;
|
||||
}
|
||||
|
||||
while (($v_buffer = fread($v_file, 512)) != '') {
|
||||
$v_binary_data = pack("a512", "$v_buffer");
|
||||
while (($v_buffer = fread($v_file, $this->buffer_length)) != '') {
|
||||
$buffer_length = strlen("$v_buffer");
|
||||
if ($buffer_length != $this->buffer_length) {
|
||||
$pack_size = ((int)($buffer_length / 512) + 1) * 512;
|
||||
$pack_format = sprintf('a%d', $pack_size);
|
||||
} else {
|
||||
$pack_format = sprintf('a%d', $this->buffer_length);
|
||||
}
|
||||
$v_binary_data = pack($pack_format, "$v_buffer");
|
||||
$this->_writeBlock($v_binary_data);
|
||||
}
|
||||
|
||||
|
@ -1532,7 +1546,8 @@ class Archive_Tar
|
|||
$p_type = '',
|
||||
$p_uid = 0,
|
||||
$p_gid = 0
|
||||
) {
|
||||
)
|
||||
{
|
||||
$p_filename = $this->_pathReduction($p_filename);
|
||||
|
||||
if (strlen($p_filename) > 99) {
|
||||
|
@ -1745,7 +1760,16 @@ class Archive_Tar
|
|||
}
|
||||
|
||||
// ----- Extract the checksum
|
||||
$v_header['checksum'] = OctDec(trim($v_data['checksum']));
|
||||
$v_data_checksum = trim($v_data['checksum']);
|
||||
if (!preg_match('/^[0-7]*$/', $v_data_checksum)) {
|
||||
$this->_error(
|
||||
'Invalid checksum for file "' . $v_data['filename']
|
||||
. '" : ' . $v_data_checksum . ' extracted'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
$v_header['checksum'] = OctDec($v_data_checksum);
|
||||
if ($v_header['checksum'] != $v_checksum) {
|
||||
$v_header['filename'] = '';
|
||||
|
||||
|
@ -1839,10 +1863,7 @@ class Archive_Tar
|
|||
if (strpos($file, 'phar://') === 0) {
|
||||
return true;
|
||||
}
|
||||
if (strpos($file, DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR) !== false) {
|
||||
return true;
|
||||
}
|
||||
if (strpos($file, '..' . DIRECTORY_SEPARATOR) === 0) {
|
||||
if (strpos($file, '../') !== false || strpos($file, '..\\') !== false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1908,19 +1929,23 @@ class Archive_Tar
|
|||
}
|
||||
|
||||
switch ($v_header['typeflag']) {
|
||||
case 'L': {
|
||||
if (!$this->_readLongHeader($v_header)) {
|
||||
return null;
|
||||
case 'L':
|
||||
{
|
||||
if (!$this->_readLongHeader($v_header)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
|
||||
case 'K': {
|
||||
$v_link_header = $v_header;
|
||||
if (!$this->_readLongHeader($v_link_header)) {
|
||||
return null;
|
||||
case 'K':
|
||||
{
|
||||
$v_link_header = $v_header;
|
||||
if (!$this->_readLongHeader($v_link_header)) {
|
||||
return null;
|
||||
}
|
||||
$v_header['link'] = $v_link_header['filename'];
|
||||
}
|
||||
$v_header['link'] = $v_link_header['filename'];
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($v_header['filename'] == $p_filename) {
|
||||
|
@ -1960,6 +1985,7 @@ class Archive_Tar
|
|||
* @param string $p_file_list
|
||||
* @param string $p_remove_path
|
||||
* @param bool $p_preserve
|
||||
* @param bool $p_symlinks
|
||||
* @return bool
|
||||
*/
|
||||
public function _extractList(
|
||||
|
@ -1968,8 +1994,10 @@ class Archive_Tar
|
|||
$p_mode,
|
||||
$p_file_list,
|
||||
$p_remove_path,
|
||||
$p_preserve = false
|
||||
) {
|
||||
$p_preserve = false,
|
||||
$p_symlinks = true
|
||||
)
|
||||
{
|
||||
$v_result = true;
|
||||
$v_nb = 0;
|
||||
$v_extract_all = true;
|
||||
|
@ -2022,19 +2050,23 @@ class Archive_Tar
|
|||
}
|
||||
|
||||
switch ($v_header['typeflag']) {
|
||||
case 'L': {
|
||||
if (!$this->_readLongHeader($v_header)) {
|
||||
return null;
|
||||
case 'L':
|
||||
{
|
||||
if (!$this->_readLongHeader($v_header)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
|
||||
case 'K': {
|
||||
$v_link_header = $v_header;
|
||||
if (!$this->_readLongHeader($v_link_header)) {
|
||||
return null;
|
||||
case 'K':
|
||||
{
|
||||
$v_link_header = $v_header;
|
||||
if (!$this->_readLongHeader($v_link_header)) {
|
||||
return null;
|
||||
}
|
||||
$v_header['link'] = $v_link_header['filename'];
|
||||
}
|
||||
$v_header['link'] = $v_link_header['filename'];
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
// ignore extended / pax headers
|
||||
|
@ -2146,6 +2178,13 @@ class Archive_Tar
|
|||
}
|
||||
}
|
||||
} elseif ($v_header['typeflag'] == "2") {
|
||||
if (!$p_symlinks) {
|
||||
$this->_warning('Symbolic links are not allowed. '
|
||||
. 'Unable to extract {'
|
||||
. $v_header['filename'] . '}'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (@file_exists($v_header['filename'])) {
|
||||
@drupal_unlink($v_header['filename']);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue