Annotation of embedaddon/php/ext/phar/tests/tar/files/make.dangerous.tar.php.inc, revision 1.1

1.1     ! misho       1: <?php
        !             2: // stolen from PEAR2_Pyrus_Developer_Creator_Tar by Greg Beaver, the original author, for use in unit tests
        !             3: // this tarmaker makes a malicious tar with a header designed to overflow the buffer
        !             4: class danger_tarmaker
        !             5: {
        !             6:     /**
        !             7:      * Path to archive file
        !             8:      *
        !             9:      * @var string
        !            10:      */
        !            11:     protected $archive;
        !            12:     /**
        !            13:      * Temporary stream used for creating the archive
        !            14:      *
        !            15:      * @var stream
        !            16:      */
        !            17:     protected $tmp;
        !            18:     protected $path;
        !            19:     protected $compress;
        !            20:     function __construct($path, $compress = 'zlib')
        !            21:     {
        !            22:         $this->compress = $compress;
        !            23:         if ($compress === 'bz2' && !function_exists('bzopen')) {
        !            24:             throw new PEAR2_Pyrus_Developer_Creator_Exception(
        !            25:                 'bzip2 extension not available');
        !            26:         }
        !            27:         if ($compress === 'zlib' && !function_exists('gzopen')) {
        !            28:             throw new PEAR2_Pyrus_Developer_Creator_Exception(
        !            29:                 'zlib extension not available');
        !            30:         }
        !            31:         $this->path = $path;
        !            32:     }
        !            33: 
        !            34:     /**
        !            35:      * save a file inside this package
        !            36:      * 
        !            37:      * This code is modified from Vincent Lascaux's File_Archive
        !            38:      * package, which is licensed under the LGPL license.
        !            39:      * @param string relative path within the package
        !            40:      * @param string|resource file contents or open file handle
        !            41:      */
        !            42:     function addFile($path, $fileOrStream, $stat = null)
        !            43:     {
        !            44:         clearstatcache();
        !            45:         if ($stat === null) {
        !            46:             if (is_resource($fileOrStream)) {
        !            47:                 $stat = fstat($fileOrStream);
        !            48:             } else {
        !            49:                 $stat = array(
        !            50:                     'mode' => 0x8000 + 0644,
        !            51:                     'uid' => 0,
        !            52:                     'gid' => 0,
        !            53:                     'size' => strlen($fileOrStream),
        !            54:                     'mtime' => time(),
        !            55:                 );
        !            56:             }
        !            57:         }
        !            58: 
        !            59:         $link = null;
        !            60:         if ($stat['mode'] & 0x4000) {
        !            61:             $type = 5;        // Directory
        !            62:         } else if ($stat['mode'] & 0x8000) {
        !            63:             $type = 0;        // Regular
        !            64:         } else if ($stat['mode'] & 0xA000) {
        !            65:             $type = 1;        // Link
        !            66:             $link = @readlink($current);
        !            67:         } else {
        !            68:             $type = 9;        // Unknown
        !            69:         }
        !            70: 
        !            71:         $filePrefix = '';
        !            72:         if (strlen($path) > 255) {
        !            73:             throw new Exception(
        !            74:                 "$path is too long, must be 255 characters or less"
        !            75:             );
        !            76:         } else if (strlen($path) > 100) {
        !            77:             $filePrefix = substr($path, 0, strlen($path)-100);
        !            78:             $path = substr($path, -100);
        !            79:         }
        !            80: 
        !            81:         $block = pack('a100a8a8a8a12A12',
        !            82:                 $path,
        !            83:                 '12345678', // have a mode that allows the name to overflow
        !            84:                 sprintf('%6s ',decoct($stat['uid'])),
        !            85:                 sprintf('%6s ',decoct($stat['gid'])),
        !            86:                 sprintf('%11s ',decoct($stat['size'])),
        !            87:                 sprintf('%11s ',decoct($stat['mtime']))
        !            88:             );
        !            89: 
        !            90:         $blockend = pack('a1a100a6a2a32a32a8a8a155a12',
        !            91:             $type,
        !            92:             $link,
        !            93:             'ustar',
        !            94:             '00',
        !            95:             'Pyrus',
        !            96:             'Pyrus',
        !            97:             '',
        !            98:             '',
        !            99:             $filePrefix,
        !           100:             '123456789abc'); // malicious block
        !           101: 
        !           102:         $checkheader = array_merge(str_split($block), str_split($blockend));
        !           103:         if (!function_exists('_pear2tarchecksum')) {
        !           104:             function _pear2tarchecksum($a, $b) {return $a + ord($b);}
        !           105:         }
        !           106:         $checksum = 256; // 8 * ord(' ');
        !           107:         $checksum += array_reduce($checkheader, '_pear2tarchecksum');
        !           108: 
        !           109:         $checksum = pack('a8', sprintf('%6s ', decoct($checksum)));
        !           110: 
        !           111:         fwrite($this->tmp, (binary)$block . $checksum . $blockend, 512);
        !           112:         if (is_resource($fileOrStream)) {
        !           113:             stream_copy_to_stream($fileOrStream, $this->tmp);
        !           114:             if ($stat['size'] % 512) {
        !           115:                 fwrite($this->tmp, (binary)str_repeat("\0", 512 - $stat['size'] % 512));
        !           116:             }
        !           117:         } else {
        !           118:             fwrite($this->tmp, (binary)$fileOrStream);
        !           119:             if (strlen($fileOrStream) % 512) {
        !           120:                 fwrite($this->tmp, (binary)str_repeat("\0", 512 - strlen($fileOrStream) % 512));
        !           121:             }
        !           122:         }
        !           123:     }
        !           124: 
        !           125:     /**
        !           126:      * Initialize the package creator
        !           127:      */
        !           128:     function init()
        !           129:     {
        !           130:         switch ($this->compress) {
        !           131:             case 'zlib' :
        !           132:                 $this->tmp = gzopen($this->path, 'wb');
        !           133:                 break;
        !           134:             case 'bz2' :
        !           135:                 $this->tmp = bzopen($this->path, 'w');
        !           136:                 break;
        !           137:             case 'none' :
        !           138:                 $this->tmp = fopen($this->path, 'wb');
        !           139:                 break;
        !           140:             default :
        !           141:                 throw new Exception(
        !           142:                     'unknown compression type ' . $this->compress);
        !           143:         }
        !           144:     }
        !           145: 
        !           146:     /**
        !           147:      * Create an internal directory, creating parent directories as needed
        !           148:      * 
        !           149:      * @param string $dir
        !           150:      */
        !           151:     function mkdir($dir)
        !           152:     {
        !           153:         $this->addFile($dir, "", array(
        !           154:                     'mode' => 0x4000 + 0644,
        !           155:                     'uid' => 0,
        !           156:                     'gid' => 0,
        !           157:                     'size' => 0,
        !           158:                     'mtime' => time(),
        !           159:                 ));
        !           160:     }
        !           161: 
        !           162:     /**
        !           163:      * Finish saving the package
        !           164:      */
        !           165:     function close()
        !           166:     {
        !           167:         fwrite($this->tmp, pack('a1024', ''));
        !           168:         fclose($this->tmp);
        !           169:     }
        !           170: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>