| | 41 | |
| | 42 | /** |
| | 43 | * Detect HTML in the first KB to prevent against potential security issue with |
| | 44 | * IE/Safari/Opera file type auto detection bug. |
| | 45 | * Returns true if file contain insecure HTML code at the beginning. |
| | 46 | * |
| | 47 | * @param string $filePath absolute path to file |
| | 48 | * @return boolean |
| | 49 | */ |
| | 50 | function DetectHtml( $filePath ) |
| | 51 | { |
| | 52 | $fp = fopen( $filePath, 'rb' ) ; |
| | 53 | $chunk = fread( $fp, 1024 ) ; |
| | 54 | fclose( $fp ) ; |
| | 55 | |
| | 56 | $chunk = strtolower( $chunk ) ; |
| | 57 | |
| | 58 | if (!$chunk) |
| | 59 | { |
| | 60 | return false ; |
| | 61 | } |
| | 62 | |
| | 63 | $chunk = trim( $chunk ) ; |
| | 64 | |
| | 65 | if ( preg_match( "/<!DOCTYPE\W*X?HTML/sim", $chunk ) ) |
| | 66 | { |
| | 67 | return true; |
| | 68 | } |
| | 69 | |
| | 70 | $tags = array( '<body', '<head', '<html', '<img', '<pre', '<script', '<table', '<title' ) ; |
| | 71 | |
| | 72 | foreach( $tags as $tag ) |
| | 73 | { |
| | 74 | if( false !== strpos( $chunk, $tag ) ) |
| | 75 | { |
| | 76 | return true ; |
| | 77 | } |
| | 78 | } |
| | 79 | |
| | 80 | //type = javascript |
| | 81 | if ( preg_match( '!type\s*=\s*[\'"]?\s*(?:\w*/)?(?:ecma|java)!sim', $chunk ) ) |
| | 82 | { |
| | 83 | return true ; |
| | 84 | } |
| | 85 | |
| | 86 | //href = javascript |
| | 87 | //src = javascript |
| | 88 | //data = javascript |
| | 89 | if ( preg_match( '!(?:href|src|data)\s*=\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk ) ) |
| | 90 | { |
| | 91 | return true ; |
| | 92 | } |
| | 93 | |
| | 94 | //url(javascript |
| | 95 | if ( preg_match( '!url\s*\(\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk ) ) |
| | 96 | { |
| | 97 | return true ; |
| | 98 | } |
| | 99 | |
| | 100 | return false ; |
| | 101 | } |
| | 102 | |
| | 103 | /** |
| | 104 | * Check file content. |
| | 105 | * Currently this function validates only image files. |
| | 106 | * Returns false if file is invalid. |
| | 107 | * |
| | 108 | * @param string $filePath absolute path to file |
| | 109 | * @param string $extension file extension |
| | 110 | * @param integer $detectionLevel 0 = none, 1 = use getimagesize for images, 2 = use DetectHtml for images |
| | 111 | * @return boolean |
| | 112 | */ |
| | 113 | function IsFileValid( $filePath, $extension, $detectionLevel ) |
| | 114 | { |
| | 115 | if ( $detectionLevel <= 0 ) { |
| | 116 | return true; |
| | 117 | } |
| | 118 | |
| | 119 | $imageCheckExtensions = array('gif', 'jpeg', 'jpg', 'png', 'swf', 'psd', 'bmp', 'iff'); |
| | 120 | |
| | 121 | // version_compare is available since PHP4 >= 4.0.7 |
| | 122 | if ( function_exists( 'version_compare' ) ) { |
| | 123 | $sCurrentVersion = phpversion(); |
| | 124 | if ( version_compare( $sCurrentVersion, "4.2.0" ) >= 0 ) { |
| | 125 | $imageCheckExtensions[] = "tiff"; |
| | 126 | $imageCheckExtensions[] = "tif"; |
| | 127 | } |
| | 128 | if ( version_compare( $sCurrentVersion, "4.3.0" ) >= 0 ) { |
| | 129 | $imageCheckExtensions[] = "swc"; |
| | 130 | } |
| | 131 | if ( version_compare( $sCurrentVersion, "4.3.2" ) >= 0 ) { |
| | 132 | $imageCheckExtensions[] = "jpc"; |
| | 133 | $imageCheckExtensions[] = "jp2"; |
| | 134 | $imageCheckExtensions[] = "jpx"; |
| | 135 | $imageCheckExtensions[] = "jb2"; |
| | 136 | $imageCheckExtensions[] = "xbm"; |
| | 137 | $imageCheckExtensions[] = "wbmp"; |
| | 138 | } |
| | 139 | } |
| | 140 | |
| | 141 | if ( !in_array( $extension, $imageCheckExtensions ) ) { |
| | 142 | return true; |
| | 143 | } |
| | 144 | |
| | 145 | if ( $detectionLevel >= 1) { |
| | 146 | if ( @getimagesize( $filePath ) === false ) { |
| | 147 | return false ; |
| | 148 | } |
| | 149 | } |
| | 150 | |
| | 151 | if ( $detectionLevel >= 2) { |
| | 152 | if ( DetectHtml( $filePath ) ) { |
| | 153 | return false; |
| | 154 | } |
| | 155 | } |
| | 156 | |
| | 157 | return true; |
| | 158 | } |
| | 159 | |