Issues (3083)

htdocs/class/class.zipfile.php (1 issue)

Severity
1
<?php
2
// 
3
/**
4
 * package::i.tools
5
 *
6
 * php-downloader    v1.0    -    www.ipunkt.biz
7
 *
8
 * (c)    2002 - www.ipunkt.biz (rok)
9
 *
10
 * Zip file creation class.
11
 * Makes zip files.
12
 *
13
 * Based on :
14
 *
15
 *       https://www.zend.com/codex.php?id=535&single=1
16
 *       By Eric Mueller <[email protected]>
17
 *
18
 *       https://www.zend.com/codex.php?id=470&single=1
19
 *       by Denis125 <[email protected]>
20
 *
21
 *       a patch from Peter Listiak <[email protected]> for last modified
22
 *       date and time of the compressed file
23
 *
24
 * Official ZIP file format: http://www.pkware.com/appnote.txt
25
 *
26
 * @copyright (c)    2002 - www.ipunkt.biz (rok)
27
 * @access           public
28
 * @package          kernel
29
 * @subpackage       core
30
 */
31
class Zipfile
32
{
33
    /**
34
     * Array to store compressed data
35
     *
36
     * @var array $datasec
37
     */
38
    public $datasec = array();
39
40
    /**
41
     * Central directory
42
     *
43
     * @var array $ctrl_dir
44
     */
45
    public $ctrl_dir = array();
46
47
    /**
48
     * End of central directory record
49
     *
50
     * @var string $eof_ctrl_dir
51
     */
52
    public $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";
53
54
    /**
55
     * Last offset position
56
     *
57
     * @var integer $old_offset
58
     */
59
    public $old_offset = 0;
60
61
    /**
62
     * Converts an Unix timestamp to a four byte DOS date and time format (date
63
     * in high two bytes, time in low two bytes allowing magnitude comparison).
64
     *
65
     * @param int $unixtime the current Unix timestamp
66
     *
67
     * @return integer the current date in a four byte DOS format
68
     * @access   private
69
     */
70
    public function unix2DosTime($unixtime = 0)
71
    {
72
        $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);
73
        if ($timearray['year'] < 1980) {
74
            $timearray['year']    = 1980;
75
            $timearray['mon']     = 1;
76
            $timearray['mday']    = 1;
77
            $timearray['hours']   = 0;
78
            $timearray['minutes'] = 0;
79
            $timearray['seconds'] = 0;
80
        } // end if
81
82
        return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
83
    } // end of the 'unix2DosTime()' method
84
85
    /**
86
     * Adds "file" to archive
87
     *
88
     * @param string  $data file contents
89
     * @param string  $name name of the file in the archive (may contains the path)
90
     * @param integer $time the current timestamp
91
     * @access   public
92
     */
93
    public function addFile($data, $name, $time = 0)
94
    {
95
        $name = str_replace('\\', '/', $name);
96
97
        $dtime    = dechex($this->unix2DosTime($time));
98
        $hexdtime = '\x' . $dtime[6] . $dtime[7] . '\x' . $dtime[4] . $dtime[5] . '\x' . $dtime[2] . $dtime[3] . '\x' . $dtime[0] . $dtime[1];
99
        eval('$hexdtime = "' . $hexdtime . '";');
0 ignored issues
show
The use of eval() is discouraged.
Loading history...
100
101
        $fr = "\x50\x4b\x03\x04";
102
        $fr .= "\x14\x00"; // ver needed to extract
103
        $fr .= "\x00\x00"; // gen purpose bit flag
104
        $fr .= "\x08\x00"; // compression method
105
        $fr .= $hexdtime; // last mod time and date
106
        // "local file header" segment
107
        $unc_len = strlen($data);
108
        $crc     = crc32($data);
109
        $zdata   = gzcompress($data);
110
        $zdata   = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug
111
        $c_len   = strlen($zdata);
112
        $fr .= pack('V', $crc); // crc32
113
        $fr .= pack('V', $c_len); // compressed filesize
114
        $fr .= pack('V', $unc_len); // uncompressed filesize
115
        $fr .= pack('v', strlen($name)); // length of filename
116
        $fr .= pack('v', 0); // extra field length
117
        $fr .= $name;
118
        // "file data" segment
119
        $fr .= $zdata;
120
        // "data descriptor" segment (optional but necessary if archive is not
121
        // served as file)
122
        $fr .= pack('V', $crc); // crc32
123
        $fr .= pack('V', $c_len); // compressed filesize
124
        $fr .= pack('V', $unc_len); // uncompressed filesize
125
        // add this entry to array
126
        $this->datasec[] = $fr;
127
        $new_offset      = strlen(implode('', $this->datasec));
128
        // now add to central directory record
129
        $cdrec = "\x50\x4b\x01\x02";
130
        $cdrec .= "\x00\x00"; // version made by
131
        $cdrec .= "\x14\x00"; // version needed to extract
132
        $cdrec .= "\x00\x00"; // gen purpose bit flag
133
        $cdrec .= "\x08\x00"; // compression method
134
        $cdrec .= $hexdtime; // last mod time & date
135
        $cdrec .= pack('V', $crc); // crc32
136
        $cdrec .= pack('V', $c_len); // compressed filesize
137
        $cdrec .= pack('V', $unc_len); // uncompressed filesize
138
        $cdrec .= pack('v', strlen($name)); // length of filename
139
        $cdrec .= pack('v', 0); // extra field length
140
        $cdrec .= pack('v', 0); // file comment length
141
        $cdrec .= pack('v', 0); // disk number start
142
        $cdrec .= pack('v', 0); // internal file attributes
143
        $cdrec .= pack('V', 32); // external file attributes - 'archive' bit set
144
        $cdrec .= pack('V', $this->old_offset); // relative offset of local header
145
        $this->old_offset = $new_offset;
146
        $cdrec .= $name;
147
        // optional extra field, file comment goes here
148
        // save to central directory
149
        $this->ctrl_dir[] = $cdrec;
150
    } // end of the 'addFile()' method
151
152
    /**
153
     * Dumps out file
154
     *
155
     * @return string the zipped file
156
     * @access public
157
     */
158
    public function file()
159
    {
160
        $data    = implode('', $this->datasec);
161
        $ctrldir = implode('', $this->ctrl_dir);
162
163
        return $data . $ctrldir . $this->eof_ctrl_dir . pack('v', count($this->ctrl_dir)) . // total # of entries "on this disk"
164
               pack('v', count($this->ctrl_dir)) . // total # of entries overall
165
               pack('V', strlen($ctrldir)) . // size of central dir
166
               pack('V', strlen($data)) . // offset to start of central dir
167
               "\x00\x00"; // .zip file comment length
168
    } // end of the 'file()' method
169
} // end of the 'zipfile' class
170
171