/** * Acts in place of the standard avatar processing function. */ function gravatar_process($data, $error) { global $config, $db, $user, $phpbb_root_path, $phpEx; // Make sure getimagesize works... if (($image_data = @getimagesize($data['gravatar'])) === 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(); if (!isset($types[$image_data[2]])) { $error[] = $user->lang['UNABLE_GET_IMAGE_SIZE']; } 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['gravatar'], $width, $height); }
/** * 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 to destination folder * The phpbb_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 phpbb_chmod()} * * @access public */ function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = false) { global $user, $phpbb_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 = $phpbb_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; } phpbb_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; }
/** * {@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); }
/** * 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; }