/** * Test Settings */ function test_upload(&$error, $upload_dir, $create_directory = false) { global $user, $src_root_path; // Does the target directory exist, is it a directory and writable. if ($create_directory) { if (!file_exists($src_root_path . $upload_dir)) { @mkdir($src_root_path . $upload_dir, 0777); src_chmod($src_root_path . $upload_dir, CHMOD_READ | CHMOD_WRITE); } } if (!file_exists($src_root_path . $upload_dir)) { $error[] = sprintf($user->lang['NO_UPLOAD_DIR'], $upload_dir); return; } if (!is_dir($src_root_path . $upload_dir)) { $error[] = sprintf($user->lang['UPLOAD_NOT_DIR'], $upload_dir); return; } if (!src_is_writable($src_root_path . $upload_dir)) { $error[] = sprintf($user->lang['NO_WRITE_UPLOAD'], $upload_dir); return; } }
/** * Move file to destination folder * The src_root_path variable will be applied to the destination path * * @param string $destination Destination path, for example $config['avatar_path'] * @param bool $overwrite If set to true, an already existing file will be overwritten * @param bool $skip_image_check If set to true, the check for the file to be a valid image is skipped * @param string $chmod Permission mask for chmodding the file after a successful move. The mode entered here reflects the mode defined by {@link src_chmod()} * * @access public */ function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = false) { global $user, $src_root_path; if (sizeof($this->error)) { return false; } $chmod = $chmod === false ? CHMOD_READ | CHMOD_WRITE : $chmod; // We need to trust the admin in specifying valid upload directories and an attacker not being able to overwrite it... $this->destination_path = $src_root_path . $destination; // Check if the destination path exist... if (!file_exists($this->destination_path)) { @unlink($this->filename); return false; } $upload_mode = @ini_get('open_basedir') || @ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'on' ? 'move' : 'copy'; $upload_mode = $this->local ? 'local' : $upload_mode; $this->destination_file = $this->destination_path . '/' . utf8_basename($this->realname); // Check if the file already exist, else there is something wrong... if (file_exists($this->destination_file) && !$overwrite) { @unlink($this->filename); $this->error[] = $user->lang($this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR', $this->destination_file); $this->file_moved = false; return false; } else { if (file_exists($this->destination_file)) { @unlink($this->destination_file); } switch ($upload_mode) { case 'copy': if (!@copy($this->filename, $this->destination_file)) { if (!@move_uploaded_file($this->filename, $this->destination_file)) { $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file); } } break; case 'move': if (!@move_uploaded_file($this->filename, $this->destination_file)) { if (!@copy($this->filename, $this->destination_file)) { $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file); } } break; case 'local': if (!@copy($this->filename, $this->destination_file)) { $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file); } break; } // Remove temporary filename @unlink($this->filename); if (sizeof($this->error)) { return false; } src_chmod($this->destination_file, $chmod); } // Try to get real filesize from destination folder $this->filesize = @filesize($this->destination_file) ? @filesize($this->destination_file) : $this->filesize; // Get mimetype of supplied file $this->mimetype = $this->get_mimetype($this->destination_file); if ($this->is_image() && !$skip_image_check) { $this->width = $this->height = 0; if (($this->image_info = @getimagesize($this->destination_file)) !== false) { $this->width = $this->image_info[0]; $this->height = $this->image_info[1]; if (!empty($this->image_info['mime'])) { $this->mimetype = $this->image_info['mime']; } // Check image type $types = fileupload::image_types(); if (!isset($types[$this->image_info[2]]) || !in_array($this->extension, $types[$this->image_info[2]])) { if (!isset($types[$this->image_info[2]])) { $this->error[] = sprintf($user->lang['IMAGE_FILETYPE_INVALID'], $this->image_info[2], $this->mimetype); } else { $this->error[] = sprintf($user->lang['IMAGE_FILETYPE_MISMATCH'], $types[$this->image_info[2]][0], $this->extension); } } // Make sure the dimensions match a valid image if (empty($this->width) || empty($this->height)) { $this->error[] = $user->lang['ATTACHED_IMAGE_NOT_IMAGE']; } } else { $this->error[] = $user->lang['UNABLE_GET_IMAGE_SIZE']; } } $this->file_moved = true; $this->additional_checks(); unset($this->upload); return true; }
/** * Create Thumbnail */ function create_thumbnail($source, $destination, $mimetype) { global $config; $min_filesize = (int) $config['img_min_thumb_filesize']; $img_filesize = file_exists($source) ? @filesize($source) : false; if (!$img_filesize || $img_filesize <= $min_filesize) { return false; } $dimension = @getimagesize($source); if ($dimension === false) { return false; } list($width, $height, $type, ) = $dimension; if (empty($width) || empty($height)) { return false; } list($new_width, $new_height) = get_img_size_format($width, $height); // Do not create a thumbnail if the resulting width/height is bigger than the original one if ($new_width >= $width && $new_height >= $height) { return false; } $used_imagick = false; // Only use imagemagick if defined and the passthru function not disabled if ($config['img_imagick'] && function_exists('passthru')) { if (substr($config['img_imagick'], -1) !== '/') { $config['img_imagick'] .= '/'; } @passthru(escapeshellcmd($config['img_imagick']) . 'convert' . (defined('PHP_OS') && preg_match('#^win#i', PHP_OS) ? '.exe' : '') . ' -quality 85 -geometry ' . $new_width . 'x' . $new_height . ' "' . str_replace('\\', '/', $source) . '" "' . str_replace('\\', '/', $destination) . '"'); if (file_exists($destination)) { $used_imagick = true; } } if (!$used_imagick) { $type = get_supported_image_types($type); if ($type['gd']) { // If the type is not supported, we are not able to create a thumbnail if ($type['format'] === false) { return false; } switch ($type['format']) { case IMG_GIF: $image = @imagecreatefromgif($source); break; case IMG_JPG: @ini_set('gd.jpeg_ignore_warning', 1); $image = @imagecreatefromjpeg($source); break; case IMG_PNG: $image = @imagecreatefrompng($source); break; case IMG_WBMP: $image = @imagecreatefromwbmp($source); break; } if (empty($image)) { return false; } if ($type['version'] == 1) { $new_image = imagecreate($new_width, $new_height); if ($new_image === false) { return false; } imagecopyresized($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); } else { $new_image = imagecreatetruecolor($new_width, $new_height); if ($new_image === false) { return false; } // Preserve alpha transparency (png for example) @imagealphablending($new_image, false); @imagesavealpha($new_image, true); imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); } // If we are in safe mode create the destination file prior to using the gd functions to circumvent a PHP bug if (@ini_get('safe_mode') || @strtolower(ini_get('safe_mode')) == 'on') { @touch($destination); } switch ($type['format']) { case IMG_GIF: imagegif($new_image, $destination); break; case IMG_JPG: imagejpeg($new_image, $destination, 90); break; case IMG_PNG: imagepng($new_image, $destination); break; case IMG_WBMP: imagewbmp($new_image, $destination); break; } imagedestroy($new_image); } else { return false; } } if (!file_exists($destination)) { return false; } src_chmod($destination, CHMOD_READ | CHMOD_WRITE); return true; }
/** * Extract archive */ function extract($dst) { $fzread = $this->isbz && function_exists('bzread') ? 'bzread' : ($this->isgz && @extension_loaded('zlib') ? 'gzread' : 'fread'); // Run through the file and grab directory entries while ($buffer = $fzread($this->fp, 512)) { $tmp = unpack('A6magic', substr($buffer, 257, 6)); if (trim($tmp['magic']) == 'ustar') { $tmp = unpack('A100name', $buffer); $filename = trim($tmp['name']); $tmp = unpack('Atype', substr($buffer, 156, 1)); $filetype = (int) trim($tmp['type']); $tmp = unpack('A12size', substr($buffer, 124, 12)); $filesize = octdec((int) trim($tmp['size'])); $target_filename = "{$dst}{$filename}"; if ($filetype == 5) { if (!is_dir($target_filename)) { $str = ''; $folders = explode('/', $target_filename); // Create and folders and subfolders if they do not exist foreach ($folders as $folder) { $folder = trim($folder); if (!$folder) { continue; } $str = !empty($str) ? $str . '/' . $folder : $folder; if (!is_dir($str)) { if (!@mkdir($str, 0777)) { trigger_error("Could not create directory {$folder}"); } src_chmod($str, CHMOD_READ | CHMOD_WRITE); } } } } else { if ($filesize >= 0 && ($filetype == 0 || $filetype == "")) { // Some archivers are punks, they don't properly order the folders in their archives! $str = ''; $folders = explode('/', pathinfo($target_filename, PATHINFO_DIRNAME)); // Create and folders and subfolders if they do not exist foreach ($folders as $folder) { $folder = trim($folder); if (!$folder) { continue; } $str = !empty($str) ? $str . '/' . $folder : $folder; if (!is_dir($str)) { if (!@mkdir($str, 0777)) { trigger_error("Could not create directory {$folder}"); } src_chmod($str, CHMOD_READ | CHMOD_WRITE); } } // Write out the files if (!($fp = fopen($target_filename, 'wb'))) { trigger_error("Couldn't create file {$filename}"); } src_chmod($target_filename, CHMOD_READ); // Grab the file contents fwrite($fp, $filesize ? $fzread($this->fp, $filesize + 511 & ~511) : '', $filesize); fclose($fp); } } } } }
/** * Write cache data to a specified file * * 'data_global' is a special case and the generated format is different for this file: * <code> * <?php exit; ?> * (expiration) * (length of var and serialised data) * (var) * (serialised data) * ... (repeat) * </code> * * The other files have a similar format: * <code> * <?php exit; ?> * (expiration) * (query) [SQL files only] * (length of serialised data) * (serialised data) * </code> * * @access private * @param string $filename Filename to write * @param mixed $data Data to store * @param int $expires Timestamp when the data expires * @param string $query Query when caching SQL queries * @return bool True if the file was successfully created, otherwise false */ function _write($filename, $data = null, $expires = 0, $query = '') { global $phpEx; $filename = $this->clean_varname($filename); $file = "{$this->cache_dir}{$filename}.{$phpEx}"; $lock = new \src\lock\flock($file); $lock->acquire(); if ($handle = @fopen($file, 'wb')) { // File header fwrite($handle, '<' . '?php exit; ?' . '>'); if ($filename == 'data_global') { // Global data is a different format foreach ($this->vars as $var => $data) { if (strpos($var, "\r") !== false || strpos($var, "\n") !== false) { // CR/LF would cause fgets() to read the cache file incorrectly // do not cache test entries, they probably won't be read back // the cache keys should really be alphanumeric with a few symbols. continue; } $data = serialize($data); // Write out the expiration time fwrite($handle, "\n" . $this->var_expires[$var] . "\n"); // Length of the remaining data for this var (ignoring two LF's) fwrite($handle, strlen($data . $var) . "\n"); fwrite($handle, $var . "\n"); fwrite($handle, $data); } } else { fwrite($handle, "\n" . $expires . "\n"); if (strpos($filename, 'sql_') === 0) { fwrite($handle, $query . "\n"); } $data = serialize($data); fwrite($handle, strlen($data) . "\n"); fwrite($handle, $data); } fclose($handle); if (!function_exists('src_chmod')) { global $src_root_path; include $src_root_path . 'includes/functions.' . $phpEx; } src_chmod($file, CHMOD_READ | CHMOD_WRITE); $return_value = true; } else { $return_value = false; } $lock->release(); return $return_value; }
/** * Writes the config file to disk, or if unable to do so offers alternative methods */ function create_config_file($mode, $sub) { global $lang, $template, $src_root_path, $phpEx; $this->page_title = $lang['STAGE_CONFIG_FILE']; // Obtain any submitted data $data = $this->get_submitted_data(); if ($data['dbms'] == '') { // Someone's been silly and tried calling this page direct // So we send them back to the start to do it again properly $this->p_master->redirect("index.{$phpEx}?mode=install"); } $s_hidden_fields = $data['img_imagick'] ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : ''; $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />'; $written = false; // Create a list of any PHP modules we wish to have loaded $available_dbms = get_available_dbms($data['dbms']); // Create a lock file to indicate that there is an install in progress $fp = @fopen($src_root_path . 'cache/install_lock', 'wb'); if ($fp === false) { // We were unable to create the lock file - abort $this->p_master->error($lang['UNABLE_WRITE_LOCK'], __LINE__, __FILE__); } @fclose($fp); @chmod($src_root_path . 'cache/install_lock', 0777); // Time to convert the data provided into a config file $config_data = src_create_config_file_data($data, $available_dbms[$data['dbms']]['DRIVER']); // Attempt to write out the config file directly. If it works, this is the easiest way to do it ... if (file_exists($src_root_path . 'config.' . $phpEx) && src_is_writable($src_root_path . 'config.' . $phpEx) || src_is_writable($src_root_path)) { // Assume it will work ... if nothing goes wrong below $written = true; if (!($fp = @fopen($src_root_path . 'config.' . $phpEx, 'w'))) { // Something went wrong ... so let's try another method $written = false; } if (!@fwrite($fp, $config_data)) { // Something went wrong ... so let's try another method $written = false; } @fclose($fp); if ($written) { // We may revert back to chmod() if we see problems with users not able to change their config.php file directly src_chmod($src_root_path . 'config.' . $phpEx, CHMOD_READ); } } if (isset($_POST['dldone'])) { // Do a basic check to make sure that the file has been uploaded // Note that all we check is that the file has _something_ in it // We don't compare the contents exactly - if they can't upload // a single file correctly, it's likely they will have other problems.... if (filesize($src_root_path . 'config.' . $phpEx) > 10) { $written = true; } } $config_options = array_merge($this->db_config_options, $this->admin_config_options); foreach ($config_options as $config_key => $vars) { if (!is_array($vars)) { continue; } $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />'; } if (!$written) { // OK, so it didn't work let's try the alternatives if (isset($_POST['dlconfig'])) { // They want a copy of the file to download, so send the relevant headers and dump out the data header("Content-Type: text/x-delimtext; name=\"config.{$phpEx}\""); header("Content-disposition: attachment; filename=config.{$phpEx}"); echo $config_data; exit; } // The option to download the config file is always available, so output it here $template->assign_vars(array('BODY' => $lang['CONFIG_FILE_UNABLE_WRITE'], 'L_DL_CONFIG' => $lang['DL_CONFIG'], 'L_DL_CONFIG_EXPLAIN' => $lang['DL_CONFIG_EXPLAIN'], 'L_DL_DONE' => $lang['DONE'], 'L_DL_DOWNLOAD' => $lang['DL_DOWNLOAD'], 'S_HIDDEN' => $s_hidden_fields, 'S_SHOW_DOWNLOAD' => true, 'U_ACTION' => $this->p_master->module_url . "?mode={$mode}&sub=config_file")); return; } else { $template->assign_vars(array('BODY' => $lang['CONFIG_FILE_WRITTEN'], 'L_SUBMIT' => $lang['NEXT_STEP'], 'S_HIDDEN' => $s_hidden_fields, 'U_ACTION' => $this->p_master->module_url . "?mode={$mode}&sub=advanced")); return; } }
/** * Save queue */ function save() { if (!sizeof($this->data)) { return; } $lock = new \src\lock\flock($this->cache_file); $lock->acquire(); if (file_exists($this->cache_file)) { include $this->cache_file; foreach ($this->queue_data as $object => $data_ary) { if (isset($this->data[$object]) && sizeof($this->data[$object])) { $this->data[$object]['data'] = array_merge($data_ary['data'], $this->data[$object]['data']); } else { $this->data[$object]['data'] = $data_ary['data']; } } } if ($fp = @fopen($this->cache_file, 'w')) { fwrite($fp, "<?php\nif (!defined('IN_src')) exit;\n\$this->queue_data = unserialize(" . var_export(serialize($this->data), true) . ");\n\n?>"); fclose($fp); src_chmod($this->cache_file, CHMOD_READ | CHMOD_WRITE); } $lock->release(); }