PageRenderTime 26ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/include/classes/Request.class.php

https://bitbucket.org/webinfopro/sqlitemanager
PHP | 567 lines | 451 code | 94 blank | 22 comment | 79 complexity | 434043e8f86979e78bcd3e3f591b3742 MD5 | raw file
  1. <?php
  2. /**
  3. * Web based SQLite management
  4. * Request input filter
  5. *
  6. * @method integer getInt() getInt($name, $default) Get a signed integer.
  7. * @method integer getUint() getUint($name, $default) Get an unsigned integer.
  8. * @method float getFloat() getFloat($name, $default) Get a floating-point number.
  9. * @method boolean getBool() getBool($name, $default) Get a boolean.
  10. * @method string getWord() getWord($name, $default)
  11. * @method string getAlnum() getAlnum($name, $default)
  12. * @method string getCmd() getCmd($name, $default)
  13. * @method string getBase64() getBase64($name, $default)
  14. * @method string getString() getString($name, $default)
  15. * @method string getHtml() getHtml($name, $default)
  16. *
  17. * @package SQLiteManager
  18. * @author Frédéric HENNINOT
  19. * @version $Id: SQLite.i18n.php,v 1.25 2006/04/14 15:16:52 freddy78 Exp $ $Revision: 1.25 $
  20. */
  21. class Request extends ArrayIterator
  22. {
  23. protected $data = array();
  24. public $tagBlacklist = array(
  25. 'applet',
  26. 'body',
  27. 'bgsound',
  28. 'base',
  29. 'basefont',
  30. 'embed',
  31. 'frame',
  32. 'frameset',
  33. 'head',
  34. 'html',
  35. 'id',
  36. 'iframe',
  37. 'ilayer',
  38. 'layer',
  39. 'link',
  40. 'meta',
  41. 'name',
  42. 'object',
  43. 'script',
  44. 'style',
  45. 'title',
  46. 'xml'
  47. );
  48. public $attrBlacklist = array(
  49. 'action',
  50. 'background',
  51. 'codebase',
  52. 'dynsrc',
  53. 'lowsrc'
  54. );
  55. public function __construct($source = null)
  56. {
  57. if (is_null($source) || !isset($source))
  58. {
  59. $this->data = & $_REQUEST;
  60. }
  61. else
  62. {
  63. $this->data = & $source;
  64. }
  65. parent::__construct($this->data);
  66. }
  67. public static function getInstance($source='default') {
  68. static $request = array();
  69. $source = strtoupper('_'.$source);
  70. if(!isset($request[$source])) {
  71. switch($source) {
  72. case '_POST':
  73. $sourceVar =& $_POST;
  74. break;
  75. case '_GET':
  76. $sourceVar =& $_GET;
  77. break;
  78. case '_COOKIE':
  79. $sourceVar =& $_COOKIE;
  80. break;
  81. case '_SERVER':
  82. $sourceVar =& $_SERVER;
  83. break;
  84. case '_ENV':
  85. $sourceVar =& $_ENV;
  86. break;
  87. default:
  88. $sourceVar = $_REQUEST;
  89. break;
  90. }
  91. $request[$source] = new Request($sourceVar);
  92. }
  93. return $request[$source];
  94. }
  95. public function get($name, $default = null, $filter = 'string')
  96. {
  97. if (isset($this->data[$name]))
  98. return $this->clean($this->data[$name], $filter);
  99. return $default;
  100. }
  101. public function set($name, $value)
  102. {
  103. $this->data[$name] = $value;
  104. parent::offsetSet($name, $value);
  105. }
  106. public function setDateFormat($format)
  107. {
  108. $this->dateFormat = $format;
  109. }
  110. public function exists($name)
  111. {
  112. if (isset($this->data[$name]))
  113. return true;
  114. return false;
  115. }
  116. public function def($name, $value)
  117. {
  118. if (isset($this->data[$name]))
  119. return;
  120. $this->data[$name] = $value;
  121. parent::offsetSet($name, $value);
  122. }
  123. public function getHash($source, $type='string')
  124. {
  125. if(is_array($source))
  126. foreach($source as $k=>$v)
  127. $source[$k] = $this->clean($v, $type);
  128. return $source;
  129. }
  130. public function offsetGet($name) {
  131. return $this->get($name);
  132. }
  133. public function clean($source, $type = 'string')
  134. {
  135. switch (strtoupper($type))
  136. {
  137. case 'INT':
  138. case 'INTEGER':
  139. preg_match('/-?[0-9]+/', (string) $source, $matches);
  140. $result = @ (int) $matches[0];
  141. break;
  142. case 'UINT':
  143. preg_match('/-?[0-9]+/', (string) $source, $matches);
  144. $result = @ abs((int) $matches[0]);
  145. break;
  146. case 'FLOAT':
  147. case 'DOUBLE':
  148. preg_match('/-?[0-9]+(\.[0-9]+)?/', (string) $source, $matches);
  149. $result = @ (float) $matches[0];
  150. break;
  151. case 'BOOL':
  152. case 'BOOLEAN':
  153. $result = (bool) $source;
  154. break;
  155. case 'WORD':
  156. $result = (string) preg_replace('/[^A-Z_]/i', '', $source);
  157. break;
  158. case 'ALNUM':
  159. $result = (string) preg_replace('/[^A-Z0-9]/i', '', $source);
  160. break;
  161. case 'CMD':
  162. $result = (string) preg_replace('/[^A-Z0-9_\.-]/i', '', $source);
  163. $result = ltrim($result, '.');
  164. break;
  165. case 'BASE64':
  166. $result = (string) preg_replace('/[^A-Z0-9\/+=]/i', '', $source);
  167. break;
  168. case 'STRING':
  169. $result = (string) $this->_remove($this->_decode((string) $source));
  170. break;
  171. case 'RAW':
  172. $result = (string)$source;
  173. break;
  174. case 'ARRAY':
  175. $result = (array) $source;
  176. break;
  177. default:
  178. if (is_array($source))
  179. {
  180. foreach ($source as $key => $value)
  181. {
  182. if (is_string($value))
  183. {
  184. $source[$key] = $this->_remove($this->_decode($value));
  185. }
  186. }
  187. $result = $source;
  188. }
  189. else
  190. {
  191. if (is_string($source) && !empty($source))
  192. {
  193. $result = $this->_remove($this->_decode($source));
  194. }
  195. else
  196. {
  197. // Not an array or string.. return the passed parameter
  198. $result = $source;
  199. }
  200. }
  201. break;
  202. }
  203. return $result;
  204. }
  205. protected function _decode($source)
  206. {
  207. static $ttr;
  208. if (!is_array($ttr))
  209. {
  210. $trans_tbl = get_html_translation_table(HTML_ENTITIES);
  211. foreach ($trans_tbl as $k => $v)
  212. {
  213. $ttr[$v] = utf8_encode($k);
  214. }
  215. }
  216. $source = strtr($source, $ttr);
  217. // Convert decimal
  218. $source = preg_replace('/&#(\d+);/me', "utf8_encode(chr(\\1))", $source); // decimal notation
  219. // Convert hex
  220. $source = preg_replace('/&#x([a-f0-9]+);/mei', "utf8_encode(chr(0x\\1))", $source); // hex notation
  221. return $source;
  222. }
  223. protected function _remove($source)
  224. {
  225. while ($source != $this->_cleanTags($source))
  226. $source = $this->_cleanTags($source);
  227. return $source;
  228. }
  229. public static function checkAttribute($attrSubSet)
  230. {
  231. $attrSubSet[0] = strtolower($attrSubSet[0]);
  232. $attrSubSet[1] = strtolower($attrSubSet[1]);
  233. return (((strpos($attrSubSet[1], 'expression') !== false) && ($attrSubSet[0]) == 'style') || (strpos($attrSubSet[1], 'javascript:') !== false) ||
  234. (strpos($attrSubSet[1], 'behaviour:') !== false) || (strpos($attrSubSet[1], 'vbscript:') !== false) ||
  235. (strpos($attrSubSet[1], 'mocha:') !== false) || (strpos($attrSubSet[1], 'livescript:') !== false));
  236. }
  237. protected function _cleanTags($source)
  238. {
  239. $source = $this->_escapeAttributeValues($source);
  240. $preTag = null;
  241. $postTag = $source;
  242. $currentSpace = false;
  243. $attr = '';
  244. $tagOpen_start = strpos($source, '<');
  245. while ($tagOpen_start !== false)
  246. {
  247. $preTag .= substr($postTag, 0, $tagOpen_start);
  248. $postTag = substr($postTag, $tagOpen_start);
  249. $fromTagOpen = substr($postTag, 1);
  250. $tagOpen_end = strpos($fromTagOpen, '>');
  251. $nextOpenTag = (strlen($postTag) > $tagOpen_start) ? strpos($postTag, '<', $tagOpen_start + 1) : false;
  252. if (($nextOpenTag !== false) && ($nextOpenTag < $tagOpen_end))
  253. {
  254. $postTag = substr($postTag, 0, $tagOpen_start) . substr($postTag, $tagOpen_start + 1);
  255. $tagOpen_start = strpos($postTag, '<');
  256. continue;
  257. }
  258. if ($tagOpen_end === false)
  259. {
  260. $postTag = substr($postTag, $tagOpen_start + 1);
  261. $tagOpen_start = strpos($postTag, '<');
  262. continue;
  263. }
  264. $tagOpen_nested = strpos($fromTagOpen, '<');
  265. $tagOpen_nested_end = strpos(substr($postTag, $tagOpen_end), '>');
  266. if (($tagOpen_nested !== false) && ($tagOpen_nested < $tagOpen_end))
  267. {
  268. $preTag .= substr($postTag, 0, ($tagOpen_nested + 1));
  269. $postTag = substr($postTag, ($tagOpen_nested + 1));
  270. $tagOpen_start = strpos($postTag, '<');
  271. continue;
  272. }
  273. $tagOpen_nested = (strpos($fromTagOpen, '<') + $tagOpen_start + 1);
  274. $currentTag = substr($fromTagOpen, 0, $tagOpen_end);
  275. $tagLength = strlen($currentTag);
  276. $tagLeft = $currentTag;
  277. $attrSet = array();
  278. $currentSpace = strpos($tagLeft, ' ');
  279. if (substr($currentTag, 0, 1) == '/')
  280. {
  281. $isCloseTag = true;
  282. list ($tagName) = explode(' ', $currentTag);
  283. $tagName = substr($tagName, 1);
  284. }
  285. else
  286. {
  287. $isCloseTag = false;
  288. list ($tagName) = explode(' ', $currentTag);
  289. }
  290. if ( !preg_match("/^[a-z][a-z0-9]*$/i", $tagName) || !$tagName || in_array(strtolower($tagName), $this->tagBlacklist))
  291. {
  292. $postTag = substr($postTag, ($tagLength + 2));
  293. $tagOpen_start = strpos($postTag, '<');
  294. continue;
  295. }
  296. while ($currentSpace !== false)
  297. {
  298. $attr = '';
  299. $fromSpace = substr($tagLeft, ($currentSpace + 1));
  300. $nextEqual = strpos($fromSpace, '=');
  301. $nextSpace = strpos($fromSpace, ' ');
  302. $openQuotes = strpos($fromSpace, '"');
  303. $closeQuotes = strpos(substr($fromSpace, ($openQuotes + 1)), '"') + $openQuotes + 1;
  304. $startAtt = '';
  305. $startAttPosition = 0;
  306. if (preg_match('#\s*=\s*\"#', $fromSpace, $matches, PREG_OFFSET_CAPTURE))
  307. {
  308. $startAtt = $matches[0][0];
  309. $startAttPosition = $matches[0][1];
  310. $closeQuotes = strpos(substr($fromSpace, ($startAttPosition + strlen($startAtt))), '"') + $startAttPosition + strlen($startAtt);
  311. $nextEqual = $startAttPosition + strpos($startAtt, '=');
  312. $openQuotes = $startAttPosition + strpos($startAtt, '"');
  313. $nextSpace = strpos(substr($fromSpace, $closeQuotes), ' ') + $closeQuotes;
  314. }
  315. if ($fromSpace != '/' && (($nextEqual && $nextSpace && $nextSpace < $nextEqual) || !$nextEqual))
  316. {
  317. if (!$nextEqual)
  318. $attribEnd = strpos($fromSpace, '/') - 1;
  319. else
  320. $attribEnd = $nextSpace - 1;
  321. if ($attribEnd > 0)
  322. $fromSpace = substr($fromSpace, $attribEnd + 1);
  323. }
  324. if (strpos($fromSpace, '=') !== false)
  325. {
  326. if (($openQuotes !== false) && (strpos(substr($fromSpace, ($openQuotes + 1)), '"') !== false))
  327. $attr = substr($fromSpace, 0, ($closeQuotes + 1));
  328. else
  329. $attr = substr($fromSpace, 0, $nextSpace);
  330. }
  331. else
  332. {
  333. if ($fromSpace != '/')
  334. $attr = substr($fromSpace, 0, $nextSpace);
  335. }
  336. if (!$attr && $fromSpace != '/')
  337. $attr = $fromSpace;
  338. $attrSet[] = $attr;
  339. $tagLeft = substr($fromSpace, strlen($attr));
  340. $currentSpace = strpos($tagLeft, ' ');
  341. }
  342. $preTag .= '</' . $tagName . '>';
  343. $postTag = substr($postTag, ($tagLength + 2));
  344. $tagOpen_start = strpos($postTag, '<');
  345. }
  346. if ($postTag != '<')
  347. $preTag .= $postTag;
  348. return $preTag;
  349. }
  350. protected function _cleanAttributes($attrSet)
  351. {
  352. $newSet = array();
  353. $count = count($attrSet);
  354. for ($i = 0; $i < $count; $i++)
  355. {
  356. if (!$attrSet[$i])
  357. continue;
  358. $attrSubSet = explode('=', trim($attrSet[$i]), 2);
  359. $attrSubSet[0] = array_pop(explode(' ', trim($attrSubSet[0])));
  360. if ((!preg_match('/[a-z]*$/i', $attrSubSet[0]))
  361. || (($this->xssAuto) && ((in_array(strtolower($attrSubSet[0]), $this->attrBlacklist))
  362. || (substr($attrSubSet[0], 0, 2) == 'on'))))
  363. {
  364. continue;
  365. }
  366. if (isset($attrSubSet[1]))
  367. {
  368. $attrSubSet[1] = trim($attrSubSet[1]);
  369. $attrSubSet[1] = str_replace('&#', '', $attrSubSet[1]);
  370. $attrSubSet[1] = preg_replace('/[\n\r]/', '', $attrSubSet[1]);
  371. $attrSubSet[1] = str_replace('"', '', $attrSubSet[1]);
  372. if ((substr($attrSubSet[1], 0, 1) == "'") && (substr($attrSubSet[1], (strlen($attrSubSet[1]) - 1), 1) == "'"))
  373. {
  374. $attrSubSet[1] = substr($attrSubSet[1], 1, (strlen($attrSubSet[1]) - 2));
  375. }
  376. $attrSubSet[1] = stripslashes($attrSubSet[1]);
  377. }
  378. else
  379. {
  380. continue;
  381. }
  382. if (self::checkAttribute($attrSubSet))
  383. continue;
  384. $attrFound = in_array(strtolower($attrSubSet[0]), $this->attrArray);
  385. if ((!$attrFound && $this->attrMethod) || ($attrFound && !$this->attrMethod))
  386. {
  387. if (empty($attrSubSet[1]) === false)
  388. {
  389. $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[1] . '"';
  390. }
  391. elseif ($attrSubSet[1] === "0")
  392. {
  393. $newSet[] = $attrSubSet[0] . '="0"';
  394. }
  395. else
  396. {
  397. $newSet[] = $attrSubSet[0] . '=""';
  398. }
  399. }
  400. }
  401. return $newSet;
  402. }
  403. protected function _escapeAttributeValues($source)
  404. {
  405. $alreadyFiltered = '';
  406. $remainder = $source;
  407. $badChars = array('<', '"', '>');
  408. $escapedChars = array('&lt;', '&quot;', '&gt;');
  409. while (preg_match('#<[^>]*?=\s*?(\"|\')#s', $remainder, $matches, PREG_OFFSET_CAPTURE))
  410. {
  411. $quotePosition = $matches[0][1];
  412. $nextBefore = $quotePosition + strlen($matches[0][0]);
  413. $quote = substr($matches[0][0], -1);
  414. $pregMatch = ($quote == '"') ? '#(\"\s*/\s*>|\"\s*>|\"\s+|\"$)#' : "#(\'\s*/\s*>|\'\s*>|\'\s+|\'$)#";
  415. if (preg_match($pregMatch, substr($remainder, $nextBefore), $matches, PREG_OFFSET_CAPTURE))
  416. $nextAfter = $nextBefore + $matches[0][1];
  417. else
  418. $nextAfter = strlen($remainder);
  419. $attributeValue = substr($remainder, $nextBefore, $nextAfter - $nextBefore);
  420. $attributeValue = str_replace($badChars, $escapedChars, $attributeValue);
  421. $attributeValue = $this->_stripCSSExpressions($attributeValue);
  422. $alreadyFiltered .= substr($remainder, 0, $nextBefore) . $attributeValue . $quote;
  423. $remainder = substr($remainder, $nextAfter + 1);
  424. }
  425. return $alreadyFiltered . $remainder;
  426. }
  427. protected function _stripCSSExpressions($source)
  428. {
  429. $test = preg_replace('#\/\*.*\*\/#U', '', $source);
  430. if (!stripos($test, ':expression'))
  431. {
  432. $return = $source;
  433. }
  434. else
  435. {
  436. if (preg_match_all('#:expression\s*\(#', $test, $matches))
  437. {
  438. $test = str_ireplace(':expression', '', $test);
  439. $return = $test;
  440. }
  441. }
  442. return $return;
  443. }
  444. public function __call($name, $arguments)
  445. {
  446. if (substr($name, 0, 3) == 'get')
  447. {
  448. $filter = substr($name, 3);
  449. $default = null;
  450. if (isset($arguments[1]))
  451. $default = $arguments[1];
  452. return $this->get($arguments[0], $default, $filter);
  453. }
  454. }
  455. public static function __callstatic($name, $arguments)
  456. {
  457. if (substr($name, 0, 3) == 'get')
  458. {
  459. $filter = substr($name, 3);
  460. $default = null;
  461. if (isset($arguments[1]))
  462. $default = $arguments[1];
  463. $source = 'default';
  464. if(isset($arguments[2]))
  465. $source = $arguments[2];
  466. $request = Request::getInstance($source);
  467. return $request->get($arguments[0], $default, $filter);
  468. }
  469. }
  470. public function __get($source) {
  471. return $this->get($source);
  472. }
  473. }