diff options
| -rw-r--r-- | phpBB/phpbb/plupload/plupload.php | 37 | ||||
| -rw-r--r-- | tests/plupload/plupload_test.php | 73 | 
2 files changed, 99 insertions, 11 deletions
diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php index 9ad12b1082..5a5b8a1874 100644 --- a/phpBB/phpbb/plupload/plupload.php +++ b/phpBB/phpbb/plupload/plupload.php @@ -274,22 +274,37 @@ class plupload  	}  	/** -	* Checks various php.ini values and the maximum file size to determine -	* the maximum size chunks a file can be split up into for upload -	* -	* @return int -	*/ +	 * Checks various php.ini values to determine the maximum chunk +	 * size a file should be split into for upload. +	 * +	 * The intention is to calculate a value which reflects whatever +	 * the most restrictive limit is set to.  And to then set the chunk +	 * size to half that value, to ensure any required transfer overhead +	 * and POST data remains well within the limit.  Or, if all of the +	 * limits are set to unlimited, the chunk size will also be unlimited. +	 * +	 * @return int +	 * +	 * @access public +	 */  	public function get_chunk_size()  	{ -		$max = min( +		$max = 0; + +		$limits = [ +			$this->php_ini->getBytes('memory_limit'),  			$this->php_ini->getBytes('upload_max_filesize'),  			$this->php_ini->getBytes('post_max_size'), -			max(1, $this->php_ini->getBytes('memory_limit')), -			$this->config['max_filesize'] -		); +		]; + +		foreach ($limits as $limit_type) +		{ +			if ($limit_type > 0) +			{ +				$max = ($max !== 0) ? min($limit_type, $max) : $limit_type; +			} +		} -		// Use half of the maximum possible to leave plenty of room for other -		// POST data.  		return floor($max / 2);  	} diff --git a/tests/plupload/plupload_test.php b/tests/plupload/plupload_test.php index 46bebb8d35..eb4657afbc 100644 --- a/tests/plupload/plupload_test.php +++ b/tests/plupload/plupload_test.php @@ -54,4 +54,77 @@ class phpbb_plupload_test extends phpbb_test_case  		$this->assertEquals($expected, $plupload->generate_resize_string());  	} + +	public function data_get_chunk_size() +	{ +		return [ +			[[ +				'memory_limit' => -1, +				'upload_max_filesize' => 0, +				'post_max_size' => 0, +			], 0], +			[[ +				'memory_limit' => -1, +				'upload_max_filesize' => 500, +				'post_max_size' => 400, +			], 200], +			[[ +				'memory_limit' => 100, +				'upload_max_filesize' => 0, +				'post_max_size' => 300, +			], 50], +			[[ +				'memory_limit' => 300, +				'upload_max_filesize' => 200, +				'post_max_size' => 0, +			], 100], +			[[ +				'memory_limit' => 3000, +				'upload_max_filesize' => 800, +				'post_max_size' => 900, +			], 400], +			[[ +				'memory_limit' => 2000, +				'upload_max_filesize' => 1000, +				'post_max_size' => 600, +			], 300], +			[[ +				'memory_limit' => 1000, +				'upload_max_filesize' => 2000, +				'post_max_size' => 3000, +			], 500], +		]; +	} + +	/** +	 * @dataProvider data_get_chunk_size +	 */ +	public function test_get_chunk_size($limits_ary, $expected) +	{ +		global $phpbb_root_path, $phpEx; + +		$lang = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); +		$config = new \phpbb\config\config([]); + +		$ini_wrapper = $this->getMockBuilder('\bantu\IniGetWrapper\IniGetWrapper') +			->setMethods(['getBytes']) +			->getMock(); +		$ini_wrapper->method('getBytes') +			->will($this->returnValueMap([ +				['memory_limit', $limits_ary['memory_limit']], +				['upload_max_filesize', $limits_ary['upload_max_filesize']], +				['post_max_size', $limits_ary['post_max_size']] +			])); + +		$plupload = new \phpbb\plupload\plupload( +			'', +			$config, +			new phpbb_mock_request, +			new \phpbb\user($lang, '\phpbb\datetime'), +			$ini_wrapper, +			new \phpbb\mimetype\guesser(array(new \phpbb\mimetype\extension_guesser)) +		); + +		$this->assertEquals($expected, $plupload->get_chunk_size()); +	}  }  | 
