/** * Move file from another location to phpBB */ function local_upload($source_file, $filedata = false) { global $user; $form_name = 'local'; $_FILES[$form_name]['local_mode'] = true; $_FILES[$form_name]['tmp_name'] = $source_file; if ($filedata === false) { $_FILES[$form_name]['name'] = utf8_basename($source_file); $_FILES[$form_name]['size'] = 0; $mimetype = ''; if (function_exists('mime_content_type')) { $mimetype = mime_content_type($source_file); } // Some browsers choke on a mimetype of application/octet-stream if (!$mimetype || $mimetype == 'application/octet-stream') { $mimetype = 'application/octetstream'; } $_FILES[$form_name]['type'] = $mimetype; } else { $_FILES[$form_name]['name'] = $filedata['realname']; $_FILES[$form_name]['size'] = $filedata['size']; $_FILES[$form_name]['type'] = $filedata['type']; } $file = new filespec($_FILES[$form_name], $this); if ($file->init_error) { $file->error[] = ''; return $file; } if (isset($_FILES[$form_name]['error'])) { $error = $this->assign_internal_error($_FILES[$form_name]['error']); if ($error !== false) { $file->error[] = $error; return $file; } } // PHP Upload filesize exceeded if ($file->get('filename') == 'none') { $max_filesize = @ini_get('upload_max_filesize'); $unit = 'MB'; if (!empty($max_filesize)) { $unit = strtolower(substr($max_filesize, -1, 1)); $max_filesize = (int) $max_filesize; $unit = $unit == 'k' ? 'KB' : ($unit == 'g' ? 'GB' : 'MB'); } $file->error[] = empty($max_filesize) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]); return $file; } // Not correctly uploaded if (!$file->is_uploaded()) { $file->error[] = $user->lang[$this->error_prefix . 'NOT_UPLOADED']; return $file; } $this->common_checks($file); return $file; }
/** * Remote avatar linkage */ function avatar_remote($data, &$error) { global $config, $db, $user, $phpbb_root_path, $phpEx; if (!preg_match('#^(http|https|ftp)://#i', $data['remotelink'])) { $data['remotelink'] = 'http://' . $data['remotelink']; } if (!preg_match('#^(http|https|ftp)://(?:(.*?\\.)*?[a-z0-9\\-]+?\\.[a-z]{2,4}|(?:\\d{1,3}\\.){3,5}\\d{1,3}):?([0-9]*?).*?\\.(gif|jpg|jpeg|png)$#i', $data['remotelink'])) { $error[] = $user->lang['AVATAR_URL_INVALID']; return false; } // Make sure getimagesize works... if (($image_data = @getimagesize($data['remotelink'])) === false && (empty($data['width']) || empty($data['height']))) { $error[] = $user->lang['UNABLE_GET_IMAGE_SIZE']; return false; } if (!empty($image_data) && ($image_data[0] < 2 || $image_data[1] < 2)) { $error[] = $user->lang['AVATAR_NO_SIZE']; return false; } $width = $data['width'] && $data['height'] ? $data['width'] : $image_data[0]; $height = $data['width'] && $data['height'] ? $data['height'] : $image_data[1]; if ($width < 2 || $height < 2) { $error[] = $user->lang['AVATAR_NO_SIZE']; return false; } // Check image type include_once $phpbb_root_path . 'includes/functions_upload.' . $phpEx; $types = fileupload::image_types(); $extension = strtolower(filespec::get_extension($data['remotelink'])); if (!empty($image_data) && (!isset($types[$image_data[2]]) || !in_array($extension, $types[$image_data[2]]))) { if (!isset($types[$image_data[2]])) { $error[] = $user->lang['UNABLE_GET_IMAGE_SIZE']; } else { $error[] = sprintf($user->lang['IMAGE_FILETYPE_MISMATCH'], $types[$image_data[2]][0], $extension); } return false; } if ($config['avatar_max_width'] || $config['avatar_max_height']) { if ($width > $config['avatar_max_width'] || $height > $config['avatar_max_height']) { $error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $width, $height); return false; } } if ($config['avatar_min_width'] || $config['avatar_min_height']) { if ($width < $config['avatar_min_width'] || $height < $config['avatar_min_height']) { $error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $width, $height); return false; } } return array(AVATAR_REMOTE, $data['remotelink'], $width, $height); }
/** * Move file from another location to phpBB */ function local_upload($source_file, $filedata = false, \phpbb\mimetype\guesser $mimetype_guesser = null) { global $user, $request; $upload = array(); $upload['local_mode'] = true; $upload['tmp_name'] = $source_file; if ($filedata === false) { $upload['name'] = utf8_basename($source_file); $upload['size'] = 0; } else { $upload['name'] = $filedata['realname']; $upload['size'] = $filedata['size']; $upload['type'] = $filedata['type']; } $file = new filespec($upload, $this, $mimetype_guesser); if ($file->init_error) { $file->error[] = ''; return $file; } if (isset($upload['error'])) { $error = $this->assign_internal_error($upload['error']); if ($error !== false) { $file->error[] = $error; return $file; } } // PHP Upload filesize exceeded if ($file->get('filename') == 'none') { $max_filesize = @ini_get('upload_max_filesize'); $unit = 'MB'; if (!empty($max_filesize)) { $unit = strtolower(substr($max_filesize, -1, 1)); $max_filesize = (int) $max_filesize; $unit = $unit == 'k' ? 'KB' : ($unit == 'g' ? 'GB' : 'MB'); } $file->error[] = empty($max_filesize) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]); return $file; } // Not correctly uploaded if (!$file->is_uploaded()) { $file->error[] = $user->lang[$this->error_prefix . 'NOT_UPLOADED']; return $file; } $this->common_checks($file); $request->overwrite('local', $upload, \phpbb\request\request_interface::FILES); return $file; }
function local_upload($source_file, $filedata = false) { global $_CLASS; $form_name = 'local'; $_FILES[$form_name]['local_mode'] = true; $_FILES[$form_name]['tmp_name'] = $source_file; if ($filedata === false) { $_FILES[$form_name]['name'] = basename($source_file); $_FILES[$form_name]['size'] = 0; $_FILES[$form_name]['type'] = ''; } else { $_FILES[$form_name]['name'] = $filedata['realname']; $_FILES[$form_name]['size'] = $filedata['size']; $_FILES[$form_name]['type'] = $filedata['type']; } $file = new filespec($_FILES[$form_name], $this); if ($file->init_error) { $file->error[] = ''; return $file; } if (isset($_FILES[$form_name]['error'])) { $error = $this->assign_internal_error($_FILES[$form_name]['error']); if ($error !== false) { $file->error[] = $error; return $file; } } // PHP Upload filesize exceeded if ($file->get('filename') == 'none') { $file->error[] = @ini_get('upload_max_filesize') == '' ? $_CLASS['core_user']->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($_CLASS['core_user']->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], @ini_get('upload_max_filesize')); return $file; } // Not correctly uploaded if (!$file->is_uploaded()) { $file->error[] = $_CLASS['core_user']->lang[$this->error_prefix . 'NOT_UPLOADED']; return $file; } $this->common_checks($file); return $file; }
/** * {@inheritdoc} */ public function process_form($request, $template, $user, $row, &$error) { $url = $request->variable('avatar_remote_url', ''); $width = $request->variable('avatar_remote_width', 0); $height = $request->variable('avatar_remote_height', 0); if (empty($url)) { return false; } if (!preg_match('#^(http|https|ftp)://#i', $url)) { $url = 'http://' . $url; } if (!function_exists('validate_data')) { require $this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext; } $validate_array = validate_data(array('url' => $url), array('url' => array('string', true, 5, 255))); $error = array_merge($error, $validate_array); if (!empty($error)) { return false; } // Check if this url looks alright // This isn't perfect, but it's what phpBB 3.0 did, and might as well make sure everything is compatible if (!preg_match('#^(http|https|ftp)://(?:(.*?\\.)*?[a-z0-9\\-]+?\\.[a-z]{2,4}|(?:\\d{1,3}\\.){3,5}\\d{1,3}):?([0-9]*?).*?\\.(' . implode('|', $this->allowed_extensions) . ')$#i', $url)) { $error[] = 'AVATAR_URL_INVALID'; return false; } // Make sure getimagesize works... if (function_exists('getimagesize')) { if (($width <= 0 || $height <= 0) && ($image_data = @getimagesize($url)) === false) { $error[] = 'UNABLE_GET_IMAGE_SIZE'; return false; } if (!empty($image_data) && ($image_data[0] <= 0 || $image_data[1] <= 0)) { $error[] = 'AVATAR_NO_SIZE'; return false; } $width = $width && $height ? $width : $image_data[0]; $height = $width && $height ? $height : $image_data[1]; } if ($width <= 0 || $height <= 0) { $error[] = 'AVATAR_NO_SIZE'; return false; } if (!class_exists('fileupload')) { include $this->phpbb_root_path . 'includes/functions_upload.' . $this->php_ext; } $types = \fileupload::image_types(); $extension = strtolower(\filespec::get_extension($url)); // Check if this is actually an image if ($file_stream = @fopen($url, 'r')) { // Timeout after 1 second stream_set_timeout($file_stream, 1); // read some data to ensure headers are present fread($file_stream, 1024); $meta = stream_get_meta_data($file_stream); if (isset($meta['wrapper_data']['headers']) && is_array($meta['wrapper_data']['headers'])) { $headers = $meta['wrapper_data']['headers']; } else { if (isset($meta['wrapper_data']) && is_array($meta['wrapper_data'])) { $headers = $meta['wrapper_data']; } else { $headers = array(); } } foreach ($headers as $header) { $header = preg_split('/ /', $header, 2); if (strtr(strtolower(trim($header[0], ':')), '_', '-') === 'content-type') { if (strpos($header[1], 'image/') !== 0) { $error[] = 'AVATAR_URL_INVALID'; fclose($file_stream); return false; } else { fclose($file_stream); break; } } } } else { $error[] = 'AVATAR_URL_INVALID'; return false; } if (!empty($image_data) && (!isset($types[$image_data[2]]) || !in_array($extension, $types[$image_data[2]]))) { if (!isset($types[$image_data[2]])) { $error[] = 'UNABLE_GET_IMAGE_SIZE'; } else { $error[] = array('IMAGE_FILETYPE_MISMATCH', $types[$image_data[2]][0], $extension); } return false; } if ($this->config['avatar_max_width'] || $this->config['avatar_max_height']) { if ($width > $this->config['avatar_max_width'] || $height > $this->config['avatar_max_height']) { $error[] = array('AVATAR_WRONG_SIZE', $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], $width, $height); return false; } } if ($this->config['avatar_min_width'] || $this->config['avatar_min_height']) { if ($width < $this->config['avatar_min_width'] || $height < $this->config['avatar_min_height']) { $error[] = array('AVATAR_WRONG_SIZE', $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], $width, $height); return false; } } return array('avatar' => $url, 'avatar_width' => $width, 'avatar_height' => $height); }
/** * The function that uploads the specified extension. * * @param string $action Requested action. * @param \filespec $file Filespec object. * @param string $upload_dir The directory for zip files storage. * @return string|bool */ public function get_dest_file($action, $file, $upload_dir) { global $phpbb_root_path, $template, $user, $request; if ($action != 'upload_local') { if (empty($file->filename)) { files::catch_errors(sizeof($file->error) ? implode('<br />', $file->error) : $user->lang['NO_UPLOAD_FILE']); return false; } else { if ($file->init_error || sizeof($file->error)) { $file->remove(); files::catch_errors(sizeof($file->error) ? implode('<br />', $file->error) : $user->lang['EXT_UPLOAD_INIT_FAIL']); return false; } } $file->clean_filename('real'); $file->move_file(str_replace($phpbb_root_path, '', $upload_dir), true, true); if (sizeof($file->error)) { $file->remove(); files::catch_errors(implode('<br />', $file->error)); return false; } $dest_file = $file->destination_file; } else { $dest_file = $upload_dir . '/' . $request->variable('local_upload', ''); } if ($action != 'upload_local') { // Make security checks if checksum is provided. $checksum = $request->variable('ext_checksum', ''); if (!empty($checksum)) { $generated_hash = ''; $checksum_type = $request->variable('ext_checksum_type', 'md5'); switch ($checksum_type) { case 'sha1': $generated_hash = sha1_file($dest_file); break; case 'md5': $generated_hash = md5_file($dest_file); break; } if (strtolower($checksum) !== strtolower($generated_hash)) { $file->remove(); files::catch_errors($user->lang('ERROR_CHECKSUM_MISMATCH', $checksum_type)); return false; } } $template->assign_var('S_EXTENSION_CHECKSUM_NOT_PROVIDED', empty($checksum)); } return $dest_file; }
protected function temporary_filepath($file_name) { // Must preserve the extension for plupload to work. return sprintf('%s/%s_%s%s', $this->temporary_directory, $this->config['plupload_salt'], md5($file_name), \filespec::get_extension($file_name)); }
/** * @dataProvider get_extension_variables */ public function test_get_extension($filename, $expected) { $this->assertEquals($expected, filespec::get_extension($filename)); }
/** * Get Attachment Data */ function get_submitted_attachment_data($check_user_id = false) { global $user, $db, $phpbb_root_path, $phpEx, $config; $this->filename_data['filecomment'] = request_var('filecomment', '', true); $this->attachment_data = isset($_POST['attachment_data']) ? $_POST['attachment_data'] : array(); $check_user_id = $check_user_id === false ? $user->data['user_id'] : $check_user_id; // Regenerate data array... $attach_ids = $filenames = array(); foreach ($this->attachment_data as $pos => $var_ary) { if ($var_ary['attach_id']) { $attach_ids[(int) $this->attachment_data[$pos]['attach_id']] = $pos; } else { $filenames[$pos] = ''; set_var($filenames[$pos], $this->attachment_data[$pos]['physical_filename'], 'string'); $filenames[$pos] = basename($filenames[$pos]); } } $this->attachment_data = array(); // Regenerate already posted attachments... if (sizeof($attach_ids)) { // Get the data from the attachments $sql = 'SELECT attach_id, physical_filename, real_filename, extension, mimetype, filesize, filetime, thumbnail FROM ' . ATTACHMENTS_TABLE . ' WHERE attach_id IN (' . implode(', ', array_keys($attach_ids)) . ') AND poster_id = ' . $check_user_id; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { if (isset($attach_ids[$row['attach_id']])) { $pos = $attach_ids[$row['attach_id']]; $this->attachment_data[$pos] = $row; set_var($this->attachment_data[$pos]['comment'], $_POST['attachment_data'][$pos]['comment'], 'string', true); unset($attach_ids[$row['attach_id']]); } } $db->sql_freeresult($result); if (sizeof($attach_ids)) { trigger_error($user->lang['NO_ACCESS_ATTACHMENT'], E_USER_ERROR); } } // Regenerate newly uploaded attachments if (sizeof($filenames)) { include_once $phpbb_root_path . 'includes/functions_upload.' . $phpEx; $sql = 'SELECT attach_id FROM ' . ATTACHMENTS_TABLE . "\n\t\t\t\tWHERE LOWER(physical_filename) IN ('" . implode("', '", array_map('strtolower', $filenames)) . "')"; $result = $db->sql_query_limit($sql, 1); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row) { trigger_error($user->lang['NO_ACCESS_ATTACHMENT'], E_USER_ERROR); } foreach ($filenames as $pos => $physical_filename) { $this->attachment_data[$pos] = array('physical_filename' => $physical_filename, 'extension' => strtolower(filespec::get_extension($phpbb_root_path . $config['upload_path'] . '/' . $physical_filename)), 'filesize' => filespec::get_filesize($phpbb_root_path . $config['upload_path'] . '/' . $physical_filename), 'attach_id' => 0, 'thumbnail' => file_exists($phpbb_root_path . $config['upload_path'] . '/thumb_' . $physical_filename) ? 1 : 0); set_var($this->attachment_data[$pos]['comment'], $_POST['attachment_data'][$pos]['comment'], 'string', true); set_var($this->attachment_data[$pos]['real_filename'], $_POST['attachment_data'][$pos]['real_filename'], 'string', true); set_var($this->attachment_data[$pos]['filetime'], $_POST['attachment_data'][$pos]['filetime'], 'int'); if (strpos($_POST['attachment_data'][$pos]['mimetype'], 'image/') !== false) { set_var($this->attachment_data[$pos]['mimetype'], $_POST['attachment_data'][$pos]['mimetype'], 'string'); } else { $this->attachment_data[$pos]['mimetype'] = filespec::get_mimetype($phpbb_root_path . $config['upload_path'] . '/' . $physical_filename); } } } }
/** * Form upload method * Upload file from users harddisk * * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified) * @return object $file Object "filespec" is returned, all further operations can be done with this object * @access public */ function form_upload($form_name) { global $user; unset($_FILES[$form_name]['local_mode']); $file = new filespec($_FILES[$form_name], $this); if ($file->init_error) { $file->error[] = ''; return $file; } // Error array filled? if (isset($_FILES[$form_name]['error'])) { $error = $this->assign_internal_error($_FILES[$form_name]['error']); if ($error !== false) { $file->error[] = $error; return $file; } } // Check if empty file got uploaded (not catched by is_uploaded_file) if (isset($_FILES[$form_name]['size']) && $_FILES[$form_name]['size'] == 0) { $file->error[] = $user->lang[$this->error_prefix . 'EMPTY_FILEUPLOAD']; return $file; } // PHP Upload filesize exceeded if ($file->get('filename') == 'none') { $file->error[] = (@ini_get('upload_max_filesize') == '') ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], @ini_get('upload_max_filesize')); return $file; } // Not correctly uploaded if (!$file->is_uploaded()) { $file->error[] = $user->lang[$this->error_prefix . 'NOT_UPLOADED']; return $file; } $this->common_checks($file); return $file; }
/** * Check than remote banner exists * called by banner_process() * * @param string $banner The banner's remote url * @param array $error The array error, passed by reference * @return false|string String if no errors, else false */ private function _banner_remote($banner, &$error) { if (!preg_match('#^(http|https|ftp)://#i', $banner)) { $banner = 'http://' . $banner; } if (!preg_match('#^(http|https|ftp)://(?:(.*?\\.)*?[a-z0-9\\-]+?\\.[a-z]{2,4}|(?:\\d{1,3}\\.){3,5}\\d{1,3}):?([0-9]*?).*?\\.(gif|jpg|jpeg|png)$#i', $banner)) { $error[] = $this->user->lang['DIR_BANNER_URL_INVALID']; return false; } // Make sure getimagesize works... if (($image_data = @getimagesize($banner)) === false) { $error[] = $this->user->lang['DIR_BANNER_UNABLE_GET_IMAGE_SIZE']; return false; } if (!empty($image_data) && ($image_data[0] < 2 || $image_data[1] < 2)) { $error[] = $this->user->lang['DIR_BANNER_UNABLE_GET_IMAGE_SIZE']; return false; } $width = $image_data[0]; $height = $image_data[1]; // Check image type if (!class_exists('fileupload')) { include $this->root_path . 'includes/functions_upload.' . $this->php_ext; } $types = \fileupload::image_types(); $extension = strtolower(\filespec::get_extension($banner)); // Check if this is actually an image if ($file_stream = @fopen($banner, 'r')) { // Timeout after 1 second stream_set_timeout($file_stream, 1); // read some data to ensure headers are present fread($file_stream, 1024); $meta = stream_get_meta_data($file_stream); if (isset($meta['wrapper_data']['headers']) && is_array($meta['wrapper_data']['headers'])) { $headers = $meta['wrapper_data']['headers']; } else { if (isset($meta['wrapper_data']) && is_array($meta['wrapper_data'])) { $headers = $meta['wrapper_data']; } else { $headers = array(); } } foreach ($headers as $header) { $header = preg_split('/ /', $header, 2); if (strtr(strtolower(trim($header[0], ':')), '_', '-') === 'content-type') { if (strpos($header[1], 'image/') !== 0) { $error[] = 'DIR_BANNER_URL_INVALID'; fclose($file_stream); return false; } else { fclose($file_stream); break; } } } } else { $error[] = 'DIR_BANNER_URL_INVALID'; return false; } if (!empty($image_data) && (!isset($types[$image_data[2]]) || !in_array($extension, $types[$image_data[2]]))) { if (!isset($types[$image_data[2]])) { $error[] = $this->user->lang['UNABLE_GET_IMAGE_SIZE']; } else { $error[] = $this->user->lang('DIR_BANNER_IMAGE_FILETYPE_MISMATCH', $types[$image_data[2]][0], $extension); } return false; } if (($this->config['dir_banner_width'] || $this->config['dir_banner_height']) && ($width > $this->config['dir_banner_width'] || $height > $this->config['dir_banner_height'])) { $error[] = $this->user->lang('DIR_BANNER_WRONG_SIZE', $this->config['dir_banner_width'], $this->config['dir_banner_height'], $width, $height); return false; } return $banner; }