Completed
Push — master ( ed35ab...871ad1 )
by Michael
05:54
created

util.php ➔ IsImageValid()   C

Complexity

Conditions 8
Paths 28

Size

Total Lines 38
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 23
nc 28
nop 2
dl 0
loc 38
rs 5.3846
c 0
b 0
f 0
1
<?php
2
/*
3
 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
4
 * Copyright (C) 2003-2010 Frederico Caldeira Knabben
5
 *
6
 * == BEGIN LICENSE ==
7
 *
8
 * Licensed under the terms of any of the following licenses at your
9
 * choice:
10
 *
11
 *  - GNU General Public License Version 2 or later (the "GPL")
12
 *    http://www.gnu.org/licenses/gpl.html
13
 *
14
 *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
15
 *    http://www.gnu.org/licenses/lgpl.html
16
 *
17
 *  - Mozilla Public License Version 1.1 or later (the "MPL")
18
 *    http://www.mozilla.org/MPL/MPL-1.1.html
19
 *
20
 * == END LICENSE ==
21
 *
22
 * Utility functions for the File Manager Connector for PHP.
23
 */
24
25
function RemoveFromStart( $sourceString, $charToRemove )
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
26
{
27
	$sPattern = '|^' . $charToRemove . '+|' ;
28
	return preg_replace( $sPattern, '', $sourceString ) ;
29
}
30
31
function RemoveFromEnd( $sourceString, $charToRemove )
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
32
{
33
	$sPattern = '|' . $charToRemove . '+$|' ;
34
	return preg_replace( $sPattern, '', $sourceString ) ;
35
}
36
37
function FindBadUtf8( $string )
38
{
39
	$regex =
40
	'([\x00-\x7F]'.
41
	'|[\xC2-\xDF][\x80-\xBF]'.
42
	'|\xE0[\xA0-\xBF][\x80-\xBF]'.
43
	'|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}'.
44
	'|\xED[\x80-\x9F][\x80-\xBF]'.
45
	'|\xF0[\x90-\xBF][\x80-\xBF]{2}'.
46
	'|[\xF1-\xF3][\x80-\xBF]{3}'.
47
	'|\xF4[\x80-\x8F][\x80-\xBF]{2}'.
48
	'|(.{1}))';
49
50
	while (preg_match('/'.$regex.'/S', $string, $matches)) {
51
		if ( isset($matches[2])) {
52
			return true;
53
		}
54
		$string = substr($string, strlen($matches[0]));
55
	}
56
57
	return false;
58
}
59
60
function ConvertToXmlAttribute( $value )
61
{
62
	if ( defined( 'PHP_OS' ) )
63
	{
64
		$os = PHP_OS ;
65
	}
66
	else
67
	{
68
		$os = php_uname() ;
69
	}
70
71
	if ( strtoupper( substr( $os, 0, 3 ) ) === 'WIN' || FindBadUtf8( $value ) )
72
	{
73
		return ( utf8_encode( htmlspecialchars( $value ) ) ) ;
74
	}
75
	else
76
	{
77
		return ( htmlspecialchars( $value ) ) ;
78
	}
79
}
80
81
/**
82
 * Check whether given extension is in html etensions list
83
 *
84
 * @param string $ext
85
 * @param array $htmlExtensions
86
 * @return boolean
87
 */
88
function IsHtmlExtension( $ext, $htmlExtensions )
89
{
90
	if ( !$htmlExtensions || !is_array( $htmlExtensions ) )
0 ignored issues
show
Bug Best Practice introduced by
The expression $htmlExtensions of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
91
	{
92
		return false ;
93
	}
94
	$lcaseHtmlExtensions = array() ;
95
	foreach ( $htmlExtensions as $key => $val )
96
	{
97
		$lcaseHtmlExtensions[$key] = strtolower( $val ) ;
98
	}
99
	return in_array( $ext, $lcaseHtmlExtensions ) ;
100
}
101
102
/**
103
 * Detect HTML in the first KB to prevent against potential security issue with
104
 * IE/Safari/Opera file type auto detection bug.
105
 * Returns true if file contain insecure HTML code at the beginning.
106
 *
107
 * @param string $filePath absolute path to file
108
 * @return boolean
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
109
 */
