blob: 3177424c4e73b2898602d6443fe17b99d67b9853 [file] [log] [blame]
Derek Jones37f4b9c2011-07-01 17:56:50 -05001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Greg Aker741de1c2010-11-10 14:52:57 -06005 * An open source application development framework for PHP 5.1.6 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
7 * @package CodeIgniter
8 * @author ExpressionEngine Dev Team
Greg Aker0711dc82011-01-05 10:49:40 -06009 * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
Derek Allard2067d1a2008-11-13 22:59:24 +000010 * @license http://codeigniter.com/user_guide/license.html
11 * @link http://codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * File Uploading Class
20 *
21 * @package CodeIgniter
22 * @subpackage Libraries
23 * @category Uploads
24 * @author ExpressionEngine Dev Team
25 * @link http://codeigniter.com/user_guide/libraries/file_uploading.html
26 */
27class CI_Upload {
Barry Mienydd671972010-10-04 16:33:58 +020028
Greg Aker58fdee82010-11-10 15:07:09 -060029 public $max_size = 0;
30 public $max_width = 0;
31 public $max_height = 0;
32 public $max_filename = 0;
33 public $allowed_types = "";
34 public $file_temp = "";
35 public $file_name = "";
36 public $orig_name = "";
37 public $file_type = "";
38 public $file_size = "";
39 public $file_ext = "";
40 public $upload_path = "";
41 public $overwrite = FALSE;
42 public $encrypt_name = FALSE;
43 public $is_image = FALSE;
44 public $image_width = '';
45 public $image_height = '';
46 public $image_type = '';
47 public $image_size_str = '';
48 public $error_msg = array();
49 public $mimes = array();
50 public $remove_spaces = TRUE;
51 public $xss_clean = FALSE;
52 public $temp_prefix = "temp_file_";
53 public $client_name = '';
Barry Mienydd671972010-10-04 16:33:58 +020054
Greg Aker58fdee82010-11-10 15:07:09 -060055 protected $_file_name_override = '';
Barry Mienydd671972010-10-04 16:33:58 +020056
Derek Allard2067d1a2008-11-13 22:59:24 +000057 /**
58 * Constructor
59 *
60 * @access public
61 */
Greg Aker58fdee82010-11-10 15:07:09 -060062 public function __construct($props = array())
Derek Allard2067d1a2008-11-13 22:59:24 +000063 {
64 if (count($props) > 0)
65 {
66 $this->initialize($props);
67 }
Barry Mienydd671972010-10-04 16:33:58 +020068
Derek Allard2067d1a2008-11-13 22:59:24 +000069 log_message('debug', "Upload Class Initialized");
70 }
Barry Mienydd671972010-10-04 16:33:58 +020071
Derek Allard2067d1a2008-11-13 22:59:24 +000072 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +020073
Derek Allard2067d1a2008-11-13 22:59:24 +000074 /**
75 * Initialize preferences
76 *
Derek Allard2067d1a2008-11-13 22:59:24 +000077 * @param array
78 * @return void
Barry Mienydd671972010-10-04 16:33:58 +020079 */
Greg Aker58fdee82010-11-10 15:07:09 -060080 public function initialize($config = array())
Derek Allard2067d1a2008-11-13 22:59:24 +000081 {
82 $defaults = array(
83 'max_size' => 0,
84 'max_width' => 0,
85 'max_height' => 0,
86 'max_filename' => 0,
87 'allowed_types' => "",
88 'file_temp' => "",
89 'file_name' => "",
90 'orig_name' => "",
91 'file_type' => "",
92 'file_size' => "",
93 'file_ext' => "",
94 'upload_path' => "",
95 'overwrite' => FALSE,
96 'encrypt_name' => FALSE,
97 'is_image' => FALSE,
98 'image_width' => '',
99 'image_height' => '',
100 'image_type' => '',
101 'image_size_str' => '',
102 'error_msg' => array(),
103 'mimes' => array(),
104 'remove_spaces' => TRUE,
105 'xss_clean' => FALSE,
Derek Jonese9d723f2010-07-12 10:10:59 -0500106 'temp_prefix' => "temp_file_",
107 'client_name' => ''
Barry Mienydd671972010-10-04 16:33:58 +0200108 );
109
110
Derek Allard2067d1a2008-11-13 22:59:24 +0000111 foreach ($defaults as $key => $val)
112 {
113 if (isset($config[$key]))
114 {
115 $method = 'set_'.$key;
116 if (method_exists($this, $method))
117 {
118 $this->$method($config[$key]);
119 }
120 else
121 {
122 $this->$key = $config[$key];
Barry Mienydd671972010-10-04 16:33:58 +0200123 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000124 }
125 else
126 {
127 $this->$key = $val;
128 }
129 }
Barry Mienydd671972010-10-04 16:33:58 +0200130
Derek Jonese9d723f2010-07-12 10:10:59 -0500131 // if a file_name was provided in the config, use it instead of the user input
132 // supplied file name for all uploads until initialized again
133 $this->_file_name_override = $this->file_name;
Derek Allard2067d1a2008-11-13 22:59:24 +0000134 }
Barry Mienydd671972010-10-04 16:33:58 +0200135
Derek Allard2067d1a2008-11-13 22:59:24 +0000136 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200137
Derek Allard2067d1a2008-11-13 22:59:24 +0000138 /**
139 * Perform the file upload
140 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000141 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +0200142 */
Greg Aker58fdee82010-11-10 15:07:09 -0600143 public function do_upload($field = 'userfile')
Derek Allard2067d1a2008-11-13 22:59:24 +0000144 {
Eric Barnes92808342011-03-18 09:02:37 -0400145
Robin Sowell0ecc0622011-01-30 16:47:43 -0500146 // Is $_FILES[$field] set? If not, no reason to continue.
Derek Allard2067d1a2008-11-13 22:59:24 +0000147 if ( ! isset($_FILES[$field]))
148 {
149 $this->set_error('upload_no_file_selected');
150 return FALSE;
151 }
Barry Mienydd671972010-10-04 16:33:58 +0200152
Derek Allard2067d1a2008-11-13 22:59:24 +0000153 // Is the upload path valid?
154 if ( ! $this->validate_upload_path())
155 {
156 // errors will already be set by validate_upload_path() so just return FALSE
157 return FALSE;
158 }
159
160 // Was the file able to be uploaded? If not, determine the reason why.
161 if ( ! is_uploaded_file($_FILES[$field]['tmp_name']))
162 {
163 $error = ( ! isset($_FILES[$field]['error'])) ? 4 : $_FILES[$field]['error'];
164
165 switch($error)
166 {
167 case 1: // UPLOAD_ERR_INI_SIZE
168 $this->set_error('upload_file_exceeds_limit');
169 break;
170 case 2: // UPLOAD_ERR_FORM_SIZE
171 $this->set_error('upload_file_exceeds_form_limit');
172 break;
173 case 3: // UPLOAD_ERR_PARTIAL
Barry Mienydd671972010-10-04 16:33:58 +0200174 $this->set_error('upload_file_partial');
Derek Allard2067d1a2008-11-13 22:59:24 +0000175 break;
176 case 4: // UPLOAD_ERR_NO_FILE
Barry Mienydd671972010-10-04 16:33:58 +0200177 $this->set_error('upload_no_file_selected');
Derek Allard2067d1a2008-11-13 22:59:24 +0000178 break;
179 case 6: // UPLOAD_ERR_NO_TMP_DIR
180 $this->set_error('upload_no_temp_directory');
181 break;
182 case 7: // UPLOAD_ERR_CANT_WRITE
183 $this->set_error('upload_unable_to_write_file');
184 break;
185 case 8: // UPLOAD_ERR_EXTENSION
186 $this->set_error('upload_stopped_by_extension');
187 break;
Derek Jones37f4b9c2011-07-01 17:56:50 -0500188 default : $this->set_error('upload_no_file_selected');
Derek Allard2067d1a2008-11-13 22:59:24 +0000189 break;
190 }
191
192 return FALSE;
193 }
194
Derek Jonese9d723f2010-07-12 10:10:59 -0500195
Derek Allard2067d1a2008-11-13 22:59:24 +0000196 // Set the uploaded data as class variables
Barry Mienydd671972010-10-04 16:33:58 +0200197 $this->file_temp = $_FILES[$field]['tmp_name'];
198 $this->file_size = $_FILES[$field]['size'];
Derek Allard2067d1a2008-11-13 22:59:24 +0000199 $this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']);
Derek Jones616fb022010-04-22 16:52:18 -0500200 $this->file_type = strtolower(trim(stripslashes($this->file_type), '"'));
Derek Jonese9d723f2010-07-12 10:10:59 -0500201 $this->file_name = $this->_prep_filename($_FILES[$field]['name']);
202 $this->file_ext = $this->get_extension($this->file_name);
203 $this->client_name = $this->file_name;
Barry Mienydd671972010-10-04 16:33:58 +0200204
Derek Allard2067d1a2008-11-13 22:59:24 +0000205 // Is the file type allowed to be uploaded?
206 if ( ! $this->is_allowed_filetype())
207 {
208 $this->set_error('upload_invalid_filetype');
209 return FALSE;
210 }
211
Derek Jonese9d723f2010-07-12 10:10:59 -0500212 // if we're overriding, let's now make sure the new name and type is allowed
213 if ($this->_file_name_override != '')
214 {
215 $this->file_name = $this->_prep_filename($this->_file_name_override);
Phil Sturgeon1e74da22010-12-15 10:45:06 +0000216
217 // If no extension was provided in the file_name config item, use the uploaded one
Pascal Kriete14287f32011-02-14 13:39:34 -0500218 if (strpos($this->_file_name_override, '.') === FALSE)
Phil Sturgeon1e74da22010-12-15 10:45:06 +0000219 {
220 $this->file_name .= $this->file_ext;
221 }
222
223 // An extension was provided, lets have it!
224 else
225 {
226 $this->file_ext = $this->get_extension($this->_file_name_override);
227 }
Derek Jonese9d723f2010-07-12 10:10:59 -0500228
229 if ( ! $this->is_allowed_filetype(TRUE))
230 {
231 $this->set_error('upload_invalid_filetype');
Barry Mienydd671972010-10-04 16:33:58 +0200232 return FALSE;
Derek Jonese9d723f2010-07-12 10:10:59 -0500233 }
234 }
Barry Mienydd671972010-10-04 16:33:58 +0200235
Derek Jonese9d723f2010-07-12 10:10:59 -0500236 // Convert the file size to kilobytes
237 if ($this->file_size > 0)
238 {
239 $this->file_size = round($this->file_size/1024, 2);
240 }
241
Derek Allard2067d1a2008-11-13 22:59:24 +0000242 // Is the file size within the allowed maximum?
243 if ( ! $this->is_allowed_filesize())
244 {
245 $this->set_error('upload_invalid_filesize');
246 return FALSE;
247 }
248
249 // Are the image dimensions within the allowed size?
250 // Note: This can fail if the server has an open_basdir restriction.
251 if ( ! $this->is_allowed_dimensions())
252 {
253 $this->set_error('upload_invalid_dimensions');
254 return FALSE;
255 }
256
257 // Sanitize the file name for security
258 $this->file_name = $this->clean_file_name($this->file_name);
Barry Mienydd671972010-10-04 16:33:58 +0200259
Derek Allard2067d1a2008-11-13 22:59:24 +0000260 // Truncate the file name if it's too long
261 if ($this->max_filename > 0)
262 {
263 $this->file_name = $this->limit_filename_length($this->file_name, $this->max_filename);
264 }
265
266 // Remove white spaces in the name
267 if ($this->remove_spaces == TRUE)
268 {
269 $this->file_name = preg_replace("/\s+/", "_", $this->file_name);
270 }
271
272 /*
273 * Validate the file name
274 * This function appends an number onto the end of
275 * the file if one with the same name already exists.
276 * If it returns false there was a problem.
277 */
278 $this->orig_name = $this->file_name;
279
280 if ($this->overwrite == FALSE)
281 {
282 $this->file_name = $this->set_filename($this->upload_path, $this->file_name);
Barry Mienydd671972010-10-04 16:33:58 +0200283
Derek Allard2067d1a2008-11-13 22:59:24 +0000284 if ($this->file_name === FALSE)
285 {
286 return FALSE;
287 }
288 }
289
290 /*
Derek Jonese9d723f2010-07-12 10:10:59 -0500291 * Run the file through the XSS hacking filter
292 * This helps prevent malicious code from being
Derek Jones37f4b9c2011-07-01 17:56:50 -0500293 * embedded within a file. Scripts can easily
Derek Jonese9d723f2010-07-12 10:10:59 -0500294 * be disguised as images or other file types.
295 */
296 if ($this->xss_clean)
297 {
298 if ($this->do_xss_clean() === FALSE)
299 {
300 $this->set_error('upload_unable_to_write_file');
301 return FALSE;
302 }
303 }
304
305 /*
Derek Allard2067d1a2008-11-13 22:59:24 +0000306 * Move the file to the final destination
307 * To deal with different server configurations
Derek Jones37f4b9c2011-07-01 17:56:50 -0500308 * we'll attempt to use copy() first. If that fails
309 * we'll use move_uploaded_file(). One of the two should
Derek Allard2067d1a2008-11-13 22:59:24 +0000310 * reliably work in most environments
311 */
312 if ( ! @copy($this->file_temp, $this->upload_path.$this->file_name))
313 {
314 if ( ! @move_uploaded_file($this->file_temp, $this->upload_path.$this->file_name))
315 {
Barry Mienydd671972010-10-04 16:33:58 +0200316 $this->set_error('upload_destination_error');
317 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000318 }
319 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000320
321 /*
322 * Set the finalized image dimensions
323 * This sets the image width/height (assuming the
Derek Jones37f4b9c2011-07-01 17:56:50 -0500324 * file was an image). We use this information
Derek Allard2067d1a2008-11-13 22:59:24 +0000325 * in the "data" function.
326 */
327 $this->set_image_properties($this->upload_path.$this->file_name);
328
329 return TRUE;
330 }
Barry Mienydd671972010-10-04 16:33:58 +0200331
Derek Allard2067d1a2008-11-13 22:59:24 +0000332 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200333
Derek Allard2067d1a2008-11-13 22:59:24 +0000334 /**
335 * Finalized Data Array
Barry Mienydd671972010-10-04 16:33:58 +0200336 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000337 * Returns an associative array containing all of the information
338 * related to the upload, allowing the developer easy access in one array.
339 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000340 * @return array
Barry Mienydd671972010-10-04 16:33:58 +0200341 */
Greg Aker58fdee82010-11-10 15:07:09 -0600342 public function data()
Derek Allard2067d1a2008-11-13 22:59:24 +0000343 {
344 return array (
345 'file_name' => $this->file_name,
346 'file_type' => $this->file_type,
347 'file_path' => $this->upload_path,
348 'full_path' => $this->upload_path.$this->file_name,
349 'raw_name' => str_replace($this->file_ext, '', $this->file_name),
350 'orig_name' => $this->orig_name,
Derek Jonese9d723f2010-07-12 10:10:59 -0500351 'client_name' => $this->client_name,
Derek Allard2067d1a2008-11-13 22:59:24 +0000352 'file_ext' => $this->file_ext,
353 'file_size' => $this->file_size,
354 'is_image' => $this->is_image(),
355 'image_width' => $this->image_width,
356 'image_height' => $this->image_height,
357 'image_type' => $this->image_type,
358 'image_size_str' => $this->image_size_str,
359 );
360 }
Barry Mienydd671972010-10-04 16:33:58 +0200361
Derek Allard2067d1a2008-11-13 22:59:24 +0000362 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200363
Derek Allard2067d1a2008-11-13 22:59:24 +0000364 /**
365 * Set Upload Path
366 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000367 * @param string
368 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200369 */
Greg Aker58fdee82010-11-10 15:07:09 -0600370 public function set_upload_path($path)
Derek Allard2067d1a2008-11-13 22:59:24 +0000371 {
372 // Make sure it has a trailing slash
373 $this->upload_path = rtrim($path, '/').'/';
374 }
Barry Mienydd671972010-10-04 16:33:58 +0200375
Derek Allard2067d1a2008-11-13 22:59:24 +0000376 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200377
Derek Allard2067d1a2008-11-13 22:59:24 +0000378 /**
379 * Set the file name
380 *
381 * This function takes a filename/path as input and looks for the
382 * existence of a file with the same name. If found, it will append a
383 * number to the end of the filename to avoid overwriting a pre-existing file.
384 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000385 * @param string
386 * @param string
387 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200388 */
Greg Aker58fdee82010-11-10 15:07:09 -0600389 public function set_filename($path, $filename)
Derek Allard2067d1a2008-11-13 22:59:24 +0000390 {
391 if ($this->encrypt_name == TRUE)
Barry Mienydd671972010-10-04 16:33:58 +0200392 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000393 mt_srand();
Barry Mienydd671972010-10-04 16:33:58 +0200394 $filename = md5(uniqid(mt_rand())).$this->file_ext;
Derek Allard2067d1a2008-11-13 22:59:24 +0000395 }
Barry Mienydd671972010-10-04 16:33:58 +0200396
Derek Allard2067d1a2008-11-13 22:59:24 +0000397 if ( ! file_exists($path.$filename))
398 {
399 return $filename;
400 }
Barry Mienydd671972010-10-04 16:33:58 +0200401
Derek Allard2067d1a2008-11-13 22:59:24 +0000402 $filename = str_replace($this->file_ext, '', $filename);
Barry Mienydd671972010-10-04 16:33:58 +0200403
Derek Allard2067d1a2008-11-13 22:59:24 +0000404 $new_filename = '';
405 for ($i = 1; $i < 100; $i++)
Barry Mienydd671972010-10-04 16:33:58 +0200406 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000407 if ( ! file_exists($path.$filename.$i.$this->file_ext))
408 {
409 $new_filename = $filename.$i.$this->file_ext;
410 break;
411 }
412 }
413
414 if ($new_filename == '')
415 {
416 $this->set_error('upload_bad_filename');
417 return FALSE;
418 }
419 else
420 {
421 return $new_filename;
422 }
423 }
Barry Mienydd671972010-10-04 16:33:58 +0200424
Derek Allard2067d1a2008-11-13 22:59:24 +0000425 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200426
Derek Allard2067d1a2008-11-13 22:59:24 +0000427 /**
428 * Set Maximum File Size
429 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000430 * @param integer
431 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200432 */
Greg Aker58fdee82010-11-10 15:07:09 -0600433 public function set_max_filesize($n)
Derek Allard2067d1a2008-11-13 22:59:24 +0000434 {
435 $this->max_size = ((int) $n < 0) ? 0: (int) $n;
436 }
Barry Mienydd671972010-10-04 16:33:58 +0200437
Derek Allard2067d1a2008-11-13 22:59:24 +0000438 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200439
Derek Allard2067d1a2008-11-13 22:59:24 +0000440 /**
441 * Set Maximum File Name Length
442 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000443 * @param integer
444 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200445 */
Greg Aker58fdee82010-11-10 15:07:09 -0600446 public function set_max_filename($n)
Derek Allard2067d1a2008-11-13 22:59:24 +0000447 {
448 $this->max_filename = ((int) $n < 0) ? 0: (int) $n;
449 }
450
451 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200452
Derek Allard2067d1a2008-11-13 22:59:24 +0000453 /**
454 * Set Maximum Image Width
455 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000456 * @param integer
457 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200458 */
Greg Aker58fdee82010-11-10 15:07:09 -0600459 public function set_max_width($n)
Derek Allard2067d1a2008-11-13 22:59:24 +0000460 {
461 $this->max_width = ((int) $n < 0) ? 0: (int) $n;
462 }
Barry Mienydd671972010-10-04 16:33:58 +0200463
Derek Allard2067d1a2008-11-13 22:59:24 +0000464 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200465
Derek Allard2067d1a2008-11-13 22:59:24 +0000466 /**
467 * Set Maximum Image Height
468 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000469 * @param integer
470 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200471 */
Greg Aker58fdee82010-11-10 15:07:09 -0600472 public function set_max_height($n)
Derek Allard2067d1a2008-11-13 22:59:24 +0000473 {
474 $this->max_height = ((int) $n < 0) ? 0: (int) $n;
475 }
Barry Mienydd671972010-10-04 16:33:58 +0200476
Derek Allard2067d1a2008-11-13 22:59:24 +0000477 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200478
Derek Allard2067d1a2008-11-13 22:59:24 +0000479 /**
480 * Set Allowed File Types
481 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000482 * @param string
483 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200484 */
Greg Aker58fdee82010-11-10 15:07:09 -0600485 public function set_allowed_types($types)
Derek Allard2067d1a2008-11-13 22:59:24 +0000486 {
Derek Jonese12f64e2010-03-02 22:55:08 -0600487 if ( ! is_array($types) && $types == '*')
488 {
489 $this->allowed_types = '*';
490 return;
491 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000492 $this->allowed_types = explode('|', $types);
493 }
Barry Mienydd671972010-10-04 16:33:58 +0200494
Derek Allard2067d1a2008-11-13 22:59:24 +0000495 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200496
Derek Allard2067d1a2008-11-13 22:59:24 +0000497 /**
498 * Set Image Properties
499 *
500 * Uses GD to determine the width/height/type of image
501 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000502 * @param string
503 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200504 */
Greg Aker58fdee82010-11-10 15:07:09 -0600505 public function set_image_properties($path = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000506 {
507 if ( ! $this->is_image())
508 {
509 return;
510 }
511
512 if (function_exists('getimagesize'))
513 {
514 if (FALSE !== ($D = @getimagesize($path)))
Barry Mienydd671972010-10-04 16:33:58 +0200515 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000516 $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
517
518 $this->image_width = $D['0'];
519 $this->image_height = $D['1'];
520 $this->image_type = ( ! isset($types[$D['2']])) ? 'unknown' : $types[$D['2']];
Derek Jones37f4b9c2011-07-01 17:56:50 -0500521 $this->image_size_str = $D['3']; // string containing height and width
Derek Allard2067d1a2008-11-13 22:59:24 +0000522 }
523 }
524 }
Barry Mienydd671972010-10-04 16:33:58 +0200525
Derek Allard2067d1a2008-11-13 22:59:24 +0000526 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200527
Derek Allard2067d1a2008-11-13 22:59:24 +0000528 /**
529 * Set XSS Clean
530 *
531 * Enables the XSS flag so that the file that was uploaded
532 * will be run through the XSS filter.
533 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000534 * @param bool
535 * @return void
536 */
Greg Aker58fdee82010-11-10 15:07:09 -0600537 public function set_xss_clean($flag = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000538 {
539 $this->xss_clean = ($flag == TRUE) ? TRUE : FALSE;
540 }
Barry Mienydd671972010-10-04 16:33:58 +0200541
Derek Allard2067d1a2008-11-13 22:59:24 +0000542 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200543
Derek Allard2067d1a2008-11-13 22:59:24 +0000544 /**
545 * Validate the image
546 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000547 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +0200548 */
Greg Aker58fdee82010-11-10 15:07:09 -0600549 public function is_image()
Derek Allard2067d1a2008-11-13 22:59:24 +0000550 {
551 // IE will sometimes return odd mime-types during upload, so here we just standardize all
552 // jpegs or pngs to the same file type.
553
Derek Jones37f4b9c2011-07-01 17:56:50 -0500554 $png_mimes = array('image/x-png');
Derek Allard2067d1a2008-11-13 22:59:24 +0000555 $jpeg_mimes = array('image/jpg', 'image/jpe', 'image/jpeg', 'image/pjpeg');
Barry Mienydd671972010-10-04 16:33:58 +0200556
Derek Allard2067d1a2008-11-13 22:59:24 +0000557 if (in_array($this->file_type, $png_mimes))
558 {
559 $this->file_type = 'image/png';
560 }
Barry Mienydd671972010-10-04 16:33:58 +0200561
Derek Allard2067d1a2008-11-13 22:59:24 +0000562 if (in_array($this->file_type, $jpeg_mimes))
563 {
564 $this->file_type = 'image/jpeg';
565 }
566
567 $img_mimes = array(
568 'image/gif',
569 'image/jpeg',
570 'image/png',
Barry Mienydd671972010-10-04 16:33:58 +0200571 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000572
573 return (in_array($this->file_type, $img_mimes, TRUE)) ? TRUE : FALSE;
574 }
Barry Mienydd671972010-10-04 16:33:58 +0200575
Derek Allard2067d1a2008-11-13 22:59:24 +0000576 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200577
Derek Allard2067d1a2008-11-13 22:59:24 +0000578 /**
579 * Verify that the filetype is allowed
580 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000581 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +0200582 */
Greg Aker58fdee82010-11-10 15:07:09 -0600583 public function is_allowed_filetype($ignore_mime = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000584 {
Derek Jonese12f64e2010-03-02 22:55:08 -0600585 if ($this->allowed_types == '*')
586 {
587 return TRUE;
588 }
Barry Mienydd671972010-10-04 16:33:58 +0200589
Derek Allard2067d1a2008-11-13 22:59:24 +0000590 if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))
591 {
592 $this->set_error('upload_no_file_types');
593 return FALSE;
594 }
Barry Mienydd671972010-10-04 16:33:58 +0200595
Derek Jonese9d723f2010-07-12 10:10:59 -0500596 $ext = strtolower(ltrim($this->file_ext, '.'));
Barry Mienydd671972010-10-04 16:33:58 +0200597
Derek Jonese9d723f2010-07-12 10:10:59 -0500598 if ( ! in_array($ext, $this->allowed_types))
Derek Allard2067d1a2008-11-13 22:59:24 +0000599 {
Derek Jonese9d723f2010-07-12 10:10:59 -0500600 return FALSE;
601 }
Derek Jonesafa282f2009-02-10 17:11:52 +0000602
Barry Mienydd671972010-10-04 16:33:58 +0200603 // Images get some additional checks
Derek Jonese9d723f2010-07-12 10:10:59 -0500604 $image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');
Barry Mienydd671972010-10-04 16:33:58 +0200605
Derek Jonese9d723f2010-07-12 10:10:59 -0500606 if (in_array($ext, $image_types))
607 {
608 if (getimagesize($this->file_temp) === FALSE)
Derek Jonesafa282f2009-02-10 17:11:52 +0000609 {
Derek Jonese9d723f2010-07-12 10:10:59 -0500610 return FALSE;
Barry Mienydd671972010-10-04 16:33:58 +0200611 }
Derek Jonese9d723f2010-07-12 10:10:59 -0500612 }
Barry Mienydd671972010-10-04 16:33:58 +0200613
Derek Jonese9d723f2010-07-12 10:10:59 -0500614 if ($ignore_mime === TRUE)
615 {
616 return TRUE;
617 }
Barry Mienydd671972010-10-04 16:33:58 +0200618
Derek Jonese9d723f2010-07-12 10:10:59 -0500619 $mime = $this->mimes_types($ext);
Barry Mienydd671972010-10-04 16:33:58 +0200620
Derek Jonese9d723f2010-07-12 10:10:59 -0500621 if (is_array($mime))
622 {
623 if (in_array($this->file_type, $mime, TRUE))
Derek Allard2067d1a2008-11-13 22:59:24 +0000624 {
Derek Jonese9d723f2010-07-12 10:10:59 -0500625 return TRUE;
Barry Mienydd671972010-10-04 16:33:58 +0200626 }
Derek Jonese9d723f2010-07-12 10:10:59 -0500627 }
628 elseif ($mime == $this->file_type)
629 {
630 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000631 }
Barry Mienydd671972010-10-04 16:33:58 +0200632
Derek Allard2067d1a2008-11-13 22:59:24 +0000633 return FALSE;
634 }
Barry Mienydd671972010-10-04 16:33:58 +0200635
Derek Allard2067d1a2008-11-13 22:59:24 +0000636 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200637
Derek Allard2067d1a2008-11-13 22:59:24 +0000638 /**
639 * Verify that the file is within the allowed size
640 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000641 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +0200642 */
Greg Aker58fdee82010-11-10 15:07:09 -0600643 public function is_allowed_filesize()
Derek Allard2067d1a2008-11-13 22:59:24 +0000644 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500645 if ($this->max_size != 0 AND $this->file_size > $this->max_size)
Derek Allard2067d1a2008-11-13 22:59:24 +0000646 {
647 return FALSE;
648 }
649 else
650 {
651 return TRUE;
652 }
653 }
Barry Mienydd671972010-10-04 16:33:58 +0200654
Derek Allard2067d1a2008-11-13 22:59:24 +0000655 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200656
Derek Allard2067d1a2008-11-13 22:59:24 +0000657 /**
658 * Verify that the image is within the allowed width/height
659 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000660 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +0200661 */
Greg Aker58fdee82010-11-10 15:07:09 -0600662 public function is_allowed_dimensions()
Derek Allard2067d1a2008-11-13 22:59:24 +0000663 {
664 if ( ! $this->is_image())
665 {
666 return TRUE;
667 }
668
669 if (function_exists('getimagesize'))
670 {
671 $D = @getimagesize($this->file_temp);
672
673 if ($this->max_width > 0 AND $D['0'] > $this->max_width)
674 {
675 return FALSE;
676 }
677
678 if ($this->max_height > 0 AND $D['1'] > $this->max_height)
679 {
680 return FALSE;
681 }
682
683 return TRUE;
684 }
685
686 return TRUE;
687 }
Barry Mienydd671972010-10-04 16:33:58 +0200688
Derek Allard2067d1a2008-11-13 22:59:24 +0000689 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200690
Derek Allard2067d1a2008-11-13 22:59:24 +0000691 /**
692 * Validate Upload Path
693 *
694 * Verifies that it is a valid upload path with proper permissions.
695 *
696 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000697 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +0200698 */
Greg Aker58fdee82010-11-10 15:07:09 -0600699 public function validate_upload_path()
Derek Allard2067d1a2008-11-13 22:59:24 +0000700 {
701 if ($this->upload_path == '')
702 {
703 $this->set_error('upload_no_filepath');
704 return FALSE;
705 }
Barry Mienydd671972010-10-04 16:33:58 +0200706
Derek Allard2067d1a2008-11-13 22:59:24 +0000707 if (function_exists('realpath') AND @realpath($this->upload_path) !== FALSE)
708 {
709 $this->upload_path = str_replace("\\", "/", realpath($this->upload_path));
710 }
711
712 if ( ! @is_dir($this->upload_path))
713 {
714 $this->set_error('upload_no_filepath');
715 return FALSE;
716 }
717
718 if ( ! is_really_writable($this->upload_path))
719 {
720 $this->set_error('upload_not_writable');
721 return FALSE;
722 }
723
Derek Jones37f4b9c2011-07-01 17:56:50 -0500724 $this->upload_path = preg_replace("/(.+?)\/*$/", "\\1/", $this->upload_path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000725 return TRUE;
726 }
Barry Mienydd671972010-10-04 16:33:58 +0200727
Derek Allard2067d1a2008-11-13 22:59:24 +0000728 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200729
Derek Allard2067d1a2008-11-13 22:59:24 +0000730 /**
731 * Extract the file extension
732 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000733 * @param string
734 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200735 */
Greg Aker58fdee82010-11-10 15:07:09 -0600736 public function get_extension($filename)
Derek Allard2067d1a2008-11-13 22:59:24 +0000737 {
738 $x = explode('.', $filename);
739 return '.'.end($x);
Barry Mienydd671972010-10-04 16:33:58 +0200740 }
741
Derek Allard2067d1a2008-11-13 22:59:24 +0000742 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200743
Derek Allard2067d1a2008-11-13 22:59:24 +0000744 /**
745 * Clean the file name for security
746 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000747 * @param string
748 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200749 */
Greg Aker58fdee82010-11-10 15:07:09 -0600750 public function clean_file_name($filename)
Derek Allard2067d1a2008-11-13 22:59:24 +0000751 {
752 $bad = array(
753 "<!--",
754 "-->",
755 "'",
756 "<",
757 ">",
758 '"',
759 '&',
760 '$',
761 '=',
762 ';',
763 '?',
764 '/',
765 "%20",
766 "%22",
767 "%3c", // <
Barry Mienydd671972010-10-04 16:33:58 +0200768 "%253c", // <
769 "%3e", // >
770 "%0e", // >
771 "%28", // (
772 "%29", // )
773 "%2528", // (
774 "%26", // &
775 "%24", // $
776 "%3f", // ?
777 "%3b", // ;
Derek Allard2067d1a2008-11-13 22:59:24 +0000778 "%3d" // =
779 );
Barry Mienydd671972010-10-04 16:33:58 +0200780
Derek Allard2067d1a2008-11-13 22:59:24 +0000781 $filename = str_replace($bad, '', $filename);
782
783 return stripslashes($filename);
784 }
785
786 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200787
Derek Allard2067d1a2008-11-13 22:59:24 +0000788 /**
789 * Limit the File Name Length
790 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000791 * @param string
792 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200793 */
Greg Aker58fdee82010-11-10 15:07:09 -0600794 public function limit_filename_length($filename, $length)
Derek Allard2067d1a2008-11-13 22:59:24 +0000795 {
796 if (strlen($filename) < $length)
797 {
798 return $filename;
799 }
Barry Mienydd671972010-10-04 16:33:58 +0200800
Derek Allard2067d1a2008-11-13 22:59:24 +0000801 $ext = '';
802 if (strpos($filename, '.') !== FALSE)
803 {
804 $parts = explode('.', $filename);
805 $ext = '.'.array_pop($parts);
806 $filename = implode('.', $parts);
807 }
Barry Mienydd671972010-10-04 16:33:58 +0200808
Derek Allard2067d1a2008-11-13 22:59:24 +0000809 return substr($filename, 0, ($length - strlen($ext))).$ext;
810 }
811
812 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200813
Derek Allard2067d1a2008-11-13 22:59:24 +0000814 /**
815 * Runs the file through the XSS clean function
816 *
817 * This prevents people from embedding malicious code in their files.
818 * I'm not sure that it won't negatively affect certain files in unexpected ways,
819 * but so far I haven't found that it causes trouble.
820 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000821 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200822 */
Greg Aker58fdee82010-11-10 15:07:09 -0600823 public function do_xss_clean()
Barry Mienydd671972010-10-04 16:33:58 +0200824 {
Derek Jonese9d723f2010-07-12 10:10:59 -0500825 $file = $this->file_temp;
Barry Mienydd671972010-10-04 16:33:58 +0200826
Derek Allard2067d1a2008-11-13 22:59:24 +0000827 if (filesize($file) == 0)
828 {
829 return FALSE;
830 }
Barry Mienydd671972010-10-04 16:33:58 +0200831
Greg Akerf82e51c2010-04-14 19:33:50 -0500832 if (function_exists('memory_get_usage') && memory_get_usage() && ini_get('memory_limit') != '')
833 {
834 $current = ini_get('memory_limit') * 1024 * 1024;
Barry Mienydd671972010-10-04 16:33:58 +0200835
Greg Akerc78a2592010-06-09 11:45:32 -0500836 // There was a bug/behavioural change in PHP 5.2, where numbers over one million get output
Derek Jones37f4b9c2011-07-01 17:56:50 -0500837 // into scientific notation. number_format() ensures this number is an integer
Greg Akerc78a2592010-06-09 11:45:32 -0500838 // http://bugs.php.net/bug.php?id=43053
Barry Mienydd671972010-10-04 16:33:58 +0200839
Greg Akerc78a2592010-06-09 11:45:32 -0500840 $new_memory = number_format(ceil(filesize($file) + $current), 0, '.', '');
Barry Mienydd671972010-10-04 16:33:58 +0200841
Greg Akerc78a2592010-06-09 11:45:32 -0500842 ini_set('memory_limit', $new_memory); // When an integer is used, the value is measured in bytes. - PHP.net
Greg Akerf82e51c2010-04-14 19:33:50 -0500843 }
844
845 // If the file being uploaded is an image, then we should have no problem with XSS attacks (in theory), but
846 // IE can be fooled into mime-type detecting a malformed image as an html file, thus executing an XSS attack on anyone
Derek Jones37f4b9c2011-07-01 17:56:50 -0500847 // using IE who looks at the image. It does this by inspecting the first 255 bytes of an image. To get around this
848 // CI will itself look at the first 255 bytes of an image to determine its relative safety. This can save a lot of
Barry Mienydd671972010-10-04 16:33:58 +0200849 // processor power and time if it is actually a clean image, as it will be in nearly all instances _except_ an
Greg Akerf82e51c2010-04-14 19:33:50 -0500850 // attempted XSS attack.
851
852 if (function_exists('getimagesize') && @getimagesize($file) !== FALSE)
853 {
Barry Mienydd671972010-10-04 16:33:58 +0200854 if (($file = @fopen($file, 'rb')) === FALSE) // "b" to force binary
855 {
Greg Akerf82e51c2010-04-14 19:33:50 -0500856 return FALSE; // Couldn't open the file, return FALSE
Barry Mienydd671972010-10-04 16:33:58 +0200857 }
Greg Akerf82e51c2010-04-14 19:33:50 -0500858
Barry Mienydd671972010-10-04 16:33:58 +0200859 $opening_bytes = fread($file, 256);
860 fclose($file);
Greg Akerf82e51c2010-04-14 19:33:50 -0500861
862 // These are known to throw IE into mime-type detection chaos
863 // <a, <body, <head, <html, <img, <plaintext, <pre, <script, <table, <title
864 // title is basically just in SVG, but we filter it anyhow
865
866 if ( ! preg_match('/<(a|body|head|html|img|plaintext|pre|script|table|title)[\s>]/i', $opening_bytes))
867 {
868 return TRUE; // its an image, no "triggers" detected in the first 256 bytes, we're good
869 }
870 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000871
872 if (($data = @file_get_contents($file)) === FALSE)
873 {
874 return FALSE;
875 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000876
Greg Akerf82e51c2010-04-14 19:33:50 -0500877 $CI =& get_instance();
Greg Akerf82e51c2010-04-14 19:33:50 -0500878 return $CI->security->xss_clean($data, TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000879 }
Barry Mienydd671972010-10-04 16:33:58 +0200880
Derek Allard2067d1a2008-11-13 22:59:24 +0000881 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200882
Derek Allard2067d1a2008-11-13 22:59:24 +0000883 /**
884 * Set an error message
885 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000886 * @param string
887 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200888 */
Greg Aker58fdee82010-11-10 15:07:09 -0600889 public function set_error($msg)
Derek Allard2067d1a2008-11-13 22:59:24 +0000890 {
Barry Mienydd671972010-10-04 16:33:58 +0200891 $CI =& get_instance();
Derek Allard2067d1a2008-11-13 22:59:24 +0000892 $CI->lang->load('upload');
Barry Mienydd671972010-10-04 16:33:58 +0200893
Derek Allard2067d1a2008-11-13 22:59:24 +0000894 if (is_array($msg))
895 {
896 foreach ($msg as $val)
897 {
Barry Mienydd671972010-10-04 16:33:58 +0200898 $msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);
Derek Allard2067d1a2008-11-13 22:59:24 +0000899 $this->error_msg[] = $msg;
900 log_message('error', $msg);
Barry Mienydd671972010-10-04 16:33:58 +0200901 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000902 }
903 else
904 {
905 $msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);
906 $this->error_msg[] = $msg;
907 log_message('error', $msg);
908 }
909 }
Barry Mienydd671972010-10-04 16:33:58 +0200910
Derek Allard2067d1a2008-11-13 22:59:24 +0000911 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200912
Derek Allard2067d1a2008-11-13 22:59:24 +0000913 /**
914 * Display the error message
915 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000916 * @param string
917 * @param string
918 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200919 */
Greg Aker58fdee82010-11-10 15:07:09 -0600920 public function display_errors($open = '<p>', $close = '</p>')
Derek Allard2067d1a2008-11-13 22:59:24 +0000921 {
922 $str = '';
923 foreach ($this->error_msg as $val)
924 {
925 $str .= $open.$val.$close;
926 }
Barry Mienydd671972010-10-04 16:33:58 +0200927
Derek Allard2067d1a2008-11-13 22:59:24 +0000928 return $str;
929 }
Barry Mienydd671972010-10-04 16:33:58 +0200930
Derek Allard2067d1a2008-11-13 22:59:24 +0000931 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200932
Derek Allard2067d1a2008-11-13 22:59:24 +0000933 /**
934 * List of Mime Types
935 *
Derek Jones37f4b9c2011-07-01 17:56:50 -0500936 * This is a list of mime types. We use it to validate
Derek Allard2067d1a2008-11-13 22:59:24 +0000937 * the "allowed types" set by the developer
938 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000939 * @param string
940 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200941 */
Greg Aker58fdee82010-11-10 15:07:09 -0600942 public function mimes_types($mime)
Derek Allard2067d1a2008-11-13 22:59:24 +0000943 {
944 global $mimes;
Barry Mienydd671972010-10-04 16:33:58 +0200945
Derek Allard2067d1a2008-11-13 22:59:24 +0000946 if (count($this->mimes) == 0)
947 {
Greg Aker3a746652011-04-19 10:59:47 -0500948 if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
bubbafoley0ea04142011-03-17 14:55:41 -0500949 {
Greg Aker3a746652011-04-19 10:59:47 -0500950 include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php');
Eric Barnesfdd5b112011-03-21 21:28:58 -0400951 }
Greg Aker3a746652011-04-19 10:59:47 -0500952 elseif (is_file(APPPATH.'config/mimes.php'))
Eric Barnesfdd5b112011-03-21 21:28:58 -0400953 {
Greg Aker3a746652011-04-19 10:59:47 -0500954 include(APPPATH.'config//mimes.php');
bubbafoley0ea04142011-03-17 14:55:41 -0500955 }
956 else
957 {
Eric Barnesfdd5b112011-03-21 21:28:58 -0400958 return FALSE;
bubbafoley0ea04142011-03-17 14:55:41 -0500959 }
Eric Barnes92808342011-03-18 09:02:37 -0400960
Eric Barnesfdd5b112011-03-21 21:28:58 -0400961 $this->mimes = $mimes;
962 unset($mimes);
Derek Allard2067d1a2008-11-13 22:59:24 +0000963 }
Barry Mienydd671972010-10-04 16:33:58 +0200964
Derek Allard2067d1a2008-11-13 22:59:24 +0000965 return ( ! isset($this->mimes[$mime])) ? FALSE : $this->mimes[$mime];
966 }
967
968 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200969
Derek Allard2067d1a2008-11-13 22:59:24 +0000970 /**
971 * Prep Filename
972 *
973 * Prevents possible script execution from Apache's handling of files multiple extensions
974 * http://httpd.apache.org/docs/1.3/mod/mod_mime.html#multipleext
975 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000976 * @param string
977 * @return string
978 */
Greg Aker58fdee82010-11-10 15:07:09 -0600979 protected function _prep_filename($filename)
Derek Allard2067d1a2008-11-13 22:59:24 +0000980 {
Greg Aker924000e2010-07-22 11:04:58 -0500981 if (strpos($filename, '.') === FALSE OR $this->allowed_types == '*')
Derek Allard2067d1a2008-11-13 22:59:24 +0000982 {
983 return $filename;
984 }
Derek Allard616dab82009-02-16 15:44:32 +0000985
Derek Allard2067d1a2008-11-13 22:59:24 +0000986 $parts = explode('.', $filename);
987 $ext = array_pop($parts);
988 $filename = array_shift($parts);
Derek Allard616dab82009-02-16 15:44:32 +0000989
Derek Allard2067d1a2008-11-13 22:59:24 +0000990 foreach ($parts as $part)
991 {
Derek Jonese9d723f2010-07-12 10:10:59 -0500992 if ( ! in_array(strtolower($part), $this->allowed_types) OR $this->mimes_types(strtolower($part)) === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000993 {
994 $filename .= '.'.$part.'_';
995 }
996 else
997 {
998 $filename .= '.'.$part;
999 }
1000 }
Derek Allardd70b0642009-02-16 13:51:42 +00001001
Derek Allard2067d1a2008-11-13 22:59:24 +00001002 $filename .= '.'.$ext;
Barry Mienydd671972010-10-04 16:33:58 +02001003
Derek Allard2067d1a2008-11-13 22:59:24 +00001004 return $filename;
1005 }
1006
1007 // --------------------------------------------------------------------
1008
1009}
1010// END Upload Class
1011
1012/* End of file Upload.php */
Greg Aker58fdee82010-11-10 15:07:09 -06001013/* Location: ./system/libraries/Upload.php */