Passed
Pull Request — master (#29)
by
unknown
04:17
created
src/MimeUploadValidator.php 2 patches
Indentation   +154 added lines, -154 removed lines patch added patch discarded remove patch
@@ -19,158 +19,158 @@
 block discarded – undo
19 19
  */
20 20
 class MimeUploadValidator extends Upload_Validator
21 21
 {
22
-    /**
23
-     * The preg_replace() pattern to use against MIME types. Used to strip out
24
-     * useless characters so matching of MIME types can be fuzzy.
25
-     *
26
-     * @var string Regexp pattern
27
-     */
28
-    protected $filterPattern = '/.*[\/\.\-\+]/i';
29
-
30
-    /**
31
-     * @param string $pattern
32
-     */
33
-    public function setFilterPattern($pattern)
34
-    {
35
-        $this->filterPattern = $pattern;
36
-    }
37
-
38
-    /**
39
-     * @return string
40
-     */
41
-    public function getFilterPattern()
42
-    {
43
-        return $this->filterPattern;
44
-    }
45
-
46
-    /**
47
-     * Check if the temporary file has a valid MIME type for it's extension.
48
-     *
49
-     * @uses finfo php extension
50
-     * @return bool|null
51
-     * @throws MimeUploadValidator_Exception
52
-     */
53
-    public function isValidMime()
54
-    {
55
-        $extension = strtolower(pathinfo($this->tmpFile['name'], PATHINFO_EXTENSION));
56
-
57
-        // we can't check filenames without an extension or no temp file path, let them pass validation.
58
-        if (!$extension || !$this->tmpFile['tmp_name']) {
59
-            return true;
60
-        }
61
-
62
-        $expectedMimes = $this->getExpectedMimeTypes($this->tmpFile);
63
-        if (empty($expectedMimes)) {
64
-            throw new MimeUploadValidator_Exception(
65
-                sprintf('Could not find a MIME type for extension %s', $extension)
66
-            );
67
-        }
68
-
69
-        $fileInfo = new finfo(FILEINFO_MIME_TYPE);
70
-        $foundMime = $fileInfo->file($this->tmpFile['tmp_name']);
71
-        if (!$foundMime) {
72
-            throw new MimeUploadValidator_Exception(
73
-                sprintf('Could not find a MIME type for file %s', $this->tmpFile['tmp_name'])
74
-            );
75
-        }
76
-
77
-        foreach ($expectedMimes as $expected) {
78
-            if ($this->compareMime($foundMime, $expected)) {
79
-                return true;
80
-            }
81
-        }
82
-
83
-        return false;
84
-    }
85
-
86
-    /**
87
-     * Fetches an array of valid mimetypes.
88
-     *
89
-     * @param $file
90
-     * @return array
91
-     * @throws MimeUploadValidator_Exception
92
-     */
93
-    public function getExpectedMimeTypes($file)
94
-    {
95
-        $extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
96
-
97
-        // if the finfo php extension isn't loaded, we can't complete this check.
98
-        if (!class_exists('finfo')) {
99
-            throw new MimeUploadValidator_Exception('PHP extension finfo is not loaded');
100
-        }
101
-
102
-        // Attempt to figure out which mime types are expected/acceptable here.
103
-        $expectedMimes = array();
104
-
105
-        // Get the mime types set in framework core
106
-        $knownMimes = Config::inst()->get(HTTP::class, 'MimeTypes');
107
-        if (isset($knownMimes[$extension])) {
108
-            $expectedMimes[] = $knownMimes[$extension];
109
-        }
110
-
111
-        // Get the mime types and their variations from mime validator
112
-        $knownMimes = $this->config()->get('MimeTypes');
113
-        if (isset($knownMimes[$extension])) {
114
-          $mimes = (array) $knownMimes[$extension];
115
-
116
-          foreach($mimes as $mime){
117
-              if (!in_array($mime,$expectedMimes)) {
118
-                  $expectedMimes[] = $mime;
119
-              }
120
-          }
121
-        }
122
-
123
-        return $expectedMimes;
124
-    }
125
-
126
-    /**
127
-     * Check two MIME types roughly match eachother.
128
-     *
129
-     * Before we check MIME types, remove known prefixes "vnd.", "x-" etc.
130
-     * If there is a suffix, we'll use that to compare. Examples:
131
-     *
132
-     * application/x-json = json
133
-     * application/json = json
134
-     * application/xhtml+xml = xml
135
-     * application/xml = xml
136
-     *
137
-     * @param string $first The first MIME type to compare to the second
138
-     * @param string $second The second MIME type to compare to the first
139
-     * @return boolean
140
-     */
141
-    public function compareMime($first, $second)
142
-    {
143
-        return preg_replace($this->filterPattern, '', $first) === preg_replace($this->filterPattern, '', $second);
144
-    }
145
-
146
-    public function validate()
147
-    {
148
-        if (parent::validate() === false) {
149
-            return false;
150
-        }
151
-
152
-        try {
153
-            $result = $this->isValidMime();
154
-
155
-            if ($result === false) {
156
-                $this->errors[] = _t(
157
-                    __CLASS__ . '.INVALIDMIME',
158
-                    'File extension does not match known MIME type'
159
-                );
160
-
161
-                return false;
162
-            }
163
-        } catch (MimeUploadValidator_Exception $e) {
164
-            $this->errors[] = _t(
165
-                __CLASS__ . '.FAILEDMIMECHECK',
166
-                'MIME validation failed: {message}',
167
-                'Argument 1: Message about why MIME type detection failed',
168
-                ['message' => $e->getMessage()]
169
-            );
170
-
171
-            return false;
172
-        }
173
-
174
-        return true;
175
-    }
22
+	/**
23
+	 * The preg_replace() pattern to use against MIME types. Used to strip out
24
+	 * useless characters so matching of MIME types can be fuzzy.
25
+	 *
26
+	 * @var string Regexp pattern
27
+	 */
28
+	protected $filterPattern = '/.*[\/\.\-\+]/i';
29
+
30
+	/**
31
+	 * @param string $pattern
32
+	 */
33
+	public function setFilterPattern($pattern)
34
+	{
35
+		$this->filterPattern = $pattern;
36
+	}
37
+
38
+	/**
39
+	 * @return string
40
+	 */
41
+	public function getFilterPattern()
42
+	{
43
+		return $this->filterPattern;
44
+	}
45
+
46
+	/**
47
+	 * Check if the temporary file has a valid MIME type for it's extension.
48
+	 *
49
+	 * @uses finfo php extension
50
+	 * @return bool|null
51
+	 * @throws MimeUploadValidator_Exception
52
+	 */
53
+	public function isValidMime()
54
+	{
55
+		$extension = strtolower(pathinfo($this->tmpFile['name'], PATHINFO_EXTENSION));
56
+
57
+		// we can't check filenames without an extension or no temp file path, let them pass validation.
58
+		if (!$extension || !$this->tmpFile['tmp_name']) {
59
+			return true;
60
+		}
61
+
62
+		$expectedMimes = $this->getExpectedMimeTypes($this->tmpFile);
63
+		if (empty($expectedMimes)) {
64
+			throw new MimeUploadValidator_Exception(
65
+				sprintf('Could not find a MIME type for extension %s', $extension)
66
+			);
67
+		}
68
+
69
+		$fileInfo = new finfo(FILEINFO_MIME_TYPE);
70
+		$foundMime = $fileInfo->file($this->tmpFile['tmp_name']);
71
+		if (!$foundMime) {
72
+			throw new MimeUploadValidator_Exception(
73
+				sprintf('Could not find a MIME type for file %s', $this->tmpFile['tmp_name'])
74
+			);
75
+		}
76
+
77
+		foreach ($expectedMimes as $expected) {
78
+			if ($this->compareMime($foundMime, $expected)) {
79
+				return true;
80
+			}
81
+		}
82
+
83
+		return false;
84
+	}
85
+
86
+	/**
87
+	 * Fetches an array of valid mimetypes.
88
+	 *
89
+	 * @param $file
90
+	 * @return array
91
+	 * @throws MimeUploadValidator_Exception
92
+	 */
93
+	public function getExpectedMimeTypes($file)
94
+	{
95
+		$extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
96
+
97
+		// if the finfo php extension isn't loaded, we can't complete this check.
98
+		if (!class_exists('finfo')) {
99
+			throw new MimeUploadValidator_Exception('PHP extension finfo is not loaded');
100
+		}
101
+
102
+		// Attempt to figure out which mime types are expected/acceptable here.
103
+		$expectedMimes = array();
104
+
105
+		// Get the mime types set in framework core
106
+		$knownMimes = Config::inst()->get(HTTP::class, 'MimeTypes');
107
+		if (isset($knownMimes[$extension])) {
108
+			$expectedMimes[] = $knownMimes[$extension];
109
+		}
110
+
111
+		// Get the mime types and their variations from mime validator
112
+		$knownMimes = $this->config()->get('MimeTypes');
113
+		if (isset($knownMimes[$extension])) {
114
+		  $mimes = (array) $knownMimes[$extension];
115
+
116
+		  foreach($mimes as $mime){
117
+			  if (!in_array($mime,$expectedMimes)) {
118
+				  $expectedMimes[] = $mime;
119
+			  }
120
+		  }
121
+		}
122
+
123
+		return $expectedMimes;
124
+	}
125
+
126
+	/**
127
+	 * Check two MIME types roughly match eachother.
128
+	 *
129
+	 * Before we check MIME types, remove known prefixes "vnd.", "x-" etc.
130
+	 * If there is a suffix, we'll use that to compare. Examples:
131
+	 *
132
+	 * application/x-json = json
133
+	 * application/json = json
134
+	 * application/xhtml+xml = xml
135
+	 * application/xml = xml
136
+	 *
137
+	 * @param string $first The first MIME type to compare to the second
138
+	 * @param string $second The second MIME type to compare to the first
139
+	 * @return boolean
140
+	 */
141
+	public function compareMime($first, $second)
142
+	{
143
+		return preg_replace($this->filterPattern, '', $first) === preg_replace($this->filterPattern, '', $second);
144
+	}
145
+
146
+	public function validate()
147
+	{
148
+		if (parent::validate() === false) {
149
+			return false;
150
+		}
151
+
152
+		try {
153
+			$result = $this->isValidMime();
154
+
155
+			if ($result === false) {
156
+				$this->errors[] = _t(
157
+					__CLASS__ . '.INVALIDMIME',
158
+					'File extension does not match known MIME type'
159
+				);
160
+
161
+				return false;
162
+			}
163
+		} catch (MimeUploadValidator_Exception $e) {
164
+			$this->errors[] = _t(
165
+				__CLASS__ . '.FAILEDMIMECHECK',
166
+				'MIME validation failed: {message}',
167
+				'Argument 1: Message about why MIME type detection failed',
168
+				['message' => $e->getMessage()]
169
+			);
170
+
171
+			return false;
172
+		}
173
+
174
+		return true;
175
+	}
176 176
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -113,8 +113,8 @@  discard block
 block discarded – undo
113 113
         if (isset($knownMimes[$extension])) {
114 114
           $mimes = (array) $knownMimes[$extension];
115 115
 
116
-          foreach($mimes as $mime){
117
-              if (!in_array($mime,$expectedMimes)) {
116
+          foreach ($mimes as $mime) {
117
+              if (!in_array($mime, $expectedMimes)) {
118 118
                   $expectedMimes[] = $mime;
119 119
               }
120 120
           }
@@ -154,7 +154,7 @@  discard block
 block discarded – undo
154 154
 
155 155
             if ($result === false) {
156 156
                 $this->errors[] = _t(
157
-                    __CLASS__ . '.INVALIDMIME',
157
+                    __CLASS__.'.INVALIDMIME',
158 158
                     'File extension does not match known MIME type'
159 159
                 );
160 160
 
@@ -162,7 +162,7 @@  discard block
 block discarded – undo
162 162
             }
163 163
         } catch (MimeUploadValidator_Exception $e) {
164 164
             $this->errors[] = _t(
165
-                __CLASS__ . '.FAILEDMIMECHECK',
165
+                __CLASS__.'.FAILEDMIMECHECK',
166 166
                 'MIME validation failed: {message}',
167 167
                 'Argument 1: Message about why MIME type detection failed',
168 168
                 ['message' => $e->getMessage()]
Please login to merge, or discard this patch.
tests/MimeUploadValidatorTest.php 2 patches
Indentation   +92 added lines, -92 removed lines patch added patch discarded remove patch
@@ -12,96 +12,96 @@
 block discarded – undo
12 12
  */
13 13
 class MimeUploadValidatorTest extends SapphireTest
14 14
 {
15
-    public function testInvalidFileExtensionValidatingMimeType()
16
-    {
17
-        // setup plaintext file with invalid extension
18
-        $tmpFileName = 'UploadTest-testUpload.jpg';
19
-        $tmpFilePath = TEMP_FOLDER . '/' . $tmpFileName;
20
-        $tmpFileContent = '';
21
-
22
-        for ($i = 0; $i < 10000; $i++) {
23
-            $tmpFileContent .= '0';
24
-        }
25
-
26
-        file_put_contents($tmpFilePath, $tmpFileContent);
27
-
28
-        // emulates the $_FILES array
29
-        $tmpFile = [
30
-            'name' => $tmpFileName,
31
-            'size' => filesize($tmpFilePath),
32
-            'tmp_name' => $tmpFilePath,
33
-            'extension' => 'jpg',
34
-            'error' => UPLOAD_ERR_OK,
35
-        ];
36
-
37
-        $upload = Upload::create();
38
-        $upload->setValidator(MimeUploadValidator::create());
39
-        $result = $upload->load($tmpFile);
40
-        $errors = $upload->getErrors();
41
-
42
-        $this->assertFalse($result, 'Load failed because file extension does not match excepted MIME type');
43
-        $this->assertEquals('File is not a valid upload', $errors[0]);
44
-
45
-        unlink($tmpFilePath);
46
-    }
47
-
48
-    public function testGetExpectedMimeTypes()
49
-    {
50
-        // Setup a file with a capitalised extension and try to match it against a lowercase file.
51
-        $tmpFileName = 'text.TXT';
52
-        $tmpFilePath = TEMP_FOLDER . '/' . $tmpFileName;
53
-        $tmpFileContent = '';
54
-
55
-        for ($i = 0; $i < 10000; $i++) {
56
-            $tmpFileContent .= '0';
57
-        }
58
-
59
-        file_put_contents($tmpFilePath, $tmpFileContent);
60
-
61
-        $validator = MimeUploadValidator::create();
62
-        $tmpFile = [
63
-            'name' => $tmpFileName,
64
-            'tmp_name' => $tmpFilePath,
65
-        ];
66
-
67
-        $expected = $validator->getExpectedMimeTypes($tmpFile);
68
-        $this->assertCount(1, $expected);
69
-        $this->assertContains('text/plain', $expected);
70
-
71
-        unlink($tmpFilePath);
72
-
73
-        // Test a physical ico file with capitalised extension
74
-        $tmpFile = [
75
-            'name' => 'favicon.ICO',
76
-            'tmp_name' => 'assets/favicon.ICO',
77
-        ];
78
-
79
-        // Ensure that site configuration doesn't interfere with the test
80
-        $icoMimes = [
81
-            'ico' => [
82
-                'image/vnd.microsoft.icon',
83
-                'image/x-icon',
84
-                'image/x-ico'
85
-            ]
86
-        ];
87
-        Config::modify()->set(MimeUploadValidator::class, 'MimeTypes', $icoMimes);
88
-
89
-        $expected = $validator->getExpectedMimeTypes($tmpFile);
90
-        $this->assertCount(3, $expected);
91
-        $this->assertContains('image/x-icon', $expected);
92
-    }
93
-
94
-    public function testMimeComparison()
95
-    {
96
-        $validator = MimeUploadValidator::create();
97
-
98
-        $this->assertTrue($validator->compareMime('application/xhtml+xml', 'application/xml'));
99
-        $this->assertTrue($validator->compareMime('application/vnd.text', 'application/text'));
100
-        $this->assertTrue($validator->compareMime('application/vnd.vnd.text', 'application/text'));
101
-        $this->assertTrue($validator->compareMime('application/x-text', 'application/text'));
102
-        $this->assertTrue($validator->compareMime('application/gzip', 'application/gzip'));
103
-        $this->assertTrue($validator->compareMime('application/x-gzip', 'application/gzip'));
104
-        $this->assertFalse($validator->compareMime('application/png', 'application/json'));
105
-        $this->assertFalse($validator->compareMime('text/plain', 'text/json'));
106
-    }
15
+	public function testInvalidFileExtensionValidatingMimeType()
16
+	{
17
+		// setup plaintext file with invalid extension
18
+		$tmpFileName = 'UploadTest-testUpload.jpg';
19
+		$tmpFilePath = TEMP_FOLDER . '/' . $tmpFileName;
20
+		$tmpFileContent = '';
21
+
22
+		for ($i = 0; $i < 10000; $i++) {
23
+			$tmpFileContent .= '0';
24
+		}
25
+
26
+		file_put_contents($tmpFilePath, $tmpFileContent);
27
+
28
+		// emulates the $_FILES array
29
+		$tmpFile = [
30
+			'name' => $tmpFileName,
31
+			'size' => filesize($tmpFilePath),
32
+			'tmp_name' => $tmpFilePath,
33
+			'extension' => 'jpg',
34
+			'error' => UPLOAD_ERR_OK,
35
+		];
36
+
37
+		$upload = Upload::create();
38
+		$upload->setValidator(MimeUploadValidator::create());
39
+		$result = $upload->load($tmpFile);
40
+		$errors = $upload->getErrors();
41
+
42
+		$this->assertFalse($result, 'Load failed because file extension does not match excepted MIME type');
43
+		$this->assertEquals('File is not a valid upload', $errors[0]);
44
+
45
+		unlink($tmpFilePath);
46
+	}
47
+
48
+	public function testGetExpectedMimeTypes()
49
+	{
50
+		// Setup a file with a capitalised extension and try to match it against a lowercase file.
51
+		$tmpFileName = 'text.TXT';
52
+		$tmpFilePath = TEMP_FOLDER . '/' . $tmpFileName;
53
+		$tmpFileContent = '';
54
+
55
+		for ($i = 0; $i < 10000; $i++) {
56
+			$tmpFileContent .= '0';
57
+		}
58
+
59
+		file_put_contents($tmpFilePath, $tmpFileContent);
60
+
61
+		$validator = MimeUploadValidator::create();
62
+		$tmpFile = [
63
+			'name' => $tmpFileName,
64
+			'tmp_name' => $tmpFilePath,
65
+		];
66
+
67
+		$expected = $validator->getExpectedMimeTypes($tmpFile);
68
+		$this->assertCount(1, $expected);
69
+		$this->assertContains('text/plain', $expected);
70
+
71
+		unlink($tmpFilePath);
72
+
73
+		// Test a physical ico file with capitalised extension
74
+		$tmpFile = [
75
+			'name' => 'favicon.ICO',
76
+			'tmp_name' => 'assets/favicon.ICO',
77
+		];
78
+
79
+		// Ensure that site configuration doesn't interfere with the test
80
+		$icoMimes = [
81
+			'ico' => [
82
+				'image/vnd.microsoft.icon',
83
+				'image/x-icon',
84
+				'image/x-ico'
85
+			]
86
+		];
87
+		Config::modify()->set(MimeUploadValidator::class, 'MimeTypes', $icoMimes);
88
+
89
+		$expected = $validator->getExpectedMimeTypes($tmpFile);
90
+		$this->assertCount(3, $expected);
91
+		$this->assertContains('image/x-icon', $expected);
92
+	}
93
+
94
+	public function testMimeComparison()
95
+	{
96
+		$validator = MimeUploadValidator::create();
97
+
98
+		$this->assertTrue($validator->compareMime('application/xhtml+xml', 'application/xml'));
99
+		$this->assertTrue($validator->compareMime('application/vnd.text', 'application/text'));
100
+		$this->assertTrue($validator->compareMime('application/vnd.vnd.text', 'application/text'));
101
+		$this->assertTrue($validator->compareMime('application/x-text', 'application/text'));
102
+		$this->assertTrue($validator->compareMime('application/gzip', 'application/gzip'));
103
+		$this->assertTrue($validator->compareMime('application/x-gzip', 'application/gzip'));
104
+		$this->assertFalse($validator->compareMime('application/png', 'application/json'));
105
+		$this->assertFalse($validator->compareMime('text/plain', 'text/json'));
106
+	}
107 107
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -16,7 +16,7 @@  discard block
 block discarded – undo
16 16
     {
17 17
         // setup plaintext file with invalid extension
18 18
         $tmpFileName = 'UploadTest-testUpload.jpg';
19
-        $tmpFilePath = TEMP_FOLDER . '/' . $tmpFileName;
19
+        $tmpFilePath = TEMP_FOLDER.'/'.$tmpFileName;
20 20
         $tmpFileContent = '';
21 21
 
22 22
         for ($i = 0; $i < 10000; $i++) {
@@ -49,7 +49,7 @@  discard block
 block discarded – undo
49 49
     {
50 50
         // Setup a file with a capitalised extension and try to match it against a lowercase file.
51 51
         $tmpFileName = 'text.TXT';
52
-        $tmpFilePath = TEMP_FOLDER . '/' . $tmpFileName;
52
+        $tmpFilePath = TEMP_FOLDER.'/'.$tmpFileName;
53 53
         $tmpFileContent = '';
54 54
 
55 55
         for ($i = 0; $i < 10000; $i++) {
Please login to merge, or discard this patch.