110
function DetectHtml( $filePath )
111
{
112
	$fp = @fopen( $filePath, 'rb' ) ;
113
114
	//open_basedir restriction, see #1906
115
	if ( $fp === false || !flock( $fp, LOCK_SH ) )
116
	{
117
		return -1 ;
118
	}
119
120
	$chunk = fread( $fp, 1024 ) ;
121
	flock( $fp, LOCK_UN ) ;
122
	fclose( $fp ) ;
123
124
	$chunk = strtolower( $chunk ) ;
125
126
	if (!$chunk)
127
	{
128
		return false ;
129
	}
130
131
	$chunk = trim( $chunk ) ;
132
133
	if ( preg_match( "/<!DOCTYPE\W*X?HTML/sim", $chunk ) )
134
	{
135
		return true;
136
	}
137
138
	$tags = array( '<body', '<head', '<html', '<img', '<pre', '<script', '<table', '<title' ) ;
139
140
	foreach( $tags as $tag )
141
	{
142
		if( false !== strpos( $chunk, $tag ) )
143
		{
144
			return true ;
145
		}
146
	}
147
148
	//type = javascript
149
	if ( preg_match( '!type\s*=\s*[\'"]?\s*(?:\w*/)?(?:ecma|java)!sim', $chunk ) )
150
	{
151
		return true ;
152
	}
153
154
	//href = javascript
155
	//src = javascript
156
	//data = javascript
157
	if ( preg_match( '!(?:href|src|data)\s*=\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk ) )
158
	{
159
		return true ;
160
	}
161
162
	//url(javascript
163
	if ( preg_match( '!url\s*\(\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk ) )
164
	{
165
		return true ;
166
	}
167
168
	return false ;
169
}
170
171
/**
172
 * Check file content.
173
 * Currently this function validates only image files.
174
 * Returns false if file is invalid.
175
 *
176
 * @param string $filePath absolute path to file
177
 * @param string $extension file extension
178
 * @param integer $detectionLevel 0 = none, 1 = use getimagesize for images, 2 = use DetectHtml for images
0 ignored issues
show
Bug introduced by
There is no parameter named $detectionLevel. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
179
 * @return boolean
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
180
 */
181
function IsImageValid( $filePath, $extension )
182
{
183
	if (!@is_readable($filePath)) {
184
		return -1;
185
	}
186
187
	$imageCheckExtensions = array('gif', 'jpeg', 'jpg', 'png', 'swf', 'psd', 'bmp', 'iff');
188
189
	// version_compare is available since PHP4 >= 4.0.7
190
	if ( function_exists( 'version_compare' ) ) {
191
		$sCurrentVersion = phpversion();
192
		if ( version_compare( $sCurrentVersion, "4.2.0" ) >= 0 ) {
193
			$imageCheckExtensions[] = "tiff";
194
			$imageCheckExtensions[] = "tif";
195
		}
196
		if ( version_compare( $sCurrentVersion, "4.3.0" ) >= 0 ) {
197
			$imageCheckExtensions[] = "swc";
198
		}
199
		if ( version_compare( $sCurrentVersion, "4.3.2" ) >= 0 ) {
200
			$imageCheckExtensions[] = "jpc";
201
			$imageCheckExtensions[] = "jp2";
202
			$imageCheckExtensions[] = "jpx";
203
			$imageCheckExtensions[] = "jb2";
204
			$imageCheckExtensions[] = "xbm";
205
			$imageCheckExtensions[] = "wbmp";
206
		}
207
	}
208
209
	if ( !in_array( $extension, $imageCheckExtensions ) ) {
210
		return true;
211
	}
212
213
	if ( @getimagesize( $filePath ) === false ) {
214
		return false ;
215
	}
216
217
	return true;
218
}
219
220
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
221