From 85ace455da66c0dd806d08943c70a4154b5be1df Mon Sep 17 00:00:00 2001 From: thisgun Date: Thu, 5 Jan 2017 17:52:45 +0900 Subject: [PATCH] =?UTF-8?q?=EC=8A=A4=EB=A7=88=ED=8A=B8=EC=97=90=EB=94=94?= =?UTF-8?q?=ED=84=B0=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EB=B0=A9=EC=8B=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/smarteditor_upload_extend.php | 11 ++ plugin/editor/smarteditor2/editor.lib.php | 103 ++++++++----- .../popup/php/UploadHandler.php | 145 ++++++++++++++---- 3 files changed, 196 insertions(+), 63 deletions(-) create mode 100644 extend/smarteditor_upload_extend.php diff --git a/extend/smarteditor_upload_extend.php b/extend/smarteditor_upload_extend.php new file mode 100644 index 000000000..80a3203e9 --- /dev/null +++ b/extend/smarteditor_upload_extend.php @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/plugin/editor/smarteditor2/editor.lib.php b/plugin/editor/smarteditor2/editor.lib.php index 80c0076be..75c3248fd 100644 --- a/plugin/editor/smarteditor2/editor.lib.php +++ b/plugin/editor/smarteditor2/editor.lib.php @@ -3,9 +3,15 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 function editor_html($id, $content, $is_dhtml_editor=true) { - global $g5, $config; + global $g5, $config, $w, $board; static $js = true; + if( $is_dhtml_editor && $content && !$w && (isset($board['bo_insert_content']) && !empty($board['bo_insert_content']) ) ){ //글쓰기 기본 내용 처리 + if( preg_match('/\r|\n/', $content) && $content === strip_tags($content, '') ) { //textarea로 작성되고, html 내용이 없다면 + $content = nl2br($content); + } + } + $editor_url = G5_EDITOR_URL.'/'.$config['cf_editor']; $html = ""; @@ -66,36 +72,17 @@ function chk_editor_js($id, $is_dhtml_editor=true) } /* - * Name: FT-NONCE-LIB - * Created By: Full Throttle Development, LLC (http://fullthrottledevelopment.com) - * Created On: July 2009 - * Last Modified On: August 12, 2009 - * Last Modified By: Glenn Ansley (glenn@fullthrottledevelopment.com) - * Version: 0.2 - */ - -/* -Copyright 2009 Full Throttle Development, LLC - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . +https://github.com/timostamm/NonceUtil-PHP */ if (!defined('FT_NONCE_UNIQUE_KEY')) - define( 'FT_NONCE_UNIQUE_KEY' , sha1(G5_MYSQL_USER) ); + define( 'FT_NONCE_UNIQUE_KEY' , sha1($_SERVER['SERVER_SOFTWARE'].G5_MYSQL_USER.session_id().G5_TABLE_PREFIX) ); + +if (!defined('FT_NONCE_SESSION_KEY')) + define( 'FT_NONCE_SESSION_KEY' , substr(md5(FT_NONCE_UNIQUE_KEY), 5) ); if (!defined('FT_NONCE_DURATION')) - define( 'FT_NONCE_DURATION' , 2160000 ); // 300 makes link or form good for 5 minutes from time of generation, 300은 5분간 유효, 2160000은 10시간동안 유효 + define( 'FT_NONCE_DURATION' , 60 * 60 ); // 300 makes link or form good for 5 minutes from time of generation, 300은 5분간 유효, 60 * 60 은 1시간 if (!defined('FT_NONCE_KEY')) define( 'FT_NONCE_KEY' , '_nonce' ); @@ -107,29 +94,73 @@ if(!function_exists('ft_nonce_create_query_string')){ } } +if(!function_exists('ft_get_secret_key')){ + function ft_get_secret_key($secret){ + return md5(FT_NONCE_UNIQUE_KEY.$secret); + } +} + // This method creates an nonce. It should be called by one of the previous two functions. if(!function_exists('ft_nonce_create')){ - function ft_nonce_create( $action = '' , $user='' ){ - return substr( ft_nonce_generate_hash( $action . $user ), -12, 10); + function ft_nonce_create( $action = '',$user='', $timeoutSeconds=FT_NONCE_DURATION ){ + + $secret = ft_get_secret_key($action.$user); + + set_session('token_'.FT_NONCE_SESSION_KEY, $secret); + + $salt = ft_nonce_generate_hash(); + $time = time(); + $maxTime = $time + $timeoutSeconds; + $nonce = $salt . "|" . $maxTime . "|" . sha1( $salt . $secret . $maxTime ); + return $nonce; + } } // This method validates an nonce if(!function_exists('ft_nonce_is_valid')){ - function ft_nonce_is_valid( $nonce , $action = '' , $user='' ){ - // Nonce generated 0-12 hours ago - if ( substr(ft_nonce_generate_hash( $action . $user ), -12, 10) == $nonce ){ - return true; + function ft_nonce_is_valid( $nonce, $action = '', $user='' ){ + + $secret = ft_get_secret_key($action.$user); + + $token = get_session('token_'.FT_NONCE_SESSION_KEY); + + if ($secret != $token){ + return false; } - return false; + + if (is_string($nonce) == false) { + return false; + } + $a = explode('|', $nonce); + if (count($a) != 3) { + return false; + } + $salt = $a[0]; + $maxTime = intval($a[1]); + $hash = $a[2]; + $back = sha1( $salt . $secret . $maxTime ); + if ($back != $hash) { + return false; + } + if (time() > $maxTime) { + return false; + } + return true; } } // This method generates the nonce timestamp if(!function_exists('ft_nonce_generate_hash')){ - function ft_nonce_generate_hash( $action='' , $user='' ){ - $i = ceil( time() / ( FT_NONCE_DURATION / 2 ) ); - return md5( $i . $action . $user . $action ); + function ft_nonce_generate_hash(){ + $length = 10; + $chars='1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'; + $ll = strlen($chars)-1; + $o = ''; + while (strlen($o) < $length) { + $o .= $chars[ rand(0, $ll) ]; + } + return $o; } } ?> \ No newline at end of file diff --git a/plugin/editor/smarteditor2/photo_uploader/popup/php/UploadHandler.php b/plugin/editor/smarteditor2/photo_uploader/popup/php/UploadHandler.php index 33ff9a8b3..6ae20946f 100644 --- a/plugin/editor/smarteditor2/photo_uploader/popup/php/UploadHandler.php +++ b/plugin/editor/smarteditor2/photo_uploader/popup/php/UploadHandler.php @@ -8,39 +8,54 @@ * * Licensed under the MIT license: * http://www.opensource.org/licenses/MIT + * https://github.com/blueimp/jQuery-File-Upload/wiki/Security + * https://github.com/blueimp/jQuery-File-Upload/pull/148 */ - class UploadHandler { + public $files = array(); protected $options; - - // PHP File Upload error message codes: - // http://php.net/manual/en/features.file-upload.errors.php - protected $error_messages = array( - 1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini', - 2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form', - 3 => 'The uploaded file was only partially uploaded', - 4 => 'No file was uploaded', - 6 => 'Missing a temporary folder', - 7 => 'Failed to write file to disk', - 8 => 'A PHP extension stopped the file upload', - 'post_max_size' => 'The uploaded file exceeds the post_max_size directive in php.ini', - 'max_file_size' => 'File is too big', - 'min_file_size' => 'File is too small', - 'accept_file_types' => 'Filetype not allowed', - 'max_number_of_files' => 'Maximum number of files exceeded', - 'max_width' => 'Image exceeds maximum width', - 'min_width' => 'Image requires a minimum width', - 'max_height' => 'Image exceeds maximum height', - 'min_height' => 'Image requires a minimum height', - 'abort' => 'File upload aborted', - 'image_resize' => 'Failed to resize image' - ); + protected $post_max_size; + protected $error_messages; protected $image_objects = array(); - function __construct($options = null, $initialize = true, $error_messages = null) { + private static $MIME_TYPES_PROCESSORS = array( + "image/gif" => array("imagecreatefromgif", "imagegif"), + "image/jpg" => array("imagecreatefromjpeg", "imagejpeg"), + "image/jpeg" => array("imagecreatefromjpeg", "imagejpeg"), + "image/png" => array("imagecreatefrompng", "imagepng"), + "image/bmp" => array("imagecreatefromwbmp", "imagewbmp") + ); + + public function __construct($options = null, $initialize = true, $error_messages = null) { + + $this->post_max_size = (defined('SMARTEDITOR_UPLOAD_SIZE_LIMIT') && SMARTEDITOR_UPLOAD_SIZE_LIMIT) ? SMARTEDITOR_UPLOAD_SIZE_LIMIT.'M' : ini_get('post_max_size'); + + // PHP File Upload error message codes: + // http://php.net/manual/en/features.file-upload.errors.php + $this->error_messages = array( + 1 => 'The uploaded file exceeds the upload_max_filesize', + 2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form', + 3 => 'The uploaded file was only partially uploaded', + 4 => 'No file was uploaded', + 6 => 'Missing a temporary folder', + 7 => 'Failed to write file to disk', + 8 => 'A PHP extension stopped the file upload', + 'post_max_size' => 'The uploaded file exceeds the post_max_size', + 'max_file_size' => 'File is too big', + 'min_file_size' => 'File is too small', + 'accept_file_types' => 'Filetype not allowed', + 'max_number_of_files' => 'Maximum number of files exceeded', + 'max_width' => 'Image exceeds maximum width', + 'min_width' => 'Image requires a minimum width', + 'max_height' => 'Image exceeds maximum height', + 'min_height' => 'Image requires a minimum height', + 'abort' => 'File upload aborted', + 'image_resize' => 'Failed to resize image' + ); + $this->options = array( 'script_url' => $this->get_full_url().'/', 'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/files/', @@ -90,6 +105,10 @@ class UploadHandler 'max_number_of_files' => null, // Defines which files are handled as image files: 'image_file_types' => '/\.(gif|jpe?g|bmp|png)$/i', + 'is_resize' => (defined('SMARTEDITOR_UPLOAD_RESIZE') && SMARTEDITOR_UPLOAD_RESIZE) ? true : false, + 'resize_max_width' => (defined('SMARTEDITOR_UPLOAD_MAX_WIDTH') && SMARTEDITOR_UPLOAD_MAX_WIDTH) ? SMARTEDITOR_UPLOAD_MAX_WIDTH : 800, + 'resize_max_height' => (defined('SMARTEDITOR_UPLOAD_MAX_HEIGHT') && SMARTEDITOR_UPLOAD_MAX_HEIGHT) ? SMARTEDITOR_UPLOAD_MAX_HEIGHT : 800, + 'resize_jpeg_compress' => (defined('SMARTEDITOR_UPLOAD_IMAGE_QUALITY') && SMARTEDITOR_UPLOAD_IMAGE_QUALITY) ? SMARTEDITOR_UPLOAD_IMAGE_QUALITY : 800, // Image resolution restrictions: 'max_width' => null, 'max_height' => null, @@ -362,7 +381,8 @@ class UploadHandler $content_length = $this->fix_integer_overflow(intval( $this->get_server_var('CONTENT_LENGTH') )); - $post_max_size = $this->get_config_bytes(ini_get('post_max_size')); + $post_max_size = $this->get_config_bytes($this->post_max_size); + if ($post_max_size && ($content_length > $post_max_size)) { $file->error = $this->get_error_message('post_max_size'); return false; @@ -1038,6 +1058,48 @@ class UploadHandler return $tmp_name; } + protected function reprocessImage($file_path, $callback) + { + // Extracting mime type using getimagesize + try { + $image_info = getimagesize($file_path); + if ($image_info === null) { + //throw new Exception("Invalid image type"); + return false; + } + + $mime_type = $image_info["mime"]; + + if (!array_key_exists($mime_type, self::$MIME_TYPES_PROCESSORS)) { + //throw new Exception("Invalid image MIME type"); + return false; + } + + $image_from_file = self::$MIME_TYPES_PROCESSORS[$mime_type][0]; + $image_to_file = self::$MIME_TYPES_PROCESSORS[$mime_type][1]; + + $reprocessed_image = @$image_from_file($file_path); + + if (!$reprocessed_image) { + //throw new Exception("Unable to create reprocessed image from file"); + return false; + } + + // Calling callback(if set) with path of image as a parameter + if ($callback !== null) { + $callback($reprocessed_image); + } + + // Freeing up memory + imagedestroy($reprocessed_image); + } catch (Exception $e) { + unlink($file_path); + return false; + } + + return true; + } + protected function handle_file_upload($uploaded_file, $name, $size, $type, $error, $index = null, $content_range = null) { $file = new \stdClass(); @@ -1050,6 +1112,12 @@ class UploadHandler //$file->name = iconv('UTF-8', 'UTF-8//IGNORE', utf8_encode($file->name)); $file->size = $this->fix_integer_overflow(intval($size)); $file->type = $type; + + if ( SMARTEDITOR_UPLOAD_IMG_CHECK && ! $this->reprocessImage($uploaded_file, null) ){ + $file->error = $this->get_error_message('accept_file_types'); + return $file; + } + if ($this->validate($uploaded_file, $file, $error, $index)) { $this->handle_form_data($file, $index); $upload_dir = $this->get_upload_path(); @@ -1079,10 +1147,32 @@ class UploadHandler ); } $file_size = $this->get_file_size($file_path, $append_file); + + try { + if(defined('G5_FILE_PERMISSION')) chmod($file_path, G5_FILE_PERMISSION); + } catch (Exception $e) { + } + if ($file_size === $file->size) { $file->url = $this->get_download_url($file->name); if ($this->is_valid_image_file($file_path)) { $this->handle_image_file($file_path, $file); + + $this->files[] = $file->name; + + if( $this->options['is_resize'] ){ + $resize_options = array( + 'max_width'=>$this->options['resize_max_width'], + 'max_height'=>$this->options['resize_max_height'], + 'jpeg_quality'=>$this->options['resize_jpeg_compress'], + 'auto_orient' => true, + ); + + if ($this->create_scaled_image($file->name, '', $resize_options)) { + $file->size = $this->get_file_size($file_path, true); + } + } + $image_width_height = $this->get_image_size($file_path); $file->width = $image_width_height[0]; $file->height = $image_width_height[1]; @@ -1099,6 +1189,7 @@ class UploadHandler } $this->set_additional_file_properties($file); } + return $file; } @@ -1365,4 +1456,4 @@ class UploadHandler return $this->generate_response($response, $print_response); } -} +} \ No newline at end of file