Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
151 / 151
100.00% covered (success)
100.00%
12 / 12
CRAP
100.00% covered (success)
100.00%
1 / 1
phpbb_fileupload_test
100.00% covered (success)
100.00%
151 / 151
100.00% covered (success)
100.00%
12 / 12
13
100.00% covered (success)
100.00%
1 / 1
 setUp
100.00% covered (success)
100.00%
45 / 45
100.00% covered (success)
100.00%
1 / 1
2
 gen_valid_filespec
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 tearDown
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 test_common_checks_invalid_extension
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 test_common_checks_disallowed_content
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
1
 test_common_checks_invalid_filename
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 test_common_checks_too_large
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 test_common_checks_valid_file
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 test_local_upload
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
1
 test_move_existent_file
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
1
 test_move_existent_file_overwrite
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
1
 test_valid_dimensions
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3*
4* This file is part of the phpBB Forum Software package.
5*
6* @copyright (c) phpBB Limited <https://www.phpbb.com>
7* @license GNU General Public License, version 2 (GPL-2.0)
8*
9* For full copyright and license information, please see
10* the docs/CREDITS.txt file.
11*
12*/
13
14require_once __DIR__ . '/../mock/filespec.php';
15
16class phpbb_fileupload_test extends phpbb_test_case
17{
18    private $path;
19
20    /** @var \phpbb\filesystem\filesystem */
21    private $filesystem;
22
23    /** @var \Symfony\Component\DependencyInjection\ContainerInterface */
24    protected $container;
25
26    /** @var \phpbb\files\factory */
27    protected $factory;
28
29    /** @var \bantu\IniGetWrapper\IniGetWrapper */
30    protected $php_ini;
31
32    /** @var \phpbb\language\language */
33    protected $language;
34
35    /** @var \phpbb\request\request_interface */
36    protected $request;
37
38    /** @var string phpBB root path */
39    protected $phpbb_root_path;
40
41    protected $mimetype_guesser;
42
43    protected function setUp(): void
44    {
45        // Global $config required by unique_id
46        global $config, $phpbb_root_path, $phpEx;
47
48        if (!is_array($config))
49        {
50            $config = new \phpbb\config\config(array());
51        }
52
53        $config['rand_seed'] = '';
54        $config['rand_seed_last_update'] = time() + 600;
55
56        $this->request = $this->createMock('\phpbb\request\request');
57        $this->php_ini = new \bantu\IniGetWrapper\IniGetWrapper;
58
59        $this->filesystem = new \phpbb\filesystem\filesystem();
60        $this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx));
61        $guessers = array(
62            new \Symfony\Component\Mime\FileinfoMimeTypeGuesser(),
63            new \Symfony\Component\Mime\FileBinaryMimeTypeGuesser(),
64            new \phpbb\mimetype\content_guesser(),
65            new \phpbb\mimetype\extension_guesser(),
66        );
67        $guessers[2]->set_priority(-2);
68        $guessers[3]->set_priority(-2);
69        $this->mimetype_guesser = new \phpbb\mimetype\guesser($guessers);
70
71        $this->container = new phpbb_mock_container_builder();
72        $this->container->set('files.filespec', new \phpbb\files\filespec(
73            $this->filesystem,
74            $this->language,
75            $this->php_ini,
76            new \FastImageSize\FastImageSize(),
77            $phpbb_root_path,
78            new \phpbb\mimetype\guesser(array(
79                'mimetype.extension_guesser' => new \phpbb\mimetype\extension_guesser(),
80            ))));
81        $this->factory = new \phpbb\files\factory($this->container);
82        $plupload = new \phpbb\plupload\plupload($phpbb_root_path, $config, $this->request, new \phpbb\user($this->language, '\phpbb\datetime'), $this->php_ini, $this->mimetype_guesser);
83        $this->container->set('files.types.form', new \phpbb\files\types\form(
84            $this->factory,
85            $this->language,
86            $this->php_ini,
87            $plupload,
88            $this->request
89        ));
90        $this->container->set('files.types.local', new \phpbb\files\types\local(
91            $this->factory,
92            $this->language,
93            $this->php_ini,
94            $this->request
95        ));
96
97        $this->path = __DIR__ . '/fixture/';
98        $this->phpbb_root_path = $phpbb_root_path;
99    }
100
101    private function gen_valid_filespec()
102    {
103        $filespec = new phpbb_mock_filespec();
104        $filespec->filesize = 1;
105        $filespec->extension = 'jpg';
106        $filespec->realname = 'valid';
107        $filespec->width = 2;
108        $filespec->height = 2;
109
110        return $filespec;
111    }
112
113    protected function tearDown(): void
114    {
115        // Clear globals
116        global $config, $user;
117        $config = array();
118        $user = null;
119    }
120
121    public function test_common_checks_invalid_extension()
122    {
123        $upload = new \phpbb\files\upload($this->factory, $this->language, $this->php_ini, $this->request);
124        $upload->set_allowed_extensions(array('png'))
125            ->set_max_filesize(100);
126        $file = $this->gen_valid_filespec();
127        $upload->common_checks($file);
128        $this->assertEquals('DISALLOWED_EXTENSION', $file->error[0]);
129    }
130
131    public function test_common_checks_disallowed_content()
132    {
133        $upload = new \phpbb\files\upload($this->factory, $this->language, $this->php_ini, $this->request);
134        $upload->set_allowed_extensions(array('jpg'))
135            ->set_max_filesize(1000);
136        $file = new \phpbb\files\filespec($this->filesystem, $this->language, $this->php_ini, new \FastImageSize\FastImageSize(), $this->phpbb_root_path);
137        $file->set_upload_ary(array(
138                'size'    => 50,
139                'tmp_name'    => __DIR__ . '/fixture/disallowed',
140                'name'        => 'disallowed.jpg',
141                'type'        => 'image/jpg'
142            ))
143            ->set_upload_namespace($upload);
144        file_put_contents(__DIR__ . '/fixture/disallowed', '<body>' . file_get_contents(__DIR__ . '/fixture/jpg'));
145        $upload->common_checks($file);
146        $this->assertEquals('DISALLOWED_CONTENT', $file->error[0]);
147        unlink(__DIR__ . '/fixture/disallowed');
148    }
149
150    public function test_common_checks_invalid_filename()
151    {
152        $upload = new \phpbb\files\upload($this->factory, $this->language, $this->php_ini, $this->request);
153        $upload->set_allowed_extensions(array('jpg'))
154            ->set_max_filesize(100);
155        $file = $this->gen_valid_filespec();
156        $file->realname = 'invalid?';
157        $upload->common_checks($file);
158        $this->assertEquals('INVALID_FILENAME', $file->error[0]);
159    }
160
161    public function test_common_checks_too_large()
162    {
163        $upload = new \phpbb\files\upload($this->factory, $this->language, $this->php_ini, $this->request);
164        $upload->set_allowed_extensions(array('jpg'))
165            ->set_max_filesize(100);
166        $file = $this->gen_valid_filespec();
167        $file->filesize = 1000;
168        $upload->common_checks($file);
169        $this->assertEquals('WRONG_FILESIZE', $file->error[0]);
170    }
171
172    public function test_common_checks_valid_file()
173    {
174        $upload = new \phpbb\files\upload($this->factory, $this->language, $this->php_ini, $this->request);
175        $upload->set_allowed_extensions(array('jpg'))
176            ->set_max_filesize(1000);
177        $file = $this->gen_valid_filespec();
178        $upload->common_checks($file);
179        $this->assertEquals(0, count($file->error));
180    }
181
182    public function test_local_upload()
183    {
184        $upload = new \phpbb\files\upload($this->factory, $this->language, $this->php_ini, $this->request);
185        $upload->set_allowed_extensions(array('jpg'))
186            ->set_max_filesize(1000);
187
188        copy($this->path . 'jpg', $this->path . 'jpg.jpg');
189        // Upload file data should be set to prevent "Undefined array key" PHP 8 warning
190        $filedata = [
191            'size'        => 519,
192            'realname'    => $this->path . 'jpg.jpg',
193            'type'        => false,
194        ];
195        $file = $upload->handle_upload('files.types.local', $this->path . 'jpg.jpg', $filedata);
196        $this->assertEquals(0, count($file->error));
197        $this->assertFalse($file->additional_checks());
198        $this->assertTrue($file->move_file('../tests/upload/fixture/copies', true));
199        $file->remove();
200    }
201
202    public function test_move_existent_file()
203    {
204        $upload = new \phpbb\files\upload($this->factory, $this->language, $this->php_ini, $this->request);
205        $upload->set_allowed_extensions(array('jpg'))
206            ->set_max_filesize(1000);
207
208        copy($this->path . 'jpg', $this->path . 'jpg.jpg');
209        // Upload file data should be set to prevent "Undefined array key" PHP 8 warning
210        $filedata = [
211            'size'        => 519,
212            'realname'    => $this->path . 'jpg.jpg',
213            'type'        => false,
214        ];
215        $file = $upload->handle_upload('files.types.local', $this->path . 'jpg.jpg', $filedata);
216        $this->assertEquals(0, count($file->error));
217        $this->assertFalse($file->move_file('../tests/upload/fixture'));
218        $this->assertFalse($file->get('file_moved'));
219        $this->assertEquals(1, count($file->error));
220    }
221
222    public function test_move_existent_file_overwrite()
223    {
224        $upload = new \phpbb\files\upload($this->factory, $this->language, $this->php_ini, $this->request);
225        $upload->set_allowed_extensions(array('jpg'))
226            ->set_max_filesize(1000);
227
228        copy($this->path . 'jpg', $this->path . 'jpg.jpg');
229        copy($this->path . 'jpg', $this->path . 'copies/jpg.jpg');
230        // Upload file data should be set to prevent "Undefined array key" PHP 8 warning
231        $filedata = [
232            'size'        => 519,
233            'realname'    => $this->path . 'jpg.jpg',
234            'type'        => false,
235        ];
236        $file = $upload->handle_upload('files.types.local', $this->path . 'jpg.jpg', $filedata);
237        $this->assertEquals(0, count($file->error));
238        $file->move_file('../tests/upload/fixture/copies', true);
239        $this->assertEquals(0, count($file->error));
240        unlink($this->path . 'copies/jpg.jpg');
241    }
242
243    public function test_valid_dimensions()
244    {
245        $upload = new \phpbb\files\upload($this->factory, $this->language, $this->php_ini, $this->request);
246        $upload->set_allowed_extensions(false)
247            ->set_max_filesize(false)
248            ->set_allowed_dimensions(1, 1, 100, 100);
249
250        $file1 = $this->gen_valid_filespec();
251        $file2 = $this->gen_valid_filespec();
252        $file2->height = 101;
253        $file3 = $this->gen_valid_filespec();
254        $file3->width = 0;
255
256        $this->assertTrue($upload->valid_dimensions($file1));
257        $this->assertFalse($upload->valid_dimensions($file2));
258        $this->assertFalse($upload->valid_dimensions($file3));
259    }
260}