44if (!class_exists(
'PEAR')) {
45 require_once
'PEAR.php';
48define(
'ARCHIVE_TAR_ATT_SEPARATOR', 90001);
49define(
'ARCHIVE_TAR_END_BLOCK', pack(
"a512",
''));
131 parent::__construct();
133 $this->_compress =
false;
134 $this->_compress_type =
'none';
135 if (($p_compress ===
null) || ($p_compress ==
'')) {
136 if (@file_exists($p_tarname)) {
137 if ($fp = @fopen($p_tarname,
"rb")) {
139 $data = fread($fp, 2);
141 if ($data ==
"\37\213") {
142 $this->_compress =
true;
143 $this->_compress_type =
'gz';
145 } elseif ($data ==
"BZ") {
146 $this->_compress =
true;
147 $this->_compress_type =
'bz2';
148 } elseif (file_get_contents($p_tarname,
false,
null, 1, 4) ==
'7zXZ') {
149 $this->_compress =
true;
150 $this->_compress_type =
'lzma2';
156 if (substr($p_tarname, -2) ==
'gz') {
157 $this->_compress =
true;
158 $this->_compress_type =
'gz';
159 } elseif ((substr($p_tarname, -3) ==
'bz2') ||
160 (substr($p_tarname, -2) ==
'bz')
162 $this->_compress =
true;
163 $this->_compress_type =
'bz2';
165 if (substr($p_tarname, -2) ==
'xz') {
166 $this->_compress =
true;
167 $this->_compress_type =
'lzma2';
172 if (($p_compress ===
true) || ($p_compress ==
'gz')) {
173 $this->_compress =
true;
174 $this->_compress_type =
'gz';
176 if ($p_compress ==
'bz2') {
177 $this->_compress =
true;
178 $this->_compress_type =
'bz2';
180 if ($p_compress ==
'lzma2') {
181 $this->_compress =
true;
182 $this->_compress_type =
'lzma2';
185 "Unsupported compression type '$p_compress'\n" .
186 "Supported types are 'gz', 'bz2' and 'lzma2'.\n"
193 $this->_tarname = $p_tarname;
194 if ($this->_compress) {
195 if ($this->_compress_type ==
'gz') {
198 if ($this->_compress_type ==
'bz2') {
201 if ($this->_compress_type ==
'lzma2') {
207 if (!extension_loaded($extname)) {
210 if (!extension_loaded($extname)) {
212 "The extension '$extname' couldn't be found.\n" .
213 "Please make sure your version of PHP was built " .
214 "with '$extname' support.\n"
221 if (version_compare(PHP_VERSION,
"5.5.0-dev") < 0) {
222 $this->_fmt =
"a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" .
223 "a8checksum/a1typeflag/a100link/a6magic/a2version/" .
224 "a32uname/a32gname/a8devmajor/a8devminor/a131prefix";
226 $this->_fmt =
"Z100filename/Z8mode/Z8uid/Z8gid/a12size/Z12mtime/" .
227 "Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" .
228 "Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix";
239 if ($this->_temp_tarname !=
'' && (
bool) preg_match(
'/^tar[[:alnum:]]*\.tmp$/', $this->_temp_tarname)) {
240 @unlink($this->_temp_tarname);
286 public function add($p_filelist)
288 return $this->
addModify($p_filelist,
'',
'');
297 public function extract($p_path =
'', $p_preserve =
false, $p_symlinks =
true)
299 return $this->
extractModify($p_path,
'', $p_preserve, $p_symlinks);
307 $v_list_detail = array();
310 if (!$this->
_extractList(
'', $v_list_detail,
"list",
'',
'')) {
311 unset($v_list_detail);
317 return $v_list_detail;
355 public function createModify($p_filelist, $p_add_dir, $p_remove_dir =
'')
363 if ($p_filelist !=
'') {
364 if (is_array($p_filelist)) {
365 $v_list = $p_filelist;
366 } elseif (is_string($p_filelist)) {
367 $v_list = explode($this->_separator, $p_filelist);
370 $this->
_error(
'Invalid file list');
374 $v_result = $this->
_addList($v_list, $p_add_dir, $p_remove_dir);
427 public function addModify($p_filelist, $p_add_dir, $p_remove_dir =
'')
438 if (is_array($p_filelist)) {
439 $v_list = $p_filelist;
440 } elseif (is_string($p_filelist)) {
441 $v_list = explode($this->_separator, $p_filelist);
443 $this->
_error(
'Invalid file list');
447 $v_result = $this->
_append($v_list, $p_add_dir, $p_remove_dir);
480 public function addString($p_filename, $p_string, $p_datetime =
false, $p_params = array())
482 $p_stamp = @$p_params[
"stamp"] ? $p_params[
"stamp"] : ($p_datetime ? $p_datetime : time());
483 $p_mode = @$p_params[
"mode"] ? $p_params[
"mode"] : 0600;
484 $p_type = @$p_params[
"type"] ? $p_params[
"type"] :
"";
485 $p_uid = @$p_params[
"uid"] ? $p_params[
"uid"] :
"";
486 $p_gid = @$p_params[
"gid"] ? $p_params[
"gid"] :
"";
501 $v_result = $this->
_addString($p_filename, $p_string, $p_datetime, $p_params);
545 public function extractModify($p_path, $p_remove_path, $p_preserve =
false, $p_symlinks =
true)
548 $v_list_detail = array();
607 public function extractList($p_filelist, $p_path =
'', $p_remove_path =
'', $p_preserve =
false, $p_symlinks =
true)
610 $v_list_detail = array();
612 if (is_array($p_filelist)) {
613 $v_list = $p_filelist;
614 } elseif (is_string($p_filelist)) {
615 $v_list = explode($this->_separator, $p_filelist);
617 $this->
_error(
'Invalid string list');
649 if (($v_size = func_num_args()) == 0) {
654 $v_att_list = func_get_args();
658 while ($i < $v_size) {
661 switch ($v_att_list[$i]) {
665 if (($i + 1) >= $v_size) {
667 'Invalid number of parameters for '
668 .
'attribute ARCHIVE_TAR_ATT_SEPARATOR'
674 $this->_separator = $v_att_list[$i + 1];
679 $this->
_error(
'Unknown attribute code ' . $v_att_list[$i] .
'');
699 $this->_ignore_regexp = $regexp;
713 $list = str_replace(array(
'#',
'.',
'^',
'$'), array(
'\#',
'\.',
'\^',
'\$'), $list);
714 $regexp =
'#/' . join(
'$|/', $list) .
'#';
723 $this->error_object = $this->raiseError($p_message);
731 $this->error_object = $this->raiseError($p_message);
740 if ($p_filename ==
null) {
741 $p_filename = $this->_tarname;
744 return @is_file($p_filename) && !@is_link($p_filename);
752 if ($this->_compress_type ==
'gz' && function_exists(
'gzopen')) {
753 $this->_file = @gzopen($this->_tarname,
"wb9");
755 if ($this->_compress_type ==
'bz2' && function_exists(
'bzopen')) {
756 $this->_file = @bzopen($this->_tarname,
"w");
758 if ($this->_compress_type ==
'lzma2' && function_exists(
'xzopen')) {
759 $this->_file = @xzopen($this->_tarname,
'w');
761 if ($this->_compress_type ==
'none') {
762 $this->_file = @fopen($this->_tarname,
"wb");
765 'Unknown or missing compression type ('
766 . $this->_compress_type .
')'
774 if ($this->_file == 0) {
776 'Unable to open in write mode \''
777 . $this->_tarname .
'\''
790 if (strtolower(substr($this->_tarname, 0, 7)) ==
'http://') {
793 if ($this->_temp_tarname ==
'') {
794 $this->_temp_tarname = uniqid(
'tar') .
'.tmp';
795 if (!$v_file_from = @fopen($this->_tarname,
'rb')) {
797 'Unable to open in read mode \''
798 . $this->_tarname .
'\''
800 $this->_temp_tarname =
'';
803 if (!$v_file_to = @fopen($this->_temp_tarname,
'wb')) {
805 'Unable to open in write mode \''
806 . $this->_temp_tarname .
'\''
808 $this->_temp_tarname =
'';
811 while ($v_data = @fread($v_file_from, 1024)) {
812 @fwrite($v_file_to, $v_data);
814 @fclose($v_file_from);
819 $v_filename = $this->_temp_tarname;
823 $v_filename = $this->_tarname;
826 if ($this->_compress_type ==
'gz' && function_exists(
'gzopen')) {
827 $this->_file = @gzopen($v_filename,
"rb");
829 if ($this->_compress_type ==
'bz2' && function_exists(
'bzopen')) {
830 $this->_file = @bzopen($v_filename,
"r");
832 if ($this->_compress_type ==
'lzma2' && function_exists(
'xzopen')) {
833 $this->_file = @xzopen($v_filename,
"r");
835 if ($this->_compress_type ==
'none') {
836 $this->_file = @fopen($v_filename,
"rb");
839 'Unknown or missing compression type ('
840 . $this->_compress_type .
')'
848 if ($this->_file == 0) {
849 $this->
_error(
'Unable to open in read mode \'' . $v_filename .
'\'');
861 if ($this->_compress_type ==
'gz') {
862 $this->_file = @gzopen($this->_tarname,
"r+b");
864 if ($this->_compress_type ==
'bz2') {
866 'Unable to open bz2 in read/write mode \''
867 . $this->_tarname .
'\' (limitation of bz2 extension)
'
871 if ($this->_compress_type == 'lzma2
') {
873 'Unable to open lzma2 in read/write mode \
''
874 . $this->_tarname .
'\' (limitation of lzma2 extension)
'
878 if ($this->_compress_type == 'none
') {
879 $this->_file = @fopen($this->_tarname, "r+b");
882 'Unknown or missing compression type (
'
883 . $this->_compress_type . ')
'
891 if ($this->_file == 0) {
893 'Unable to open in read/write mode \
''
894 . $this->_tarname .
'\''
908 if (is_resource($this->_file)) {
909 if ($this->_compress_type ==
'gz') {
910 @gzclose($this->_file);
912 if ($this->_compress_type ==
'bz2') {
913 @bzclose($this->_file);
915 if ($this->_compress_type ==
'lzma2') {
916 @xzclose($this->_file);
918 if ($this->_compress_type ==
'none') {
919 @fclose($this->_file);
922 'Unknown or missing compression type ('
923 . $this->_compress_type .
')'
935 if ($this->_temp_tarname !=
'') {
936 @unlink($this->_temp_tarname);
937 $this->_temp_tarname =
'';
951 if ($this->_temp_tarname !=
'') {
953 @unlink($this->_temp_tarname);
954 $this->_temp_tarname =
'';
957 @unlink($this->_tarname);
959 $this->_tarname =
'';
971 if (is_resource($this->_file)) {
972 if ($p_len ===
null) {
973 switch ($this->_compress_type)
976 $bytes = @gzwrite($this->_file, $p_binary_data);
979 $bytes = @bzwrite($this->_file, $p_binary_data);
982 $bytes = @xzwrite($this->_file, $p_binary_data);
985 $bytes = @fwrite($this->_file, $p_binary_data);
988 $this->
_error(
'Unknown or missing compression type (' . $this->_compress_type .
')');
992 switch ($this->_compress_type)
995 $bytes = @gzwrite($this->_file, $p_binary_data, $p_len);
998 $bytes = @bzwrite($this->_file, $p_binary_data, $p_len);
1001 $bytes = @xzwrite($this->_file, $p_binary_data, $p_len);
1004 $bytes = @fwrite($this->_file, $p_binary_data, $p_len);
1007 $this->
_error(
'Unknown or missing compression type (' . $this->_compress_type .
')');
1011 return $bytes !==
false;
1022 if (is_resource($this->_file)) {
1023 if ($this->_compress_type ==
'gz') {
1024 $v_block = @gzread($this->_file, 512);
1026 if ($this->_compress_type ==
'bz2') {
1027 $v_block = @bzread($this->_file, 512);
1029 if ($this->_compress_type ==
'lzma2') {
1030 $v_block = @xzread($this->_file, 512);
1032 if ($this->_compress_type ==
'none') {
1033 $v_block = @fread($this->_file, 512);
1036 'Unknown or missing compression type ('
1037 . $this->_compress_type .
')'
1053 if (is_resource($this->_file)) {
1054 if ($p_len ===
null) {
1058 if ($this->_compress_type ==
'gz') {
1059 @gzseek($this->_file, gztell($this->_file) + ($p_len * 512));
1061 if ($this->_compress_type ==
'bz2') {
1063 for ($i = 0; $i < $p_len; $i++) {
1067 if ($this->_compress_type ==
'lzma2') {
1069 for ($i = 0; $i < $p_len; $i++) {
1073 if ($this->_compress_type ==
'none') {
1074 @fseek($this->_file, $p_len * 512, SEEK_CUR);
1077 'Unknown or missing compression type ('
1078 . $this->_compress_type .
')'
1093 if (is_resource($this->_file)) {
1095 $v_binary_data = pack(
'a1024',
'');
1107 public function _addList($p_list, $p_add_dir, $p_remove_dir)
1110 $v_header = array();
1116 if (!$this->_file) {
1117 $this->
_error(
'Invalid file descriptor');
1121 if (
sizeof($p_list) == 0) {
1125 foreach ($p_list as $v_filename) {
1131 if ($v_filename == $this->_tarname) {
1135 if ($v_filename ==
'') {
1140 if ($this->_ignore_regexp && preg_match($this->_ignore_regexp,
'/' . $v_filename)) {
1141 $this->
_warning(
"File '$v_filename' ignored");
1145 if (!file_exists($v_filename) && !is_link($v_filename)) {
1146 $this->
_warning(
"File '$v_filename' does not exist");
1151 if (!$this->
_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir)) {
1155 if (@is_dir($v_filename) && !@is_link($v_filename)) {
1156 if (!($p_hdir = opendir($v_filename))) {
1157 $this->
_warning(
"Directory '$v_filename' can not be read");
1160 while (
false !== ($p_hitem = readdir($p_hdir))) {
1161 if (($p_hitem !=
'.') && ($p_hitem !=
'..')) {
1162 if ($v_filename !=
".") {
1163 $p_temp_list[0] = $v_filename .
'/' . $p_hitem;
1165 $p_temp_list[0] = $p_hitem;
1176 unset($p_temp_list);
1193 public function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $v_stored_filename =
null)
1195 if (!$this->_file) {
1196 $this->
_error(
'Invalid file descriptor');
1200 if ($p_filename ==
'') {
1201 $this->
_error(
'Invalid file name');
1205 if (is_null($v_stored_filename)) {
1208 $v_stored_filename = $p_filename;
1210 if (strcmp($p_filename, $p_remove_dir) == 0) {
1214 if ($p_remove_dir !=
'') {
1215 if (substr($p_remove_dir, -1) !=
'/') {
1216 $p_remove_dir .=
'/';
1219 if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) {
1220 $v_stored_filename = substr($p_filename, strlen($p_remove_dir));
1225 if ($p_add_dir !=
'') {
1226 if (substr($p_add_dir, -1) ==
'/') {
1227 $v_stored_filename = $p_add_dir . $v_stored_filename;
1229 $v_stored_filename = $p_add_dir .
'/' . $v_stored_filename;
1237 if (($v_file = @fopen($p_filename,
"rb")) == 0) {
1239 "Unable to open file '" . $p_filename
1240 .
"' in binary read mode"
1245 if (!$this->
_writeHeader($p_filename, $v_stored_filename)) {
1249 while (($v_buffer = fread($v_file, $this->buffer_length)) !=
'') {
1253 $pack_format = sprintf(
'a%d', $pack_size);
1255 $pack_format = sprintf(
'a%d', $this->buffer_length);
1257 $v_binary_data = pack($pack_format,
"$v_buffer");
1266 if (!$this->
_writeHeader($p_filename, $v_stored_filename)) {
1281 public function _addString($p_filename, $p_string, $p_datetime =
false, $p_params = array())
1283 $p_stamp = @$p_params[
"stamp"] ? $p_params[
"stamp"] : ($p_datetime ? $p_datetime : time());
1284 $p_mode = @$p_params[
"mode"] ? $p_params[
"mode"] : 0600;
1285 $p_type = @$p_params[
"type"] ? $p_params[
"type"] :
"";
1286 $p_uid = @$p_params[
"uid"] ? $p_params[
"uid"] : 0;
1287 $p_gid = @$p_params[
"gid"] ? $p_params[
"gid"] : 0;
1288 if (!$this->_file) {
1289 $this->
_error(
'Invalid file descriptor');
1293 if ($p_filename ==
'') {
1294 $this->
_error(
'Invalid file name');
1302 if ($p_datetime ===
false) {
1303 $p_datetime = time();
1320 while (($v_buffer = substr($p_string, (($i++) * 512), 512)) !=
'') {
1321 $v_binary_data = pack(
"a512", $v_buffer);
1337 if ($p_stored_filename ==
'') {
1338 $p_stored_filename = $p_filename;
1343 if (strlen($v_reduced_filename) > 99) {
1350 if (@is_link($p_filename)) {
1351 $v_linkname = readlink($p_filename);
1354 if (strlen($v_linkname) > 99) {
1360 $v_info = lstat($p_filename);
1361 $v_uid = sprintf(
"%07s", DecOct($v_info[4]));
1362 $v_gid = sprintf(
"%07s", DecOct($v_info[5]));
1363 $v_perms = sprintf(
"%07s", DecOct($v_info[
'mode'] & 000777));
1364 $v_mtime = sprintf(
"%011s", DecOct($v_info[
'mtime']));
1366 if (@is_link($p_filename)) {
1368 $v_size = sprintf(
"%011s", DecOct(0));
1369 } elseif (@is_dir($p_filename)) {
1371 $v_size = sprintf(
"%011s", DecOct(0));
1375 $v_size = sprintf(
"%011s", DecOct($v_info[
'size']));
1378 $v_magic =
'ustar ';
1383 if (function_exists(
'posix_getpwuid')) {
1384 $userinfo = posix_getpwuid($v_info[4]);
1385 $groupinfo = posix_getgrgid($v_info[5]);
1387 if (isset($userinfo[
'name'])) {
1388 $v_uname = $userinfo[
'name'];
1391 if (isset($groupinfo[
'name'])) {
1392 $v_gname = $groupinfo[
'name'];
1400 $v_binary_data_first = pack(
1402 $v_reduced_filename,
1409 $v_binary_data_last = pack(
1410 "a1a100a6a2a32a32a8a8a155a12",
1426 for ($i = 0; $i < 148; $i++) {
1427 $v_checksum += ord(substr($v_binary_data_first, $i, 1));
1430 for ($i = 148; $i < 156; $i++) {
1431 $v_checksum += ord(
' ');
1434 for ($i = 156, $j = 0; $i < 512; $i++, $j++) {
1435 $v_checksum += ord(substr($v_binary_data_last, $j, 1));
1442 $v_checksum = sprintf(
"%06s\0 ", DecOct($v_checksum));
1443 $v_binary_data = pack(
"a8", $v_checksum);
1474 if (strlen($p_filename) > 99) {
1480 if ($p_type ==
"5") {
1481 $v_size = sprintf(
"%011s", DecOct(0));
1483 $v_size = sprintf(
"%011s", DecOct($p_size));
1486 $v_uid = sprintf(
"%07s", DecOct($p_uid));
1487 $v_gid = sprintf(
"%07s", DecOct($p_gid));
1488 $v_perms = sprintf(
"%07s", DecOct($p_perms & 000777));
1490 $v_mtime = sprintf(
"%11s", DecOct($p_mtime));
1494 $v_magic =
'ustar ';
1498 if (function_exists(
'posix_getpwuid')) {
1499 $userinfo = posix_getpwuid($p_uid);
1500 $groupinfo = posix_getgrgid($p_gid);
1502 if ($userinfo ===
false || $groupinfo ===
false) {
1506 $v_uname = $userinfo[
'name'];
1507 $v_gname = $groupinfo[
'name'];
1520 $v_binary_data_first = pack(
1529 $v_binary_data_last = pack(
1530 "a1a100a6a2a32a32a8a8a155a12",
1546 for ($i = 0; $i < 148; $i++) {
1547 $v_checksum += ord(substr($v_binary_data_first, $i, 1));
1550 for ($i = 148; $i < 156; $i++) {
1551 $v_checksum += ord(
' ');
1554 for ($i = 156, $j = 0; $i < 512; $i++, $j++) {
1555 $v_checksum += ord(substr($v_binary_data_last, $j, 1));
1562 $v_checksum = sprintf(
"%06s ", DecOct($v_checksum));
1563 $v_binary_data = pack(
"a8", $v_checksum);
1578 $v_uid = sprintf(
"%07s", 0);
1579 $v_gid = sprintf(
"%07s", 0);
1580 $v_perms = sprintf(
"%07s", 0);
1581 $v_size = sprintf(
"%'011s", DecOct(strlen($p_filename)));
1582 $v_mtime = sprintf(
"%011s", 0);
1583 $v_typeflag = ($is_link ?
'K' :
'L');
1585 $v_magic =
'ustar ';
1593 $v_binary_data_first = pack(
1602 $v_binary_data_last = pack(
1603 "a1a100a6a2a32a32a8a8a155a12",
1619 for ($i = 0; $i < 148; $i++) {
1620 $v_checksum += ord(substr($v_binary_data_first, $i, 1));
1623 for ($i = 148; $i < 156; $i++) {
1624 $v_checksum += ord(
' ');
1627 for ($i = 156, $j = 0; $i < 512; $i++, $j++) {
1628 $v_checksum += ord(substr($v_binary_data_last, $j, 1));
1635 $v_checksum = sprintf(
"%06s\0 ", DecOct($v_checksum));
1636 $v_binary_data = pack(
"a8", $v_checksum);
1644 while (($v_buffer = substr($p_filename, (($i++) * 512), 512)) !=
'') {
1645 $v_binary_data = pack(
"a512",
"$v_buffer");
1659 if (strlen($v_binary_data) == 0) {
1660 $v_header[
'filename'] =
'';
1664 if (strlen($v_binary_data) != 512) {
1665 $v_header[
'filename'] =
'';
1666 $this->
_error(
'Invalid block size : ' . strlen($v_binary_data));
1670 if (!is_array($v_header)) {
1671 $v_header = array();
1676 $v_binary_split = str_split($v_binary_data);
1677 $v_checksum += array_sum(array_map(
'ord', array_slice($v_binary_split, 0, 148)));
1678 $v_checksum += array_sum(array_map(
'ord', array(
' ',
' ',
' ',
' ',
' ',
' ',
' ',
' ',)));
1679 $v_checksum += array_sum(array_map(
'ord', array_slice($v_binary_split, 156, 512)));
1682 $v_data = unpack($this->_fmt, $v_binary_data);
1684 if (strlen($v_data[
"prefix"]) > 0) {
1685 $v_data[
"filename"] =
"$v_data[prefix]/$v_data[filename]";
1689 $v_data_checksum = trim($v_data[
'checksum']);
1690 if (!preg_match(
'/^[0-7]*$/', $v_data_checksum)) {
1692 'Invalid checksum for file "' . $v_data[
'filename']
1693 .
'" : ' . $v_data_checksum .
' extracted'
1698 $v_header[
'checksum'] = OctDec($v_data_checksum);
1699 if ($v_header[
'checksum'] != $v_checksum) {
1700 $v_header[
'filename'] =
'';
1703 if (($v_checksum == 256) && ($v_header[
'checksum'] == 0)) {
1708 'Invalid checksum for file "' . $v_data[
'filename']
1709 .
'" : ' . $v_checksum .
' calculated, '
1710 . $v_header[
'checksum'] .
' expected'
1716 $v_header[
'filename'] = rtrim($v_data[
'filename'],
"\0");
1719 'Malicious .tar detected, file "' . $v_header[
'filename'] .
1720 '" will not install in desired directory tree'
1724 $v_header[
'mode'] = OctDec(trim($v_data[
'mode']));
1725 $v_header[
'uid'] = OctDec(trim($v_data[
'uid']));
1726 $v_header[
'gid'] = OctDec(trim($v_data[
'gid']));
1728 $v_header[
'mtime'] = OctDec(trim($v_data[
'mtime']));
1729 if (($v_header[
'typeflag'] = $v_data[
'typeflag']) ==
"5") {
1730 $v_header[
'size'] = 0;
1732 $v_header[
'link'] = trim($v_data[
'link']);
1761 $ch = ord($tar_size[0]);
1764 $rec_str = $tar_size .
"\x00";
1766 $size = ($ch & 0x40) ? -1 : 0;
1767 $size = ($size << 6) | ($ch & 0x3f);
1769 for ($num_ch = 1; $num_ch < 12; ++$num_ch) {
1770 $size = ($size * 256) + ord($rec_str[$num_ch]);
1776 return OctDec(trim($tar_size));
1789 if (strpos($file,
'://') !==
false) {
1792 if (strpos($file,
'../') !==
false || strpos($file,
'..\\') !==
false) {
1805 $v_filesize = $v_header[
'size'];
1806 $n = floor($v_header[
'size'] / 512);
1807 for ($i = 0; $i < $n; $i++) {
1809 $v_filename .= $v_content;
1811 if (($v_header[
'size'] % 512) != 0) {
1813 $v_filename .= $v_content;
1819 if (!$this->
_readHeader($v_binary_data, $v_header)) {
1823 $v_filename = rtrim(substr($v_filename, 0, $v_filesize),
"\0");
1824 $v_header[
'filename'] = $v_filename;
1827 'Malicious .tar detected, file "' . $v_filename .
1828 '" will not install in desired directory tree'
1848 while (strlen($v_binary_data = $this->
_readBlock()) != 0) {
1849 if (!$this->
_readHeader($v_binary_data, $v_header)) {
1853 if ($v_header[
'filename'] ==
'') {
1857 switch ($v_header[
'typeflag']) {
1868 $v_link_header = $v_header;
1872 $v_header[
'link'] = $v_link_header[
'filename'];
1877 if ($v_header[
'filename'] == $p_filename) {
1878 if ($v_header[
'typeflag'] ==
"5") {
1880 'Unable to extract in string a directory '
1881 .
'entry {' . $v_header[
'filename'] .
'}'
1885 $n = floor($v_header[
'size'] / 512);
1886 for ($i = 0; $i < $n; $i++) {
1889 if (($v_header[
'size'] % 512) != 0) {
1891 $v_result_str .= substr(
1894 ($v_header[
'size'] % 512)
1897 return $v_result_str;
1900 $this->
_jumpBlock(ceil(($v_header[
'size'] / 512)));
1923 $p_preserve =
false,
1929 $v_extract_all =
true;
1933 if ($p_path ==
'' || (substr($p_path, 0, 1) !=
'/'
1934 && substr($p_path, 0, 3) !=
"../" && !strpos($p_path,
':'))
1936 $p_path =
"./" . $p_path;
1941 if (($p_remove_path !=
'') && (substr($p_remove_path, -1) !=
'/')) {
1942 $p_remove_path .=
'/';
1944 $p_remove_path_size = strlen($p_remove_path);
1948 $v_extract_all =
true;
1952 $v_extract_all =
false;
1956 $v_extract_all =
false;
1960 $this->
_error(
'Invalid extract mode (' . $p_mode .
')');
1966 while (strlen($v_binary_data = $this->
_readBlock()) != 0) {
1967 $v_extract_file =
false;
1968 $v_extraction_stopped = 0;
1970 if (!$this->
_readHeader($v_binary_data, $v_header)) {
1974 if ($v_header[
'filename'] ==
'') {
1978 switch ($v_header[
'typeflag']) {
1989 $v_link_header = $v_header;
1993 $v_header[
'link'] = $v_link_header[
'filename'];
1999 if ($v_header[
'typeflag'] ==
'x' || $v_header[
'typeflag'] ==
'g') {
2000 $this->
_jumpBlock(ceil(($v_header[
'size'] / 512)));
2004 if ((!$v_extract_all) && (is_array($p_file_list))) {
2006 $v_extract_file =
false;
2008 for ($i = 0; $i <
sizeof($p_file_list); $i++) {
2010 if (substr($p_file_list[$i], -1) ==
'/') {
2012 if ((strlen($v_header[
'filename']) > strlen($p_file_list[$i]))
2013 && (substr($v_header[
'filename'], 0, strlen($p_file_list[$i]))
2014 == $p_file_list[$i])
2016 $v_extract_file =
true;
2020 elseif ($p_file_list[$i] == $v_header[
'filename']) {
2021 $v_extract_file =
true;
2026 $v_extract_file =
true;
2030 if (($v_extract_file) && (!$v_listing)) {
2031 if (($p_remove_path !=
'')
2032 && (substr($v_header[
'filename'] .
'/', 0, $p_remove_path_size)
2035 $v_header[
'filename'] = substr(
2036 $v_header[
'filename'],
2039 if ($v_header[
'filename'] ==
'') {
2043 if (($p_path !=
'./') && ($p_path !=
'/')) {
2044 while (substr($p_path, -1) ==
'/') {
2045 $p_path = substr($p_path, 0, strlen($p_path) - 1);
2048 if (substr($v_header[
'filename'], 0, 1) ==
'/') {
2049 $v_header[
'filename'] = $p_path . $v_header[
'filename'];
2051 $v_header[
'filename'] = $p_path .
'/' . $v_header[
'filename'];
2054 if (file_exists($v_header[
'filename'])) {
2055 if ((@is_dir($v_header[
'filename']))
2056 && ($v_header[
'typeflag'] ==
'')
2059 'File ' . $v_header[
'filename']
2060 .
' already exists as a directory'
2064 if (($this->
_isArchive($v_header[
'filename']))
2065 && ($v_header[
'typeflag'] ==
"5")
2068 'Directory ' . $v_header[
'filename']
2069 .
' already exists as a file'
2073 if (!is_writeable($v_header[
'filename'])) {
2075 'File ' . $v_header[
'filename']
2076 .
' already exists and is write protected'
2080 if (filemtime($v_header[
'filename']) > $v_header[
'mtime']) {
2086 ($v_header[
'typeflag'] ==
"5"
2087 ? $v_header[
'filename']
2088 : dirname($v_header[
'filename']))
2091 $this->
_error(
'Unable to create path for ' . $v_header[
'filename']);
2095 if ($v_extract_file) {
2096 if ($v_header[
'typeflag'] ==
"5") {
2097 if (!@file_exists($v_header[
'filename'])) {
2098 if (!@mkdir($v_header[
'filename'], 0775)) {
2100 'Unable to create directory {'
2101 . $v_header[
'filename'] .
'}'
2106 } elseif ($v_header[
'typeflag'] ==
"2") {
2108 $this->
_warning(
'Symbolic links are not allowed. '
2109 .
'Unable to extract {'
2110 . $v_header[
'filename'] .
'}'
2114 $absolute_link = FALSE;
2116 if (strpos($v_header[
'link'],
"/") === 0 || strpos($v_header[
'link'],
':') !== FALSE) {
2117 $absolute_link = TRUE;
2120 $s_filename = preg_replace(
'@^' . preg_quote($p_path) .
'@',
"", $v_header[
'filename']);
2121 $s_linkname = str_replace(
'\\',
'/', $v_header[
'link']);
2122 foreach (explode(
"/", $s_filename) as $dir) {
2123 if ($dir ===
"..") {
2125 } elseif ($dir !==
"" && $dir !==
"." ) {
2129 foreach (explode(
"/", $s_linkname) as $dir){
2130 if ($link_depth <= 0) {
2133 if ($dir ===
"..") {
2135 } elseif ($dir !==
"" && $dir !==
".") {
2140 if ($absolute_link || $link_depth <= 0) {
2142 'Out-of-path file extraction {'
2143 . $v_header[
'filename'] .
' --> ' .
2144 $v_header[
'link'] .
'}'
2148 if (@file_exists($v_header[
'filename'])) {
2149 @unlink($v_header[
'filename']);
2151 if (!@symlink($v_header[
'link'], $v_header[
'filename'])) {
2153 'Unable to extract symbolic link {'
2154 . $v_header[
'filename'] .
'}'
2159 if (($v_dest_file = @fopen($v_header[
'filename'],
"wb")) == 0) {
2161 'Error while opening {' . $v_header[
'filename']
2162 .
'} in write binary mode'
2166 $n = floor($v_header[
'size'] / 512);
2167 for ($i = 0; $i < $n; $i++) {
2169 fwrite($v_dest_file, $v_content, 512);
2171 if (($v_header[
'size'] % 512) != 0) {
2173 fwrite($v_dest_file, $v_content, ($v_header[
'size'] % 512));
2176 @fclose($v_dest_file);
2179 @chown($v_header[
'filename'], $v_header[
'uid']);
2180 @chgrp($v_header[
'filename'], $v_header[
'gid']);
2184 @touch($v_header[
'filename'], $v_header[
'mtime']);
2185 if ($v_header[
'mode'] & 0111) {
2187 $mode = fileperms($v_header[
'filename']) | (~umask() & 0111);
2188 @chmod($v_header[
'filename'], $mode);
2194 if (!is_file($v_header[
'filename'])) {
2196 'Extracted file ' . $v_header[
'filename']
2197 .
'does not exist. Archive may be corrupted.'
2202 $filesize = filesize($v_header[
'filename']);
2203 if ($filesize != $v_header[
'size']) {
2205 'Extracted file ' . $v_header[
'filename']
2206 .
' does not have the correct file size \''
2208 .
'\' (
' . $v_header['size
']
2209 . ' expected). Archive may be corrupted.
'
2215 $this->_jumpBlock(ceil(($v_header['size
'] / 512)));
2218 $this->_jumpBlock(ceil(($v_header['size
'] / 512)));
2221 /* TBC : Seems to be unused ...
2222 if ($this->_compress)
2223 $v_end_of_file = @gzeof($this->_file);
2225 $v_end_of_file = @feof($this->_file);
2228 if ($v_listing || $v_extract_file || $v_extraction_stopped) {
2229 // ----- Log extracted files
2230 if (($v_file_dir = dirname($v_header['filename
']))
2231 == $v_header['filename
']
2235 if ((substr($v_header['filename
'], 0, 1) == '/
') && ($v_file_dir == '')) {
2239 $p_list_detail[$v_nb++] = $v_header;
2240 if (is_array($p_file_list) && (count($p_list_detail) == count($p_file_list))) {
2252 public function _openAppend()
2254 if (filesize($this->_tarname) == 0) {
2255 return $this->_openWrite();
2258 if ($this->_compress) {
2261 if (!@rename($this->_tarname, $this->_tarname . ".tmp")) {
2263 'Error
while renaming \
'' . $this->_tarname
2264 .
'\' to temporary file \
'' . $this->_tarname
2270 if ($this->_compress_type ==
'gz') {
2271 $v_temp_tar = @gzopen($this->_tarname .
".tmp",
"rb");
2272 } elseif ($this->_compress_type ==
'bz2') {
2273 $v_temp_tar = @bzopen($this->_tarname .
".tmp",
"r");
2274 } elseif ($this->_compress_type ==
'lzma2') {
2275 $v_temp_tar = @xzopen($this->_tarname .
".tmp",
"r");
2279 if ($v_temp_tar == 0) {
2281 'Unable to open file \'' . $this->_tarname
2282 .
'.tmp\' in binary read mode'
2284 @rename($this->_tarname .
".tmp", $this->_tarname);
2289 @rename($this->_tarname .
".tmp", $this->_tarname);
2293 if ($this->_compress_type ==
'gz') {
2296 while (!@gzeof($v_temp_tar)) {
2297 $v_buffer = @gzread($v_temp_tar, 512);
2303 } elseif ($end_blocks > 0) {
2304 for ($i = 0; $i < $end_blocks; $i++) {
2309 $v_binary_data = pack(
"a512", $v_buffer);
2313 @gzclose($v_temp_tar);
2314 } elseif ($this->_compress_type ==
'bz2') {
2317 while (strlen($v_buffer = @bzread($v_temp_tar, 512)) > 0) {
2323 } elseif ($end_blocks > 0) {
2324 for ($i = 0; $i < $end_blocks; $i++) {
2329 $v_binary_data = pack(
"a512", $v_buffer);
2333 @bzclose($v_temp_tar);
2334 } elseif ($this->_compress_type ==
'lzma2') {
2337 while (strlen($v_buffer = @xzread($v_temp_tar, 512)) > 0) {
2343 } elseif ($end_blocks > 0) {
2344 for ($i = 0; $i < $end_blocks; $i++) {
2349 $v_binary_data = pack(
"a512", $v_buffer);
2353 @xzclose($v_temp_tar);
2356 if (!@unlink($this->_tarname .
".tmp")) {
2358 'Error while deleting temporary file \''
2359 . $this->_tarname .
'.tmp\''
2370 $v_size = filesize($this->_tarname);
2375 fseek($this->_file, $v_size - 1024);
2377 fseek($this->_file, $v_size - 1024);
2379 fseek($this->_file, $v_size - 512);
2392 public function _append($p_filelist, $p_add_dir =
'', $p_remove_dir =
'')
2398 if ($this->
_addList($p_filelist, $p_add_dir, $p_remove_dir)) {
2418 if ((@is_dir($p_dir)) || ($p_dir ==
'')) {
2422 $p_parent_dir = dirname($p_dir);
2424 if (($p_parent_dir != $p_dir) &&
2425 ($p_parent_dir !=
'') &&
2431 if (!@mkdir($p_dir, 0775)) {
2432 $this->
_error(
"Unable to create directory '$p_dir'");
2454 $v_list = explode(
'/', $p_dir);
2457 for ($i =
sizeof($v_list) - 1; $i >= 0; $i--) {
2459 if ($v_list[$i] ==
".") {
2463 if ($v_list[$i] ==
"..") {
2467 if (($v_list[$i] ==
'')
2468 && ($i != (
sizeof($v_list) - 1))
2474 $v_result = $v_list[$i] . ($i != (
sizeof($v_list) - 1) ?
'/'
2482 if (defined(
'OS_WINDOWS') && OS_WINDOWS) {
2483 $v_result = strtr($v_result,
'\\',
'/');
2496 if (defined(
'OS_WINDOWS') && OS_WINDOWS) {
2498 if (($p_remove_disk_letter)
2499 && (($v_position = strpos($p_path,
':')) !=
false)
2501 $p_path = substr($p_path, $v_position + 1);
2504 if ((strpos($p_path,
'\\') > 0) || (substr($p_path, 0, 1) ==
'\\')) {
2505 $p_path = strtr($p_path,
'\\',
'/');
const ARCHIVE_TAR_END_BLOCK
const ARCHIVE_TAR_ATT_SEPARATOR(!class_exists('PEAR'))
__construct($p_tarname, $p_compress=null, $buffer_length=512)
_readLongHeader(&$v_header)
extractModify($p_path, $p_remove_path, $p_preserve=false, $p_symlinks=true)
_extractInString($p_filename)
_addString($p_filename, $p_string, $p_datetime=false, $p_params=array())
_translateWinPath($p_path, $p_remove_disk_letter=true)
_extractList( $p_path, &$p_list_detail, $p_mode, $p_file_list, $p_remove_path, $p_preserve=false, $p_symlinks=true)
_writeLongHeader($p_filename, $is_link=false)
_isMaliciousFilename($file)
extract($p_path='', $p_preserve=false, $p_symlinks=true)
_writeHeaderBlock( $p_filename, $p_size, $p_mtime=0, $p_perms=0, $p_type='', $p_uid=0, $p_gid=0)
extractInString($p_filename)
_addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $v_stored_filename=null)
_append($p_filelist, $p_add_dir='', $p_remove_dir='')
_writeHeader($p_filename, $p_stored_filename)
createModify($p_filelist, $p_add_dir, $p_remove_dir='')
addModify($p_filelist, $p_add_dir, $p_remove_dir='')
extractList($p_filelist, $p_path='', $p_remove_path='', $p_preserve=false, $p_symlinks=true)
_isArchive($p_filename=null)
_writeBlock($p_binary_data, $p_len=null)
_addList($p_list, $p_add_dir, $p_remove_dir)
addString($p_filename, $p_string, $p_datetime=false, $p_params=array())
_readHeader($v_binary_data, &$v_header)
static loadExtension($ext)