Revision cd5c298a
Added by Geoffroy Desvernay over 5 years ago
drupal7/modules/system/system.tar.inc | ||
---|---|---|
41 | 41 |
|
42 | 42 |
/** |
43 | 43 |
* Note on Drupal 8 porting. |
44 |
* This file origin is Tar.php, release 1.4.0 (stable) with some code
|
|
45 |
* from PEAR.php, release 1.9.5 (stable) both at http://pear.php.net.
|
|
44 |
* This file origin is Tar.php, release 1.4.5 (stable) with some code
|
|
45 |
* from PEAR.php, release 1.10.5 (stable) both at http://pear.php.net.
|
|
46 | 46 |
* To simplify future porting from pear of this file, you should not |
47 | 47 |
* do cosmetic or other non significant changes to this file. |
48 | 48 |
* The following changes have been done: |
... | ... | |
259 | 259 |
return false; |
260 | 260 |
} |
261 | 261 |
} |
262 |
|
|
263 |
|
|
264 |
if (version_compare(PHP_VERSION, "5.5.0-dev") < 0) { |
|
265 |
$this->_fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" . |
|
266 |
"a8checksum/a1typeflag/a100link/a6magic/a2version/" . |
|
267 |
"a32uname/a32gname/a8devmajor/a8devminor/a131prefix"; |
|
268 |
} else { |
|
269 |
$this->_fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" . |
|
270 |
"Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" . |
|
271 |
"Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix"; |
|
272 |
} |
|
273 |
|
|
274 |
|
|
262 | 275 |
} |
263 | 276 |
|
264 | 277 |
public function __destruct() |
... | ... | |
278 | 291 |
* @param string $ext The extension name |
279 | 292 |
* @return bool Success or not on the dl() call |
280 | 293 |
*/ |
281 |
function loadExtension($ext) |
|
294 |
public static function loadExtension($ext)
|
|
282 | 295 |
{ |
283 | 296 |
if (extension_loaded($ext)) { |
284 | 297 |
return true; |
... | ... | |
287 | 300 |
// if either returns true dl() will produce a FATAL error, stop that |
288 | 301 |
if ( |
289 | 302 |
function_exists('dl') === false || |
290 |
ini_get('enable_dl') != 1 || |
|
291 |
ini_get('safe_mode') == 1 |
|
303 |
ini_get('enable_dl') != 1 |
|
292 | 304 |
) { |
293 | 305 |
return false; |
294 | 306 |
} |
... | ... | |
714 | 726 |
} |
715 | 727 |
|
716 | 728 |
// ----- Get the arguments |
717 |
$v_att_list = & func_get_args();
|
|
729 |
$v_att_list = func_get_args(); |
|
718 | 730 |
|
719 | 731 |
// ----- Read the attributes |
720 | 732 |
$i = 0; |
... | ... | |
1394 | 1406 |
if ($p_stored_filename == '') { |
1395 | 1407 |
$p_stored_filename = $p_filename; |
1396 | 1408 |
} |
1397 |
$v_reduce_filename = $this->_pathReduction($p_stored_filename); |
|
1398 | 1409 |
|
1399 |
if (strlen($v_reduce_filename) > 99) { |
|
1400 |
if (!$this->_writeLongHeader($v_reduce_filename)) { |
|
1410 |
$v_reduced_filename = $this->_pathReduction($p_stored_filename); |
|
1411 |
|
|
1412 |
if (strlen($v_reduced_filename) > 99) { |
|
1413 |
if (!$this->_writeLongHeader($v_reduced_filename, false)) { |
|
1414 |
return false; |
|
1415 |
} |
|
1416 |
} |
|
1417 |
|
|
1418 |
$v_linkname = ''; |
|
1419 |
if (@is_link($p_filename)) { |
|
1420 |
$v_linkname = readlink($p_filename); |
|
1421 |
} |
|
1422 |
|
|
1423 |
if (strlen($v_linkname) > 99) { |
|
1424 |
if (!$this->_writeLongHeader($v_linkname, true)) { |
|
1401 | 1425 |
return false; |
1402 | 1426 |
} |
1403 | 1427 |
} |
... | ... | |
1406 | 1430 |
$v_uid = sprintf("%07s", DecOct($v_info[4])); |
1407 | 1431 |
$v_gid = sprintf("%07s", DecOct($v_info[5])); |
1408 | 1432 |
$v_perms = sprintf("%07s", DecOct($v_info['mode'] & 000777)); |
1409 |
|
|
1410 | 1433 |
$v_mtime = sprintf("%011s", DecOct($v_info['mtime'])); |
1411 | 1434 |
|
1412 |
$v_linkname = ''; |
|
1413 |
|
|
1414 | 1435 |
if (@is_link($p_filename)) { |
1415 | 1436 |
$v_typeflag = '2'; |
1416 |
$v_linkname = readlink($p_filename); |
|
1417 | 1437 |
$v_size = sprintf("%011s", DecOct(0)); |
1418 | 1438 |
} elseif (@is_dir($p_filename)) { |
1419 | 1439 |
$v_typeflag = "5"; |
... | ... | |
1425 | 1445 |
} |
1426 | 1446 |
|
1427 | 1447 |
$v_magic = 'ustar '; |
1428 |
|
|
1429 | 1448 |
$v_version = ' '; |
1430 | 1449 |
|
1431 | 1450 |
if (function_exists('posix_getpwuid')) { |
... | ... | |
1440 | 1459 |
} |
1441 | 1460 |
|
1442 | 1461 |
$v_devmajor = ''; |
1443 |
|
|
1444 | 1462 |
$v_devminor = ''; |
1445 |
|
|
1446 | 1463 |
$v_prefix = ''; |
1447 | 1464 |
|
1448 | 1465 |
$v_binary_data_first = pack( |
1449 | 1466 |
"a100a8a8a8a12a12", |
1450 |
$v_reduce_filename, |
|
1467 |
$v_reduced_filename,
|
|
1451 | 1468 |
$v_perms, |
1452 | 1469 |
$v_uid, |
1453 | 1470 |
$v_gid, |
... | ... | |
1487 | 1504 |
$this->_writeBlock($v_binary_data_first, 148); |
1488 | 1505 |
|
1489 | 1506 |
// ----- Write the calculated checksum |
1490 |
$v_checksum = sprintf("%06s ", DecOct($v_checksum)); |
|
1507 |
$v_checksum = sprintf("%06s\0 ", DecOct($v_checksum));
|
|
1491 | 1508 |
$v_binary_data = pack("a8", $v_checksum); |
1492 | 1509 |
$this->_writeBlock($v_binary_data, 8); |
1493 | 1510 |
|
... | ... | |
1519 | 1536 |
$p_filename = $this->_pathReduction($p_filename); |
1520 | 1537 |
|
1521 | 1538 |
if (strlen($p_filename) > 99) { |
1522 |
if (!$this->_writeLongHeader($p_filename)) { |
|
1539 |
if (!$this->_writeLongHeader($p_filename, false)) {
|
|
1523 | 1540 |
return false; |
1524 | 1541 |
} |
1525 | 1542 |
} |
... | ... | |
1615 | 1632 |
* @param string $p_filename |
1616 | 1633 |
* @return bool |
1617 | 1634 |
*/ |
1618 |
public function _writeLongHeader($p_filename) |
|
1635 |
public function _writeLongHeader($p_filename, $is_link = false)
|
|
1619 | 1636 |
{ |
1620 |
$v_size = sprintf("%11s ", DecOct(strlen($p_filename))); |
|
1621 |
|
|
1622 |
$v_typeflag = 'L'; |
|
1623 |
|
|
1637 |
$v_uid = sprintf("%07s", 0); |
|
1638 |
$v_gid = sprintf("%07s", 0); |
|
1639 |
$v_perms = sprintf("%07s", 0); |
|
1640 |
$v_size = sprintf("%'011s", DecOct(strlen($p_filename))); |
|
1641 |
$v_mtime = sprintf("%011s", 0); |
|
1642 |
$v_typeflag = ($is_link ? 'K' : 'L'); |
|
1624 | 1643 |
$v_linkname = ''; |
1625 |
|
|
1626 |
$v_magic = ''; |
|
1627 |
|
|
1628 |
$v_version = ''; |
|
1629 |
|
|
1644 |
$v_magic = 'ustar '; |
|
1645 |
$v_version = ' '; |
|
1630 | 1646 |
$v_uname = ''; |
1631 |
|
|
1632 | 1647 |
$v_gname = ''; |
1633 |
|
|
1634 | 1648 |
$v_devmajor = ''; |
1635 |
|
|
1636 | 1649 |
$v_devminor = ''; |
1637 |
|
|
1638 | 1650 |
$v_prefix = ''; |
1639 | 1651 |
|
1640 | 1652 |
$v_binary_data_first = pack( |
1641 | 1653 |
"a100a8a8a8a12a12", |
1642 | 1654 |
'././@LongLink', |
1643 |
0,
|
|
1644 |
0,
|
|
1645 |
0,
|
|
1655 |
$v_perms,
|
|
1656 |
$v_uid,
|
|
1657 |
$v_gid,
|
|
1646 | 1658 |
$v_size, |
1647 |
0
|
|
1659 |
$v_mtime
|
|
1648 | 1660 |
); |
1649 | 1661 |
$v_binary_data_last = pack( |
1650 | 1662 |
"a1a100a6a2a32a32a8a8a155a12", |
... | ... | |
1679 | 1691 |
$this->_writeBlock($v_binary_data_first, 148); |
1680 | 1692 |
|
1681 | 1693 |
// ----- Write the calculated checksum |
1682 |
$v_checksum = sprintf("%06s ", DecOct($v_checksum)); |
|
1694 |
$v_checksum = sprintf("%06s\0 ", DecOct($v_checksum));
|
|
1683 | 1695 |
$v_binary_data = pack("a8", $v_checksum); |
1684 | 1696 |
$this->_writeBlock($v_binary_data, 8); |
1685 | 1697 |
|
... | ... | |
1720 | 1732 |
// ----- Calculate the checksum |
1721 | 1733 |
$v_checksum = 0; |
1722 | 1734 |
// ..... First part of the header |
1723 |
for ($i = 0; $i < 148; $i++) { |
|
1724 |
$v_checksum += ord(substr($v_binary_data, $i, 1)); |
|
1725 |
} |
|
1726 |
// ..... Ignore the checksum value and replace it by ' ' (space) |
|
1727 |
for ($i = 148; $i < 156; $i++) { |
|
1728 |
$v_checksum += ord(' '); |
|
1729 |
} |
|
1730 |
// ..... Last part of the header |
|
1731 |
for ($i = 156; $i < 512; $i++) { |
|
1732 |
$v_checksum += ord(substr($v_binary_data, $i, 1)); |
|
1733 |
} |
|
1735 |
$v_binary_split = str_split($v_binary_data); |
|
1736 |
$v_checksum += array_sum(array_map('ord', array_slice($v_binary_split, 0, 148))); |
|
1737 |
$v_checksum += array_sum(array_map('ord', array(' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',))); |
|
1738 |
$v_checksum += array_sum(array_map('ord', array_slice($v_binary_split, 156, 512))); |
|
1734 | 1739 |
|
1735 |
if (version_compare(PHP_VERSION, "5.5.0-dev") < 0) { |
|
1736 |
$fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" . |
|
1737 |
"a8checksum/a1typeflag/a100link/a6magic/a2version/" . |
|
1738 |
"a32uname/a32gname/a8devmajor/a8devminor/a131prefix"; |
|
1739 |
} else { |
|
1740 |
$fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" . |
|
1741 |
"Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" . |
|
1742 |
"Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix"; |
|
1743 |
} |
|
1744 |
$v_data = unpack($fmt, $v_binary_data); |
|
1740 |
|
|
1741 |
$v_data = unpack($this->_fmt, $v_binary_data); |
|
1745 | 1742 |
|
1746 | 1743 |
if (strlen($v_data["prefix"]) > 0) { |
1747 | 1744 |
$v_data["filename"] = "$v_data[prefix]/$v_data[filename]"; |
... | ... | |
1777 | 1774 |
$v_header['mode'] = OctDec(trim($v_data['mode'])); |
1778 | 1775 |
$v_header['uid'] = OctDec(trim($v_data['uid'])); |
1779 | 1776 |
$v_header['gid'] = OctDec(trim($v_data['gid'])); |
1780 |
$v_header['size'] = OctDec(trim($v_data['size']));
|
|
1777 |
$v_header['size'] = $this->_tarRecToSize($v_data['size']);
|
|
1781 | 1778 |
$v_header['mtime'] = OctDec(trim($v_data['mtime'])); |
1782 | 1779 |
if (($v_header['typeflag'] = $v_data['typeflag']) == "5") { |
1783 | 1780 |
$v_header['size'] = 0; |
... | ... | |
1796 | 1793 |
return true; |
1797 | 1794 |
} |
1798 | 1795 |
|
1796 |
/** |
|
1797 |
* Convert Tar record size to actual size |
|
1798 |
* |
|
1799 |
* @param string $tar_size |
|
1800 |
* @return size of tar record in bytes |
|
1801 |
*/ |
|
1802 |
private function _tarRecToSize($tar_size) |
|
1803 |
{ |
|
1804 |
/* |
|
1805 |
* First byte of size has a special meaning if bit 7 is set. |
|
1806 |
* |
|
1807 |
* Bit 7 indicates base-256 encoding if set. |
|
1808 |
* Bit 6 is the sign bit. |
|
1809 |
* Bits 5:0 are most significant value bits. |
|
1810 |
*/ |
|
1811 |
$ch = ord($tar_size[0]); |
|
1812 |
if ($ch & 0x80) { |
|
1813 |
// Full 12-bytes record is required. |
|
1814 |
$rec_str = $tar_size . "\x00"; |
|
1815 |
|
|
1816 |
$size = ($ch & 0x40) ? -1 : 0; |
|
1817 |
$size = ($size << 6) | ($ch & 0x3f); |
|
1818 |
|
|
1819 |
for ($num_ch = 1; $num_ch < 12; ++$num_ch) { |
|
1820 |
$size = ($size * 256) + ord($rec_str[$num_ch]); |
|
1821 |
} |
|
1822 |
|
|
1823 |
return $size; |
|
1824 |
|
|
1825 |
} else { |
|
1826 |
return OctDec(trim($tar_size)); |
|
1827 |
} |
|
1828 |
} |
|
1829 |
|
|
1799 | 1830 |
/** |
1800 | 1831 |
* Detect and report a malicious file name |
1801 | 1832 |
* |
... | ... | |
1805 | 1836 |
*/ |
1806 | 1837 |
private function _maliciousFilename($file) |
1807 | 1838 |
{ |
1808 |
if (strpos($file, '/../') !== false) {
|
|
1839 |
if (strpos($file, 'phar://') === 0) {
|
|
1809 | 1840 |
return true; |
1810 | 1841 |
} |
1811 |
if (strpos($file, '../') === 0) { |
|
1842 |
if (strpos($file, DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR) !== false) { |
|
1843 |
return true; |
|
1844 |
} |
|
1845 |
if (strpos($file, '..' . DIRECTORY_SEPARATOR) === 0) { |
|
1812 | 1846 |
return true; |
1813 | 1847 |
} |
1814 | 1848 |
return false; |
... | ... | |
1873 | 1907 |
continue; |
1874 | 1908 |
} |
1875 | 1909 |
|
1876 |
// ----- Look for long filename |
|
1877 |
if ($v_header['typeflag'] == 'L') { |
|
1878 |
if (!$this->_readLongHeader($v_header)) { |
|
1879 |
return null; |
|
1880 |
} |
|
1910 |
switch ($v_header['typeflag']) { |
|
1911 |
case 'L': { |
|
1912 |
if (!$this->_readLongHeader($v_header)) { |
|
1913 |
return null; |
|
1914 |
} |
|
1915 |
} break; |
|
1916 |
|
|
1917 |
case 'K': { |
|
1918 |
$v_link_header = $v_header; |
|
1919 |
if (!$this->_readLongHeader($v_link_header)) { |
|
1920 |
return null; |
|
1921 |
} |
|
1922 |
$v_header['link'] = $v_link_header['filename']; |
|
1923 |
} break; |
|
1881 | 1924 |
} |
1882 | 1925 |
|
1883 | 1926 |
if ($v_header['filename'] == $p_filename) { |
... | ... | |
1978 | 2021 |
continue; |
1979 | 2022 |
} |
1980 | 2023 |
|
1981 |
// ----- Look for long filename |
|
1982 |
if ($v_header['typeflag'] == 'L') { |
|
1983 |
if (!$this->_readLongHeader($v_header)) { |
|
1984 |
return false; |
|
1985 |
} |
|
2024 |
switch ($v_header['typeflag']) { |
|
2025 |
case 'L': { |
|
2026 |
if (!$this->_readLongHeader($v_header)) { |
|
2027 |
return null; |
|
2028 |
} |
|
2029 |
} break; |
|
2030 |
|
|
2031 |
case 'K': { |
|
2032 |
$v_link_header = $v_header; |
|
2033 |
if (!$this->_readLongHeader($v_link_header)) { |
|
2034 |
return null; |
|
2035 |
} |
|
2036 |
$v_header['link'] = $v_link_header['filename']; |
|
2037 |
} break; |
|
1986 | 2038 |
} |
1987 | 2039 |
|
1988 | 2040 |
// ignore extended / pax headers |
Also available in: Unified diff
MAJ 7.60 -> 7.62