aboutsummaryrefslogtreecommitdiffstats
path: root/tests/upload/filespec_test.php
diff options
context:
space:
mode:
authorMaat <maat-pub@mageia.biz>2020-05-08 18:29:30 +0200
committerMaat <maat-pub@mageia.biz>2020-05-08 21:36:04 +0200
commit36bc1870f21fac04736a1049c1d5b8e127d729f4 (patch)
tree9d102331eeaf1ef3cd23e656320d7c08e65757ed /tests/upload/filespec_test.php
parent8875d385d0579b451dac4d9bda465172b4f69ee0 (diff)
parent149375253685b3a38996f63015a74b7a0f53aa14 (diff)
downloadforums-36bc1870f21fac04736a1049c1d5b8e127d729f4.tar
forums-36bc1870f21fac04736a1049c1d5b8e127d729f4.tar.gz
forums-36bc1870f21fac04736a1049c1d5b8e127d729f4.tar.bz2
forums-36bc1870f21fac04736a1049c1d5b8e127d729f4.tar.xz
forums-36bc1870f21fac04736a1049c1d5b8e127d729f4.zip
Merge remote-tracking branch 'upstream/prep-release-3.1.11'
Diffstat (limited to 'tests/upload/filespec_test.php')
-rw-r--r--tests/upload/filespec_test.php338
1 files changed, 338 insertions, 0 deletions
diff --git a/tests/upload/filespec_test.php b/tests/upload/filespec_test.php
new file mode 100644
index 0000000000..ed28bcb38f
--- /dev/null
+++ b/tests/upload/filespec_test.php
@@ -0,0 +1,338 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+require_once __DIR__ . '/../../phpBB/includes/functions.php';
+require_once __DIR__ . '/../../phpBB/includes/utf/utf_tools.php';
+require_once __DIR__ . '/../../phpBB/includes/functions_upload.php';
+
+class phpbb_filespec_test extends phpbb_test_case
+{
+ const TEST_COUNT = 100;
+ const PREFIX = 'phpbb_';
+ const MAX_STR_LEN = 50;
+ const UPLOAD_MAX_FILESIZE = 1000;
+
+ private $config;
+ public $path;
+
+ protected function setUp()
+ {
+ // Global $config required by unique_id
+ // Global $user required by filespec::additional_checks and
+ // filespec::move_file
+ global $config, $user;
+
+ if (!is_array($config))
+ {
+ $config = array();
+ }
+
+ $config['rand_seed'] = '';
+ $config['rand_seed_last_update'] = time() + 600;
+ // This config value is normally pulled from the database which is set
+ // to this value at install time.
+ // See: phpBB/install/schemas/schema_data.sql
+ $config['mime_triggers'] = 'body|head|html|img|plaintext|a href|pre|script|table|title';
+
+ $user = new phpbb_mock_user();
+ $user->lang = new phpbb_mock_lang();
+
+ $this->config = &$config;
+ $this->path = __DIR__ . '/fixture/';
+
+ // Create copies of the files for use in testing move_file
+ $iterator = new DirectoryIterator($this->path);
+ foreach ($iterator as $fileinfo)
+ {
+ if ($fileinfo->isDot() || $fileinfo->isDir())
+ {
+ continue;
+ }
+
+ copy($fileinfo->getPathname(), $this->path . 'copies/' . $fileinfo->getFilename() . '_copy');
+ if ($fileinfo->getFilename() === 'txt')
+ {
+ copy($fileinfo->getPathname(), $this->path . 'copies/' . $fileinfo->getFilename() . '_copy_2');
+ }
+ }
+
+ $guessers = array(
+ new \Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser(),
+ new \Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser(),
+ new \phpbb\mimetype\content_guesser(),
+ new \phpbb\mimetype\extension_guesser(),
+ );
+ $guessers[2]->set_priority(-2);
+ $guessers[3]->set_priority(-2);
+ $this->mimetype_guesser = new \phpbb\mimetype\guesser($guessers);
+ }
+
+ private function get_filespec($override = array())
+ {
+ // Initialise a blank filespec object for use with trivial methods
+ $upload_ary = array(
+ 'name' => '',
+ 'type' => '',
+ 'size' => '',
+ 'tmp_name' => '',
+ 'error' => '',
+ );
+
+ return new filespec(array_merge($upload_ary, $override), null, $this->mimetype_guesser);
+ }
+
+ protected function tearDown()
+ {
+ global $user;
+ $this->config = array();
+ $user = null;
+
+ $iterator = new DirectoryIterator($this->path . 'copies');
+ foreach ($iterator as $fileinfo)
+ {
+ $name = $fileinfo->getFilename();
+ if ($name[0] !== '.')
+ {
+ unlink($fileinfo->getPathname());
+ }
+ }
+ }
+
+ public function additional_checks_variables()
+ {
+ // False here just indicates the file is too large and fails the
+ // filespec::additional_checks method because of it. All other code
+ // paths in that method are covered elsewhere.
+ return array(
+ array('gif', true),
+ array('jpg', false),
+ array('png', true),
+ array('tif', false),
+ array('txt', false),
+ );
+ }
+
+ /**
+ * @dataProvider additional_checks_variables
+ */
+ public function test_additional_checks($filename, $expected)
+ {
+ $upload = new phpbb_mock_fileupload();
+ $filespec = $this->get_filespec();
+ $filespec->upload = $upload;
+ $filespec->file_moved = true;
+ $filespec->filesize = $filespec->get_filesize($this->path . $filename);
+
+ $this->assertEquals($expected, $filespec->additional_checks());
+ }
+
+ public function check_content_variables()
+ {
+ // False here indicates that a file is non-binary and contains
+ // disallowed content that makes IE report the mimetype incorrectly.
+ return array(
+ array('gif', true),
+ array('jpg', true),
+ array('png', true),
+ array('tif', true),
+ array('txt', false),
+ );
+ }
+
+ /**
+ * @dataProvider check_content_variables
+ */
+ public function test_check_content($filename, $expected)
+ {
+ $disallowed_content = explode('|', $this->config['mime_triggers']);
+ $filespec = $this->get_filespec(array('tmp_name' => $this->path . $filename));
+ $this->assertEquals($expected, $filespec->check_content($disallowed_content));
+ // All files should pass if $disallowed_content is empty
+ $this->assertEquals(true, $filespec->check_content(array()));
+ }
+
+ public function clean_filename_variables()
+ {
+ $chunks = str_split('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\'\\" /:*?<>|[];(){},#+=-_`', 8);
+ return array(
+ array($chunks[0] . $chunks[7]),
+ array($chunks[1] . $chunks[8]),
+ array($chunks[2] . $chunks[9]),
+ array($chunks[3] . $chunks[4]),
+ array($chunks[5] . $chunks[6]),
+ );
+ }
+
+ /**
+ * @dataProvider clean_filename_variables
+ */
+ public function test_clean_filename_real($filename)
+ {
+ $bad_chars = array("'", "\\", ' ', '/', ':', '*', '?', '"', '<', '>', '|');
+ $filespec = $this->get_filespec(array('name' => $filename));
+ $filespec->clean_filename('real', self::PREFIX);
+ $name = $filespec->realname;
+
+ $this->assertEquals(0, preg_match('/%(\w{2})/', $name));
+ foreach ($bad_chars as $char)
+ {
+ $this->assertFalse(strpos($name, $char));
+ }
+ }
+
+ public function test_clean_filename_unique()
+ {
+ $filenames = array();
+ for ($tests = 0; $tests < self::TEST_COUNT; $tests++)
+ {
+ $filespec = $this->get_filespec();
+ $filespec->clean_filename('unique', self::PREFIX);
+ $name = $filespec->realname;
+
+ $this->assertEquals(strlen($name), 32 + strlen(self::PREFIX));
+ $this->assertRegExp('#^[A-Za-z0-9]+$#', substr($name, strlen(self::PREFIX)));
+ $this->assertFalse(isset($filenames[$name]));
+ $filenames[$name] = true;
+ }
+ }
+
+ public function get_extension_variables()
+ {
+ return array(
+ array('file.png', 'png'),
+ array('file.phpbb.gif', 'gif'),
+ array('file..', ''),
+ array('.file..jpg.webp', 'webp'),
+ array('/test.com/file', ''),
+ array('/test.com/file.gif', 'gif'),
+ );
+ }
+
+ /**
+ * @dataProvider get_extension_variables
+ */
+ public function test_get_extension($filename, $expected)
+ {
+ $this->assertEquals($expected, filespec::get_extension($filename));
+ }
+
+ public function is_image_variables()
+ {
+ return array(
+ array('gif', 'image/gif', true),
+ array('jpg', 'image/jpg', true),
+ array('png', 'image/png', true),
+ array('tif', 'image/tif', true),
+ array('txt', 'text/plain', false),
+ array('jpg', 'application/octet-stream', false),
+ array('gif', 'application/octetstream', false),
+ array('png', 'application/mime', false),
+ );
+ }
+
+ /**
+ * @dataProvider is_image_variables
+ */
+ public function test_is_image($filename, $mimetype, $expected)
+ {
+ $filespec = $this->get_filespec(array('tmp_name' => $this->path . $filename, 'type' => $mimetype));
+ $this->assertEquals($expected, $filespec->is_image());
+ }
+
+ public function is_image_get_mimetype()
+ {
+ return array(
+ array('gif', 'image/gif', true),
+ array('jpg', 'image/jpg', true),
+ array('png', 'image/png', true),
+ array('tif', 'image/tif', true),
+ array('txt', 'text/plain', false),
+ array('jpg', 'application/octet-stream', true),
+ array('gif', 'application/octetstream', true),
+ array('png', 'application/mime', true),
+ );
+ }
+
+ /**
+ * @dataProvider is_image_get_mimetype
+ */
+ public function test_is_image_get_mimetype($filename, $mimetype, $expected)
+ {
+ if (!class_exists('finfo') && strtolower(substr(PHP_OS, 0, 3)) === 'win')
+ {
+ $this->markTestSkipped('Unable to test mimetype guessing without fileinfo support on Windows');
+ }
+
+ $filespec = $this->get_filespec(array('tmp_name' => $this->path . $filename, 'type' => $mimetype));
+ $filespec->get_mimetype($this->path . $filename);
+ $this->assertEquals($expected, $filespec->is_image());
+ }
+
+ public function move_file_variables()
+ {
+ return array(
+ array('gif_copy', 'gif_moved', 'image/gif', 'gif', false, true),
+ array('non_existant', 'still_non_existant', 'text/plain', 'txt', 'GENERAL_UPLOAD_ERROR', false),
+ array('txt_copy', 'txt_as_img', 'image/jpg', 'txt', false, true),
+ array('txt_copy_2', 'txt_moved', 'text/plain', 'txt', false, true),
+ array('jpg_copy', 'jpg_moved', 'image/png', 'jpg', false, true),
+ array('png_copy', 'png_moved', 'image/png', 'jpg', 'IMAGE_FILETYPE_MISMATCH', true),
+ );
+ }
+
+ /**
+ * @dataProvider move_file_variables
+ */
+ public function test_move_file($tmp_name, $realname, $mime_type, $extension, $error, $expected)
+ {
+ // Global $phpbb_root_path and $phpEx are required by phpbb_chmod
+ global $phpbb_root_path, $phpEx;
+ $phpbb_root_path = '';
+ $phpEx = 'php';
+
+ $upload = new phpbb_mock_fileupload();
+ $upload->max_filesize = self::UPLOAD_MAX_FILESIZE;
+
+ $filespec = $this->get_filespec(array(
+ 'tmp_name' => $this->path . 'copies/' . $tmp_name,
+ 'name' => $realname,
+ 'type' => $mime_type,
+ ));
+ $filespec->extension = $extension;
+ $filespec->upload = $upload;
+ $filespec->local = true;
+
+ $this->assertEquals($expected, $filespec->move_file($this->path . 'copies'));
+ $this->assertEquals($filespec->file_moved, file_exists($this->path . 'copies/' . $realname));
+ if ($error)
+ {
+ $this->assertEquals($error, $filespec->error[0]);
+ }
+
+ $phpEx = '';
+ }
+
+ /**
+ * @dataProvider clean_filename_variables
+ */
+ public function test_uploadname($filename)
+ {
+ $type_cast_helper = new \phpbb\request\type_cast_helper();
+
+ $upload_name = '';
+ $type_cast_helper->set_var($upload_name, $filename, 'string', true, true);
+ $filespec = $this->get_filespec(array('name'=> $upload_name));
+
+ $this->assertSame(trim(utf8_basename(htmlspecialchars($filename))), $filespec->uploadname);
+ }
+}