PageRenderTime 26ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/public/ckfinder/core/connector/php/php5/Utils/FileSystem.php

https://github.com/dmi3x/test-CMS-for-Kohana-3
PHP | 474 lines | 264 code | 53 blank | 157 comment | 102 complexity | 6b404595c351d171b10808740f9ffadd MD5 | raw file
  1. <?php
  2. /*
  3. * CKFinder
  4. * ========
  5. * http://ckfinder.com
  6. * Copyright (C) 2007-2010, CKSource - Frederico Knabben. All rights reserved.
  7. *
  8. * The software, this file and its contents are subject to the CKFinder
  9. * License. Please read the license.txt file before using, installing, copying,
  10. * modifying or distribute this file or part of its contents. The contents of
  11. * this file is part of the Source Code of CKFinder.
  12. */
  13. /**
  14. * @package CKFinder
  15. * @subpackage Utils
  16. * @copyright CKSource - Frederico Knabben
  17. */
  18. /**
  19. * @package CKFinder
  20. * @subpackage Utils
  21. * @copyright CKSource - Frederico Knabben
  22. */
  23. class CKFinder_Connector_Utils_FileSystem
  24. {
  25. /**
  26. * This function behaves similar to System.IO.Path.Combine in C#, the only diffrenece is that it also accepts null values and treat them as empty string
  27. *
  28. * @static
  29. * @access public
  30. * @param string $path1 first path
  31. * @param string $path2 scecond path
  32. * @return string
  33. */
  34. public static function combinePaths($path1, $path2)
  35. {
  36. if (is_null($path1)) {
  37. $path1 = "";
  38. }
  39. if (is_null($path2)) {
  40. $path2 = "";
  41. }
  42. if (!strlen($path2)) {
  43. if (strlen($path1)) {
  44. $_lastCharP1 = substr($path1, -1, 1);
  45. if ($_lastCharP1 != "/" && $_lastCharP1 != "\\") {
  46. $path1 .= DIRECTORY_SEPARATOR;
  47. }
  48. }
  49. }
  50. else {
  51. $_firstCharP2 = substr($path2, 0, 1);
  52. if (strlen($path1)) {
  53. if (strpos($path2, $path1)===0) {
  54. return $path2;
  55. }
  56. $_lastCharP1 = substr($path1, -1, 1);
  57. if ($_lastCharP1 != "/" && $_lastCharP1 != "\\" && $_firstCharP2 != "/" && $_firstCharP2 != "\\") {
  58. $path1 .= DIRECTORY_SEPARATOR;
  59. }
  60. }
  61. else {
  62. return $path2;
  63. }
  64. }
  65. return $path1 . $path2;
  66. }
  67. /**
  68. * Check whether $fileName is a valid file name, return true on success
  69. *
  70. * @static
  71. * @access public
  72. * @param string $fileName
  73. * @return boolean
  74. */
  75. public static function checkFileName($fileName)
  76. {
  77. if (is_null($fileName) || !strlen($fileName) || substr($fileName,-1,1)=="." || false!==strpos($fileName, "..")) {
  78. return false;
  79. }
  80. if (preg_match(CKFINDER_REGEX_INVALID_FILE, $fileName)) {
  81. return false;
  82. }
  83. return true;
  84. }
  85. /**
  86. * Unlink file/folder
  87. *
  88. * @static
  89. * @access public
  90. * @param string $path
  91. * @return boolean
  92. */
  93. public static function unlink($path)
  94. {
  95. /* make sure the path exists */
  96. if(!file_exists($path)) {
  97. return false;
  98. }
  99. /* If it is a file or link, just delete it */
  100. if(is_file($path) || is_link($path)) {
  101. return @unlink($path);
  102. }
  103. /* Scan the dir and recursively unlink */
  104. $files = scandir($path);
  105. if ($files) {
  106. foreach($files as $filename)
  107. {
  108. if ($filename == '.' || $filename == '..') {
  109. continue;
  110. }
  111. $file = str_replace('//','/',$path.'/'.$filename);
  112. CKFinder_Connector_Utils_FileSystem::unlink($file);
  113. }
  114. }
  115. /* Remove the parent dir */
  116. if(!@rmdir($path)) {
  117. return false;
  118. }
  119. return true;
  120. }
  121. /**
  122. * Return file name without extension (without dot & last part after dot)
  123. *
  124. * @static
  125. * @access public
  126. * @param string $fileName
  127. * @return string
  128. */
  129. public static function getFileNameWithoutExtension($fileName)
  130. {
  131. $dotPos = strrpos( $fileName, '.' );
  132. if (false === $dotPos) {
  133. return $fileName;
  134. }
  135. return substr($fileName, 0, $dotPos);
  136. }
  137. /**
  138. * Get file extension (only last part - e.g. extension of file.foo.bar.jpg = jpg)
  139. *
  140. * @static
  141. * @access public
  142. * @param string $fileName
  143. * @return string
  144. */
  145. public static function getExtension( $fileName )
  146. {
  147. $dotPos = strrpos( $fileName, '.' );
  148. if (false === $dotPos) {
  149. return "";
  150. }
  151. return substr( $fileName, strrpos( $fileName, '.' ) +1 ) ;
  152. }
  153. /**
  154. * Read file, split it into small chunks and send it to the browser
  155. *
  156. * @static
  157. * @access public
  158. * @param string $filename
  159. * @return boolean
  160. */
  161. public static function readfileChunked($filename)
  162. {
  163. $chunksize = 1024 * 10; // how many bytes per chunk
  164. $handle = fopen($filename, 'rb');
  165. if ($handle === false) {
  166. return false;
  167. }
  168. while (!feof($handle)) {
  169. echo fread($handle, $chunksize);
  170. @ob_flush();
  171. flush();
  172. set_time_limit(8);
  173. }
  174. fclose($handle);
  175. return true;
  176. }
  177. /**
  178. * Convert file name from UTF-8 to system encoding
  179. *
  180. * @static
  181. * @access public
  182. * @param string $fileName
  183. * @return string
  184. */
  185. public static function convertToFilesystemEncoding($fileName)
  186. {
  187. $_config =& CKFinder_Connector_Core_Factory::getInstance("Core_Config");
  188. $encoding = $_config->getFilesystemEncoding();
  189. if (is_null($encoding) || strcasecmp($encoding, "UTF-8") == 0 || strcasecmp($encoding, "UTF8") == 0) {
  190. return $fileName;
  191. }
  192. if (!function_exists("iconv")) {
  193. if (strcasecmp($encoding, "ISO-8859-1") == 0 || strcasecmp($encoding, "ISO8859-1") == 0 || strcasecmp($encoding, "Latin1") == 0) {
  194. return str_replace("\0", "_", utf8_decode($fileName));
  195. } else if (function_exists('mb_convert_encoding')) {
  196. /**
  197. * @todo check whether charset is supported - mb_list_encodings
  198. */
  199. $encoded = @mb_convert_encoding($fileName, $encoding, 'UTF-8');
  200. if (@mb_strlen($fileName, "UTF-8") != @mb_strlen($encoded, $encoding)) {
  201. return str_replace("\0", "_", preg_replace("/[^[:ascii:]]/u","_",$fileName));
  202. }
  203. else {
  204. return str_replace("\0", "_", $encoded);
  205. }
  206. } else {
  207. return str_replace("\0", "_", preg_replace("/[^[:ascii:]]/u","_",$fileName));
  208. }
  209. }
  210. $converted = @iconv("UTF-8", $encoding . "//IGNORE//TRANSLIT", $fileName);
  211. if ($converted === false) {
  212. return str_replace("\0", "_", preg_replace("/[^[:ascii:]]/u","_",$fileName));
  213. }
  214. return $converted;
  215. }
  216. /**
  217. * Convert file name from system encoding into UTF-8
  218. *
  219. * @static
  220. * @access public
  221. * @param string $fileName
  222. * @return string
  223. */
  224. public static function convertToConnectorEncoding($fileName)
  225. {
  226. $_config =& CKFinder_Connector_Core_Factory::getInstance("Core_Config");
  227. $encoding = $_config->getFilesystemEncoding();
  228. if (is_null($encoding) || strcasecmp($encoding, "UTF-8") == 0 || strcasecmp($encoding, "UTF8") == 0) {
  229. return $fileName;
  230. }
  231. if (!function_exists("iconv")) {
  232. if (strcasecmp($encoding, "ISO-8859-1") == 0 || strcasecmp($encoding, "ISO8859-1") == 0 || strcasecmp($encoding, "Latin1") == 0) {
  233. return utf8_encode($fileName);
  234. } else {
  235. return $fileName;
  236. }
  237. }
  238. $converted = @iconv($encoding, "UTF-8", $fileName);
  239. if ($converted === false) {
  240. return $fileName;
  241. }
  242. return $converted;
  243. }
  244. /**
  245. * Find document root
  246. *
  247. * @return string
  248. * @access public
  249. */
  250. public function getDocumentRootPath()
  251. {
  252. /**
  253. * The absolute pathname of the currently executing script.
  254. * Notatka: If a script is executed with the CLI, as a relative path, such as file.php or ../file.php,
  255. * $_SERVER['SCRIPT_FILENAME'] will contain the relative path specified by the user.
  256. */
  257. if (isset($_SERVER['SCRIPT_FILENAME'])) {
  258. $sRealPath = dirname($_SERVER['SCRIPT_FILENAME']);
  259. }
  260. else {
  261. /**
  262. * realpath — Returns canonicalized absolute pathname
  263. */
  264. $sRealPath = realpath( './' ) ;
  265. }
  266. /**
  267. * The filename of the currently executing script, relative to the document root.
  268. * For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar
  269. * would be /test.php/foo.bar.
  270. */
  271. $sSelfPath = dirname($_SERVER['PHP_SELF']);
  272. return substr($sRealPath, 0, strlen($sRealPath) - strlen($sSelfPath));
  273. }
  274. /**
  275. * Create directory recursively
  276. *
  277. * @access public
  278. * @static
  279. * @param string $dir
  280. * @return boolean
  281. */
  282. public static function createDirectoryRecursively($dir)
  283. {
  284. if (DIRECTORY_SEPARATOR === "\\") {
  285. $dir = str_replace("/", "\\", $dir);
  286. }
  287. else if (DIRECTORY_SEPARATOR === "/") {
  288. $dir = str_replace("\\", "/", $dir);
  289. }
  290. $_config =& CKFinder_Connector_Core_Factory::getInstance("Core_Config");
  291. if ($perms = $_config->getChmodFolders()) {
  292. $oldUmask = umask(0);
  293. $bCreated = @mkdir($dir, $perms, true);
  294. umask($oldUmask);
  295. }
  296. else {
  297. $bCreated = @mkdir($dir, 0777, true);
  298. }
  299. return $bCreated;
  300. }
  301. /**
  302. * Detect HTML in the first KB to prevent against potential security issue with
  303. * IE/Safari/Opera file type auto detection bug.
  304. * Returns true if file contain insecure HTML code at the beginning.
  305. *
  306. * @static
  307. * @access public
  308. * @param string $filePath absolute path to file
  309. * @return boolean
  310. */
  311. public static function detectHtml($filePath)
  312. {
  313. $fp = @fopen($filePath, 'rb');
  314. if ( $fp === false || !flock( $fp, LOCK_SH ) ) {
  315. return -1 ;
  316. }
  317. $chunk = fread($fp, 1024);
  318. flock( $fp, LOCK_UN ) ;
  319. fclose($fp);
  320. $chunk = strtolower($chunk);
  321. if (!$chunk) {
  322. return false;
  323. }
  324. $chunk = trim($chunk);
  325. if (preg_match("/<!DOCTYPE\W*X?HTML/sim", $chunk)) {
  326. return true;
  327. }
  328. $tags = array('<body', '<head', '<html', '<img', '<pre', '<script', '<table', '<title');
  329. foreach( $tags as $tag ) {
  330. if(false !== strpos($chunk, $tag)) {
  331. return true ;
  332. }
  333. }
  334. //type = javascript
  335. if (preg_match('!type\s*=\s*[\'"]?\s*(?:\w*/)?(?:ecma|java)!sim', $chunk)) {
  336. return true ;
  337. }
  338. //href = javascript
  339. //src = javascript
  340. //data = javascript
  341. if (preg_match('!(?:href|src|data)\s*=\s*[\'"]?\s*(?:ecma|java)script:!sim',$chunk)) {
  342. return true ;
  343. }
  344. //url(javascript
  345. if (preg_match('!url\s*\(\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk)) {
  346. return true ;
  347. }
  348. return false ;
  349. }
  350. /**
  351. * Check file content.
  352. * Currently this function validates only image files.
  353. * Returns false if file is invalid.
  354. *
  355. * @static
  356. * @access public
  357. * @param string $filePath absolute path to file
  358. * @param string $extension file extension
  359. * @param integer $detectionLevel 0 = none, 1 = use getimagesize for images, 2 = use DetectHtml for images
  360. * @return boolean
  361. */
  362. public static function isImageValid($filePath, $extension)
  363. {
  364. if (!@is_readable($filePath)) {
  365. return -1;
  366. }
  367. $imageCheckExtensions = array('gif', 'jpeg', 'jpg', 'png', 'psd', 'bmp', 'tiff');
  368. // version_compare is available since PHP4 >= 4.0.7
  369. if ( function_exists( 'version_compare' ) ) {
  370. $sCurrentVersion = phpversion();
  371. if ( version_compare( $sCurrentVersion, "4.2.0" ) >= 0 ) {
  372. $imageCheckExtensions[] = "tiff";
  373. $imageCheckExtensions[] = "tif";
  374. }
  375. if ( version_compare( $sCurrentVersion, "4.3.0" ) >= 0 ) {
  376. $imageCheckExtensions[] = "swc";
  377. }
  378. if ( version_compare( $sCurrentVersion, "4.3.2" ) >= 0 ) {
  379. $imageCheckExtensions[] = "jpc";
  380. $imageCheckExtensions[] = "jp2";
  381. $imageCheckExtensions[] = "jpx";
  382. $imageCheckExtensions[] = "jb2";
  383. $imageCheckExtensions[] = "xbm";
  384. $imageCheckExtensions[] = "wbmp";
  385. }
  386. }
  387. if ( !in_array( $extension, $imageCheckExtensions ) ) {
  388. return true;
  389. }
  390. if ( @getimagesize( $filePath ) === false ) {
  391. return false ;
  392. }
  393. return true;
  394. }
  395. /**
  396. * Returns true if directory is not empty
  397. *
  398. * @access public
  399. * @static
  400. * @param string $serverPath
  401. * @return boolean
  402. */
  403. public static function hasChildren($serverPath)
  404. {
  405. if (!is_dir($serverPath) || (false === $fh = @opendir($serverPath))) {
  406. return false;
  407. }
  408. $hasChildren = false;
  409. while (false !== ($filename = readdir($fh))) {
  410. if ($filename == '.' || $filename == '..') {
  411. continue;
  412. } else if (is_dir($serverPath . DIRECTORY_SEPARATOR . $filename)) {
  413. //we have found valid directory
  414. $hasChildren = true;
  415. break;
  416. }
  417. }
  418. closedir($fh);
  419. return $hasChildren;
  420. }
  421. }