Skip to content

Commit

Permalink
Merge pull request #15 from serlin74/master
Browse files Browse the repository at this point in the history
Fix reading of archives with files > 8GB.
  • Loading branch information
mrook committed Nov 28, 2015
2 parents fc2937c + 184af11 commit 932051a
Showing 1 changed file with 35 additions and 1 deletion.
36 changes: 35 additions & 1 deletion Archive/Tar.php
Original file line number Diff line number Diff line change
Expand Up @@ -1697,7 +1697,7 @@ public function _readHeader($v_binary_data, &$v_header)
$v_header['mode'] = OctDec(trim($v_data['mode']));
$v_header['uid'] = OctDec(trim($v_data['uid']));
$v_header['gid'] = OctDec(trim($v_data['gid']));
$v_header['size'] = OctDec(trim($v_data['size']));
$v_header['size'] = $this->_tarRecToSize($v_data['size']);
$v_header['mtime'] = OctDec(trim($v_data['mtime']));
if (($v_header['typeflag'] = $v_data['typeflag']) == "5") {
$v_header['size'] = 0;
Expand All @@ -1716,6 +1716,40 @@ public function _readHeader($v_binary_data, &$v_header)
return true;
}

/**
* Convert Tar record size to actual size
*
* @param string $tar_size
* @return size of tar record in bytes
*/
private function _tarRecToSize($tar_size)
{
/*
* First byte of size has a special meaning if bit 7 is set.
*
* Bit 7 indicates base-256 encoding if set.
* Bit 6 is the sign bit.
* Bits 5:0 are most significant value bits.
*/
$ch = ord($tar_size[0]);
if ($ch & 0x80) {
// Full 12-bytes record is required.
$rec_str = $tar_size . "\x00";

$size = ($ch & 0x40) ? -1 : 0;
$size = ($size << 6) | ($ch & 0x3f);

for ($num_ch = 1; $num_ch < 12; ++$num_ch) {
$size = ($size * 256) + ord($rec_str[$num_ch]);
}

return $size;

} else {
return OctDec(trim($tar_size));
}
}

/**
* Detect and report a malicious file name
*
Expand Down

0 comments on commit 932051a

Please sign in to comment.