1 <?php
2 3 4 5 6 7 8
9
10 defined('JPATH_PLATFORM') or die;
11
12 jimport('joomla.filesystem.file');
13
14 15 16 17 18 19 20 21 22 23 24
25 class JArchiveGzip implements JArchiveExtractable
26 {
27 28 29 30 31 32
33 private $_flags = array('FTEXT' => 0x01, 'FHCRC' => 0x02, 'FEXTRA' => 0x04, 'FNAME' => 0x08, 'FCOMMENT' => 0x10);
34
35 36 37 38 39 40
41 private $_data = null;
42
43 44 45 46 47 48 49 50 51 52 53 54
55 public function extract($archive, $destination, array $options = array())
56 {
57 $this->_data = null;
58
59 if (!extension_loaded('zlib'))
60 {
61 return $this->raiseWarning(100, 'The zlib extension is not available.');
62 }
63
64 if (isset($options['use_streams']) && $options['use_streams'] != false)
65 {
66 return $this->extractStream($archive, $destination, $options);
67 }
68
69 $this->_data = file_get_contents($archive);
70
71 if (!$this->_data)
72 {
73 return $this->raiseWarning(100, 'Unable to read archive');
74 }
75
76 $position = $this->_getFilePosition();
77 $buffer = gzinflate(substr($this->_data, $position, strlen($this->_data) - $position));
78
79 if (empty($buffer))
80 {
81 return $this->raiseWarning(100, 'Unable to decompress data');
82 }
83
84 if (JFile::write($destination, $buffer) === false)
85 {
86 return $this->raiseWarning(100, 'Unable to write archive');
87 }
88
89 return true;
90 }
91
92 93 94 95 96 97 98 99 100
101 protected function ($archive, $destination, $options = array())
102 {
103
104 $input = JFactory::getStream();
105
106
107 $input->set('processingmethod', 'gz');
108
109 if (!$input->open($archive))
110 {
111 return $this->raiseWarning(100, 'Unable to read archive (gz)');
112 }
113
114 $output = JFactory::getStream();
115
116 if (!$output->open($destination, 'w'))
117 {
118 $input->close();
119
120 return $this->raiseWarning(100, 'Unable to write archive (gz)');
121 }
122
123 do
124 {
125 $this->_data = $input->read($input->get('chunksize', 8196));
126
127 if ($this->_data && !$output->write($this->_data))
128 {
129 $input->close();
130
131 return $this->raiseWarning(100, 'Unable to write file (gz)');
132 }
133 }
134
135 while ($this->_data);
136
137 $output->close();
138 $input->close();
139
140 return true;
141 }
142
143 144 145 146 147 148 149 150 151 152 153
154 private function raiseWarning($code, $msg)
155 {
156 if (class_exists('JError'))
157 {
158 return JError::raiseWarning($code, $msg);
159 }
160
161 throw new RuntimeException($msg);
162 }
163
164 165 166 167 168 169 170
171 public static function isSupported()
172 {
173 return extension_loaded('zlib');
174 }
175
176 177 178 179 180 181 182 183
184 public function _getFilePosition()
185 {
186
187 $position = 0;
188 $info = @ unpack('CCM/CFLG/VTime/CXFL/COS', substr($this->_data, $position + 2));
189
190 if (!$info)
191 {
192 return $this->raiseWarning(100, 'Unable to decompress data.');
193 }
194
195 $position += 10;
196
197 if ($info['FLG'] & $this->_flags['FEXTRA'])
198 {
199 $XLEN = unpack('vLength', substr($this->_data, $position + 0, 2));
200 $XLEN = $XLEN['Length'];
201 $position += $XLEN + 2;
202 }
203
204 if ($info['FLG'] & $this->_flags['FNAME'])
205 {
206 $filenamePos = strpos($this->_data, "\x0", $position);
207 $position = $filenamePos + 1;
208 }
209
210 if ($info['FLG'] & $this->_flags['FCOMMENT'])
211 {
212 $commentPos = strpos($this->_data, "\x0", $position);
213 $position = $commentPos + 1;
214 }
215
216 if ($info['FLG'] & $this->_flags['FHCRC'])
217 {
218 $hcrc = unpack('vCRC', substr($this->_data, $position + 0, 2));
219 $hcrc = $hcrc['CRC'];
220 $position += 2;
221 }
222
223 return $position;
224 }
225 }
226