src/Tar.php
protected function parseHeader($block)
    {
        if (!$block || strlen($block) != 512) {
            throw new ArchiveCorruptedException('Unexpected length of header');
        }

        // null byte blocks are ignored
        if(trim($block) === '') return false;

        for ($i = 0, $chks = 0; $i < 148; $i++) {
            $chks += ord($block[$i]);
        }

        for ($i = 156, $chks += 256; $i < 512; $i++) {
            $chks += ord($block[$i]);
        }

        $header = @unpack(
            "a100filename/a8perm/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix",
            $block
        );
        if (!$header) {
            throw new ArchiveCorruptedException('Failed to parse header');
        }

        $return['checksum'] = OctDec(trim($header['checksum']));
        if ($return['checksum'] != $chks) {
            throw new ArchiveCorruptedException('Header does not match it\'s checksum');
        }

        $return['filename'] = trim($header['filename']);
        $return['perm']     = OctDec(trim($header['perm']));
        $return['uid']      = OctDec(trim($header['uid']));
        $return['gid']      = OctDec(trim($header['gid']));
        $return['size']     = OctDec(trim($header['size']));
        $return['mtime']    = OctDec(trim($header['mtime']));
        $return['typeflag'] = $header['typeflag'];
        $return['link']     = trim($header['link']);
        $return['uname']    = trim($header['uname']);
        $return['gname']    = trim($header['gname']);

        // Handle ustar Posix compliant path prefixes
        if (trim($header['prefix'])) {
            $return['filename'] = trim($header['prefix']).'/'.$return['filename'];
        }

        // Handle Long-Link entries from GNU Tar
        if ($return['typeflag'] == 'L') {
            // following data block(s) is the filename
            $filename = trim($this->readbytes(ceil($return['size'] / 512) * 512));
            // next block is the real header
            $block  = $this->readbytes(512);
            $return = $this->parseHeader($block);
            // overwrite the filename
            $return['filename'] = $filename;
        }

        return $return;
    }
protected function parseHeader($block)
    {
        if (!$block || strlen($block) != 512) {
            throw new ArchiveCorruptedException('Unexpected length of header');
        }

        // null byte blocks are ignored
        if(trim($block) === '') return false;

        for ($i = 0, $chks = 0; $i < 148; $i++) {
            $chks += ord($block[$i]);
        }

        for ($i = 156, $chks += 256; $i < 512; $i++) {
            $chks += ord($block[$i]);
        }

        $header = @unpack(
            "a100filename/a8perm/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix",
            $block
        );
        if (!$header) {
            throw new ArchiveCorruptedException('Failed to parse header');
        }

        $return['checksum'] = OctDec(trim($header['checksum']));
        if ($return['checksum'] != $chks) {
            throw new ArchiveCorruptedException('Header does not match it\'s checksum');
        }

        $return['filename'] = trim($header['filename']);
        $return['perm']     = OctDec(trim($header['perm']));
        $return['uid']      = OctDec(trim($header['uid']));
        $return['gid']      = OctDec(trim($header['gid']));
        $return['size']     = OctDec(trim($header['size']));
        $return['mtime']    = OctDec(trim($header['mtime']));
        $return['typeflag'] = $header['typeflag'];
        $return['link']     = trim($header['link']);
        $return['uname']    = trim($header['uname']);
        $return['gname']    = trim($header['gname']);

        // Handle ustar Posix compliant path prefixes
        if (trim($header['prefix'])) {
            $return['filename'] = trim($header['prefix']).'/'.$return['filename'];
        }

        // Handle Long-Link entries from GNU Tar
        if ($return['typeflag'] == 'L') {
            // following data block(s) is the filename
            $filename = trim($this->readbytes(ceil($return['size'] / 512) * 512));
            // next block is the real header
            $block  = $this->readbytes(512);
            $return = $this->parseHeader($block);
            // overwrite the filename
            $return['filename'] = $filename;
        }

        return $return;
    }
protected function parseHeader ( $ block ) { if ( ! $ block || strlen ( $ block ) != 512 ) { throw new ArchiveCorruptedException ( 'Unexpected length of header' ) ; } // null byte blocks are ignored if ( trim ( $ block ) === '' ) return false ; for ( $ i = 0 , $ chks = 0 ; $ i < 148 ; $ i ++ ) { $ chks += ord ( $ block [ $ i ] ) ; } for ( $ i = 156 , $ chks += 256 ; $ i < 512 ; $ i ++ ) { $ chks += ord ( $ block [ $ i ] ) ; } $ header = @ unpack ( "a100filename/a8perm/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix" , $ block ) ; if ( ! $ header ) { throw new ArchiveCorruptedException ( 'Failed to parse header' ) ; } $ return [ 'checksum' ] = OctDec ( trim ( $ header [ 'checksum' ] ) ) ; if ( $ return [ 'checksum' ] != $ chks ) { throw new ArchiveCorruptedException ( 'Header does not match it\'s checksum' ) ; } $ return [ 'filename' ] = trim ( $ header [ 'filename' ] ) ; $ return [ 'perm' ] = OctDec ( trim ( $ header [ 'perm' ] ) ) ; $ return [ 'uid' ] = OctDec ( trim ( $ header [ 'uid' ] ) ) ; $ return [ 'gid' ] = OctDec ( trim ( $ header [ 'gid' ] ) ) ; $ return [ 'size' ] = OctDec ( trim ( $ header [ 'size' ] ) ) ; $ return [ 'mtime' ] = OctDec ( trim ( $ header [ 'mtime' ] ) ) ; $ return [ 'typeflag' ] = $ header [ 'typeflag' ] ; $ return [ 'link' ] = trim ( $ header [ 'link' ] ) ; $ return [ 'uname' ] = trim ( $ header [ 'uname' ] ) ; $ return [ 'gname' ] = trim ( $ header [ 'gname' ] ) ; // Handle ustar Posix compliant path prefixes if ( trim ( $ header [ 'prefix' ] ) ) { $ return [ 'filename' ] = trim ( $ header [ 'prefix' ] ) . '/' . $ return [ 'filename' ] ; } // Handle Long-Link entries from GNU Tar if ( $ return [ 'typeflag' ] == 'L' ) { // following data block(s) is the filename $ filename = trim ( $ this -> readbytes ( ceil ( $ return [ 'size' ] / 512 ) * 512 ) ) ; // next block is the real header $ block = $ this -> readbytes ( 512 ) ; $ return = $ this -> parseHeader ( $ block ) ; // overwrite the filename $ return [ 'filename' ] = $ filename ; } return $ return ; }
Decode the given tar file header

@param string $block a 512 byte block containing the header data
@return array|false returns false when this was a null block
@throws ArchiveCorruptedException
Decode the given tar file header