‪TYPO3CMS  ‪main
UploadedFileTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use PHPUnit\Framework\Attributes\DataProvider;
21 use PHPUnit\Framework\Attributes\Test;
25 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
26 
27 final class ‪UploadedFileTest extends UnitTestCase
28 {
29  protected ‪$tmpFile;
30 
31  protected function ‪setUp(): void
32  {
33  parent::setUp();
34  $this->tmpFile = null;
35  }
36 
37  protected function ‪tearDown(): void
38  {
39  if (is_string($this->tmpFile) && file_exists($this->tmpFile)) {
40  unlink($this->tmpFile);
41  }
42  parent::tearDown();
43  }
44 
45  public static function ‪invalidStreamsDataProvider(): array
46  {
47  return [
48  'int' => [1],
49  'float' => [1.1],
50  /* Have not figured out a valid way to test an invalid path yet; null byte injection
51  * appears to get caught by fopen()
52  'invalid-path' => [ ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) ? '[:]' : 'foo' . "\0" ],
53  */
54  'array' => [['filename']],
55  'object' => [(object)['filename']],
56  ];
57  }
58 
59  #[DataProvider('invalidStreamsDataProvider')]
60  #[Test]
61  public function ‪constructorRaisesExceptionOnInvalidStreamOrFile($streamOrFile): void
62  {
63  $this->expectException(\InvalidArgumentException::class);
64  new ‪UploadedFile($streamOrFile, 0, UPLOAD_ERR_OK);
65  }
66 
67  public static function ‪invalidErrorStatusesDataProvider(): array
68  {
69  return [
70  'negative' => [-1],
71  'too-big' => [9],
72  ];
73  }
74 
75  #[DataProvider('invalidErrorStatusesDataProvider')]
76  #[Test]
78  {
79  $this->expectException(\InvalidArgumentException::class);
80  $this->expectExceptionCode(1436717303);
81  new ‪UploadedFile(fopen('php://temp', 'wb+'), 0, $status);
82  }
83 
84  #[Test]
86  {
87  $stream = new ‪Stream('php://temp');
88  $upload = new ‪UploadedFile($stream, 0, UPLOAD_ERR_OK);
89  self::assertSame($stream, $upload->getStream());
90  }
91 
92  #[Test]
93  public function ‪getStreamReturnsWrappedPhpStream(): void
94  {
95  $stream = fopen('php://temp', 'wb+');
96  $upload = new ‪UploadedFile($stream, 0, UPLOAD_ERR_OK);
97  $uploadStream = $upload->getStream()->detach();
98  self::assertSame($stream, $uploadStream);
99  }
100 
101  #[Test]
102  public function ‪getStreamReturnsStreamForFile(): void
103  {
104  $this->tmpFile = $stream = tempnam(sys_get_temp_dir(), 'phly');
105  $upload = new ‪UploadedFile($stream, 0, UPLOAD_ERR_OK);
106  $uploadStream = $upload->getStream();
107  $r = new \ReflectionProperty($uploadStream, 'stream');
108  self::assertSame($stream, $r->getValue($uploadStream));
109  }
110 
111  #[Test]
112  public function ‪moveToMovesFileToDesignatedPath(): void
113  {
114  $stream = new ‪Stream('php://temp', 'wb+');
115  $stream->write('Foo bar!');
116  $upload = new ‪UploadedFile($stream, 0, UPLOAD_ERR_OK);
117 
118  $this->tmpFile = $to = GeneralUtility::tempnam('psr7');
119  $upload->moveTo($to);
120  self::assertFileExists($to);
121  $contents = file_get_contents($to);
122  self::assertEquals($stream->__toString(), $contents);
123  }
124 
125  #[Test]
126  public function ‪moveToRaisesExceptionForEmptyPath(): void
127  {
128  $stream = new ‪Stream('php://temp', 'wb+');
129  $stream->write('Foo bar!');
130  $upload = new ‪UploadedFile($stream, 0, UPLOAD_ERR_OK);
131  $this->expectException(\InvalidArgumentException::class);
132  $this->expectExceptionCode(1436717307);
133  $upload->moveTo('');
134  }
135 
136  #[Test]
137  public function ‪moveToCannotBeCalledMoreThanOnce(): void
138  {
139  $stream = new ‪Stream('php://temp', 'wb+');
140  $stream->write('Foo bar!');
141  $upload = new ‪UploadedFile($stream, 0, UPLOAD_ERR_OK);
142 
143  $this->tmpFile = $to = GeneralUtility::tempnam('psr7');
144  $upload->moveTo($to);
145  self::assertFileExists($to);
146 
147  $this->expectException(\RuntimeException::class);
148  $this->expectExceptionCode(1436717308);
149  $upload->moveTo($to);
150  }
151 
152  #[Test]
154  {
155  $stream = new ‪Stream('php://temp', 'wb+');
156  $stream->write('Foo bar!');
157  $upload = new ‪UploadedFile($stream, 0, UPLOAD_ERR_OK);
158 
159  $this->tmpFile = $to = GeneralUtility::tempnam('psr7');
160  $upload->moveTo($to);
161  self::assertFileExists($to);
162 
163  $this->expectException(\RuntimeException::class);
164  $this->expectExceptionCode(1436717306);
165  $upload->getStream();
166  }
167 
171  #[Test]
172  public function ‪nfdFileNameIsNormalized(): void
173  {
174  $clientFileName = hex2bin('6fcc88') . '.png';
175  $subject = new ‪UploadedFile(fopen('php://temp', 'wb+'), 0, 0, $clientFileName);
176  self::assertSame(hex2bin('c3b6') . '.png', $subject->getClientFilename());
177  }
178 }
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\moveToCannotBeCalledMoreThanOnce
‪moveToCannotBeCalledMoreThanOnce()
Definition: UploadedFileTest.php:137
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\moveToMovesFileToDesignatedPath
‪moveToMovesFileToDesignatedPath()
Definition: UploadedFileTest.php:112
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest
Definition: UploadedFileTest.php:28
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\$tmpFile
‪$tmpFile
Definition: UploadedFileTest.php:29
‪TYPO3\CMS\Core\Tests\Unit\Http
Definition: ApplicationTypeTest.php:18
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\getStreamReturnsOriginalStreamObject
‪getStreamReturnsOriginalStreamObject()
Definition: UploadedFileTest.php:85
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\setUp
‪setUp()
Definition: UploadedFileTest.php:31
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\constructorRaisesExceptionOnInvalidStreamOrFile
‪constructorRaisesExceptionOnInvalidStreamOrFile($streamOrFile)
Definition: UploadedFileTest.php:61
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\getGetStreamRaisesExceptionAfterMove
‪getGetStreamRaisesExceptionAfterMove()
Definition: UploadedFileTest.php:153
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\nfdFileNameIsNormalized
‪nfdFileNameIsNormalized()
Definition: UploadedFileTest.php:172
‪TYPO3\CMS\Core\Http\Stream
Definition: Stream.php:31
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\constructorRaisesExceptionOnInvalidErrorStatus
‪constructorRaisesExceptionOnInvalidErrorStatus($status)
Definition: UploadedFileTest.php:77
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\moveToRaisesExceptionForEmptyPath
‪moveToRaisesExceptionForEmptyPath()
Definition: UploadedFileTest.php:126
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\invalidStreamsDataProvider
‪static invalidStreamsDataProvider()
Definition: UploadedFileTest.php:45
‪TYPO3\CMS\Core\Http\UploadedFile
Definition: UploadedFile.php:34
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\tearDown
‪tearDown()
Definition: UploadedFileTest.php:37
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\invalidErrorStatusesDataProvider
‪static invalidErrorStatusesDataProvider()
Definition: UploadedFileTest.php:67
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\getStreamReturnsWrappedPhpStream
‪getStreamReturnsWrappedPhpStream()
Definition: UploadedFileTest.php:93
‪TYPO3\CMS\Core\Tests\Unit\Http\UploadedFileTest\getStreamReturnsStreamForFile
‪getStreamReturnsStreamForFile()
Definition: UploadedFileTest.php:102