PageRenderTime 91ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/app/code/core/Mage/Core/Model/File/Validator/AvailablePath.php

https://gitlab.com/LisovyiEvhenii/ismextensions
PHP | 324 lines | 168 code | 23 blank | 133 comment | 27 complexity | 45f0f713d4280835f44ab663d1644d4c MD5 | raw file
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magento.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magento.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Core
  23. * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Validator for check not protected/available path
  28. *
  29. * Mask symbols from path:
  30. * "?" - something directory with any name
  31. * "*" - something directory structure, which can not exist
  32. * Note: For set directory structure which must be exist, need to set mask "/?/{@*}"
  33. * Mask symbols from filename:
  34. * "*" - something symbols in file name
  35. * Example:
  36. * <code>
  37. * //set available path
  38. * $validator->setAvailablePath(array('/path/to/?/*fileMask.xml'));
  39. * $validator->isValid('/path/to/MyDir/Some-fileMask.xml'); //return true
  40. * $validator->setAvailablePath(array('/path/to/{@*}*.xml'));
  41. * $validator->isValid('/path/to/my.xml'); //return true, because directory structure can't exist
  42. * </code>
  43. *
  44. * @category Mage
  45. * @package Mage_Core
  46. * @author Magento Core Team <core@magentocommerce.com>
  47. */
  48. class Mage_Core_Model_File_Validator_AvailablePath extends Zend_Validate_Abstract
  49. {
  50. const PROTECTED_PATH = 'protectedPath';
  51. const NOT_AVAILABLE_PATH = 'notAvailablePath';
  52. const PROTECTED_LFI = 'protectedLfi';
  53. /**
  54. * The path
  55. *
  56. * @var string
  57. */
  58. protected $_value;
  59. /**
  60. * Protected paths
  61. *
  62. * @var array
  63. */
  64. protected $_protectedPaths = array();
  65. /**
  66. * Available paths
  67. *
  68. * @var array
  69. */
  70. protected $_availablePaths = array();
  71. /**
  72. * Cache of made regular expressions from path masks
  73. *
  74. * @var array
  75. */
  76. protected $_pathsData;
  77. /**
  78. * Construct
  79. */
  80. public function __construct()
  81. {
  82. $this->_initMessageTemplates();
  83. }
  84. /**
  85. * Initialize message templates with translating
  86. *
  87. * @return Mage_Adminhtml_Model_Core_File_Validator_SavePath_Available
  88. */
  89. protected function _initMessageTemplates()
  90. {
  91. if (!$this->_messageTemplates) {
  92. $this->_messageTemplates = array(
  93. self::PROTECTED_PATH =>
  94. Mage::helper('core')->__('Path "%value%" is protected and cannot be used.'),
  95. self::NOT_AVAILABLE_PATH =>
  96. Mage::helper('core')->__('Path "%value%" is not available and cannot be used.'),
  97. self::PROTECTED_LFI =>
  98. Mage::helper('core')->__('Path "%value%" may not include parent directory traversal ("../", "..\\").'),
  99. );
  100. }
  101. return $this;
  102. }
  103. /**
  104. * Set paths masks
  105. *
  106. * @param array $paths All paths masks types.
  107. * E.g.: array('available' => array(...), 'protected' => array(...))
  108. * @return Mage_Adminhtml_Model_Core_File_Validator_SavePath_Available
  109. */
  110. public function setPaths(array $paths)
  111. {
  112. if (isset($paths['available']) && is_array($paths['available'])) {
  113. $this->_availablePaths = $paths['available'];
  114. }
  115. if (isset($paths['protected']) && is_array($paths['protected'])) {
  116. $this->_protectedPaths = $paths['protected'];
  117. }
  118. return $this;
  119. }
  120. /**
  121. * Set protected paths masks
  122. *
  123. * @param array $paths
  124. * @return Mage_Adminhtml_Model_Core_File_Validator_SavePath_Available
  125. */
  126. public function setProtectedPaths(array $paths)
  127. {
  128. $this->_protectedPaths = $paths;
  129. return $this;
  130. }
  131. /**
  132. * Add protected paths masks
  133. *
  134. * @param string|array $path
  135. * @return Mage_Adminhtml_Model_Core_File_Validator_SavePath_Available
  136. */
  137. public function addProtectedPath($path)
  138. {
  139. if (is_array($path)) {
  140. $this->_protectedPaths = array_merge($this->_protectedPaths, $path);
  141. } else {
  142. $this->_protectedPaths[] = $path;
  143. }
  144. return $this;
  145. }
  146. /**
  147. * Get protected paths masks
  148. *
  149. * @return array
  150. */
  151. public function getProtectedPaths()
  152. {
  153. return $this->_protectedPaths;
  154. }
  155. /**
  156. * Set available paths masks
  157. *
  158. * @param array $paths
  159. * @return Mage_Adminhtml_Model_Core_File_Validator_SavePath_Available
  160. */
  161. public function setAvailablePaths(array $paths)
  162. {
  163. $this->_availablePaths = $paths;
  164. return $this;
  165. }
  166. /**
  167. * Add available paths mask
  168. *
  169. * @param string|array $path
  170. * @return Mage_Adminhtml_Model_Core_File_Validator_SavePath_Available
  171. */
  172. public function addAvailablePath($path)
  173. {
  174. if (is_array($path)) {
  175. $this->_availablePaths = array_merge($this->_availablePaths, $path);
  176. } else {
  177. $this->_availablePaths[] = $path;
  178. }
  179. return $this;
  180. }
  181. /**
  182. * Get available paths masks
  183. *
  184. * @return array
  185. */
  186. public function getAvailablePaths()
  187. {
  188. return $this->_availablePaths;
  189. }
  190. /**
  191. * Returns true if and only if $value meets the validation requirements
  192. *
  193. * If $value fails validation, then this method returns false, and
  194. * getMessages() will return an array of messages that explain why the
  195. * validation failed.
  196. *
  197. * @throws Exception Throw exception on empty both paths masks types
  198. * @param string $value File/dir path
  199. * @return bool
  200. */
  201. public function isValid($value)
  202. {
  203. $value = trim($value);
  204. $this->_setValue($value);
  205. if (!$this->_availablePaths && !$this->_protectedPaths) {
  206. throw new Exception(Mage::helper('core')->__('Please set available and/or protected paths list(s) before validation.'));
  207. }
  208. if (preg_match('#\.\.[\\\/]#', $this->_value)) {
  209. $this->_error(self::PROTECTED_LFI, $this->_value);
  210. return false;
  211. }
  212. //validation
  213. $value = str_replace(array('/', '\\'), DS, $this->_value);
  214. $valuePathInfo = pathinfo(ltrim($value, '\\/'));
  215. if ($valuePathInfo['dirname'] == '.' || $valuePathInfo['dirname'] == DS) {
  216. $valuePathInfo['dirname'] = '';
  217. }
  218. if ($this->_protectedPaths && !$this->_isValidByPaths($valuePathInfo, $this->_protectedPaths, true)) {
  219. $this->_error(self::PROTECTED_PATH, $this->_value);
  220. return false;
  221. }
  222. if ($this->_availablePaths && !$this->_isValidByPaths($valuePathInfo, $this->_availablePaths, false)) {
  223. $this->_error(self::NOT_AVAILABLE_PATH, $this->_value);
  224. return false;
  225. }
  226. return true;
  227. }
  228. /**
  229. * Validate value by path masks
  230. *
  231. * @param array $valuePathInfo Path info from value path
  232. * @param array $paths Protected/available paths masks
  233. * @param bool $protected Paths masks is protected?
  234. * @return bool
  235. */
  236. protected function _isValidByPaths($valuePathInfo, $paths, $protected)
  237. {
  238. foreach ($paths as $path) {
  239. $path = ltrim($path, '\\/');
  240. if (!isset($this->_pathsData[$path]['regFilename'])) {
  241. $pathInfo = pathinfo($path);
  242. $options['file_mask'] = $pathInfo['basename'];
  243. if ($pathInfo['dirname'] == '.' || $pathInfo['dirname'] == DS) {
  244. $pathInfo['dirname'] = '';
  245. } else {
  246. $pathInfo['dirname'] = str_replace(array('/', '\\'), DS, $pathInfo['dirname']);
  247. }
  248. $options['dir_mask'] = $pathInfo['dirname'];
  249. $this->_pathsData[$path]['options'] = $options;
  250. } else {
  251. $options = $this->_pathsData[$path]['options'];
  252. }
  253. //file mask
  254. if (false !== (strpos($options['file_mask'], '*'))) {
  255. if (!isset($this->_pathsData[$path]['regFilename'])) {
  256. //make regular
  257. $reg = $options['file_mask'];
  258. $reg = str_replace('.', '\.', $reg);
  259. $reg = str_replace('*', '.*?', $reg);
  260. $reg = "/^($reg)$/";
  261. } else {
  262. $reg = $this->_pathsData[$path]['regFilename'];
  263. }
  264. $resultFile = preg_match($reg, $valuePathInfo['basename']);
  265. } else {
  266. $resultFile = ($options['file_mask'] == $valuePathInfo['basename']);
  267. }
  268. //directory mask
  269. $reg = $options['dir_mask'] . DS;
  270. if (!isset($this->_pathsData[$path]['regDir'])) {
  271. //make regular
  272. $reg = str_replace('.', '\.', $reg);
  273. $reg = str_replace('*\\', '||', $reg);
  274. $reg = str_replace('*/', '||', $reg);
  275. //$reg = str_replace('*', '||', $reg);
  276. $reg = str_replace(DS, '[\\' . DS . ']', $reg);
  277. $reg = str_replace('?', '([^\\' . DS . ']+)', $reg);
  278. $reg = str_replace('||', '(.*[\\' . DS . '])?', $reg);
  279. $reg = "/^$reg$/";
  280. } else {
  281. $reg = $this->_pathsData[$path]['regDir'];
  282. }
  283. $resultDir = preg_match($reg, $valuePathInfo['dirname'] . DS);
  284. if ($protected && ($resultDir && $resultFile)) {
  285. return false;
  286. } elseif (!$protected && ($resultDir && $resultFile)) {
  287. //return true because one match with available path mask
  288. return true;
  289. }
  290. }
  291. if ($protected) {
  292. return true;
  293. } else {
  294. //return false because no one match with available path mask
  295. return false;
  296. }
  297. }
  298. }