PageRenderTime 46ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/libraries/joomla/environment/request.php

https://github.com/joebushi/joomla
PHP | 580 lines | 285 code | 52 blank | 243 comment | 39 complexity | f7403d2138040258439768ae920ac2c9 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. <?php
  2. /**
  3. * @version $Id$
  4. * @package Joomla.Framework
  5. * @subpackage Environment
  6. * @copyright Copyright (C) 2005 - 2010 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE.txt
  8. */
  9. // No direct access
  10. defined('JPATH_BASE') or die;
  11. /**
  12. * Create the request global object
  13. */
  14. $GLOBALS['_JREQUEST'] = array();
  15. /**
  16. * Set the available masks for cleaning variables
  17. */
  18. define('JREQUEST_NOTRIM' , 1);
  19. define('JREQUEST_ALLOWRAW' , 2);
  20. define('JREQUEST_ALLOWHTML', 4);
  21. /**
  22. * JRequest Class
  23. *
  24. * This class serves to provide the Joomla Framework with a common interface to access
  25. * request variables. This includes $_POST, $_GET, and naturally $_REQUEST. Variables
  26. * can be passed through an input filter to avoid injection or returned raw.
  27. *
  28. * @static
  29. * @package Joomla.Framework
  30. * @subpackage Environment
  31. * @since 1.5
  32. */
  33. class JRequest
  34. {
  35. /**
  36. * Gets the full request path.
  37. *
  38. * @return string
  39. */
  40. public static function getURI()
  41. {
  42. $uri = &JFactory::getURI();
  43. return $uri->toString(array('path', 'query'));
  44. }
  45. /**
  46. * Gets the request method.
  47. *
  48. * @return string
  49. */
  50. public static function getMethod()
  51. {
  52. $method = strtoupper($_SERVER['REQUEST_METHOD']);
  53. return $method;
  54. }
  55. /**
  56. * Fetches and returns a given variable.
  57. *
  58. * The default behaviour is fetching variables depending on the
  59. * current request method: GET and HEAD will result in returning
  60. * an entry from $_GET, POST and PUT will result in returning an
  61. * entry from $_POST.
  62. *
  63. * You can force the source by setting the $hash parameter:
  64. *
  65. * post $_POST
  66. * get $_GET
  67. * files $_FILES
  68. * cookie $_COOKIE
  69. * env $_ENV
  70. * server $_SERVER
  71. * method via current $_SERVER['REQUEST_METHOD']
  72. * default $_REQUEST
  73. *
  74. * @param string $name Variable name.
  75. * @param string $default Default value if the variable does not exist.
  76. * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD).
  77. * @param string $type Return type for the variable, for valid values see {@link JFilterInput::clean()}.
  78. * @param int $mask Filter mask for the variable.
  79. * @return mixed Requested variable.
  80. * @since 1.5
  81. */
  82. public static function getVar($name, $default = null, $hash = 'default', $type = 'none', $mask = 0)
  83. {
  84. // Ensure hash and type are uppercase
  85. $hash = strtoupper($hash);
  86. if ($hash === 'METHOD') {
  87. $hash = strtoupper($_SERVER['REQUEST_METHOD']);
  88. }
  89. $type = strtoupper($type);
  90. $sig = $hash.$type.$mask;
  91. // Get the input hash
  92. switch ($hash)
  93. {
  94. case 'GET' :
  95. $input = &$_GET;
  96. break;
  97. case 'POST' :
  98. $input = &$_POST;
  99. break;
  100. case 'FILES' :
  101. $input = &$_FILES;
  102. break;
  103. case 'COOKIE' :
  104. $input = &$_COOKIE;
  105. break;
  106. case 'ENV' :
  107. $input = &$_ENV;
  108. break;
  109. case 'SERVER' :
  110. $input = &$_SERVER;
  111. break;
  112. default:
  113. $input = &$_REQUEST;
  114. $hash = 'REQUEST';
  115. break;
  116. }
  117. if (isset($GLOBALS['_JREQUEST'][$name]['SET.'.$hash]) && ($GLOBALS['_JREQUEST'][$name]['SET.'.$hash] === true)) {
  118. // Get the variable from the input hash
  119. $var = (isset($input[$name]) && $input[$name] !== null) ? $input[$name] : $default;
  120. $var = self::_cleanVar($var, $mask, $type);
  121. }
  122. elseif (!isset($GLOBALS['_JREQUEST'][$name][$sig]))
  123. {
  124. if (isset($input[$name]) && $input[$name] !== null) {
  125. // Get the variable from the input hash and clean it
  126. $var = self::_cleanVar($input[$name], $mask, $type);
  127. // Handle magic quotes compatability
  128. if (get_magic_quotes_gpc() && ($var != $default) && ($hash != 'FILES')) {
  129. $var = self::_stripSlashesRecursive($var);
  130. }
  131. $GLOBALS['_JREQUEST'][$name][$sig] = $var;
  132. }
  133. elseif ($default !== null) {
  134. // Clean the default value
  135. $var = self::_cleanVar($default, $mask, $type);
  136. }
  137. else {
  138. $var = $default;
  139. }
  140. } else {
  141. $var = $GLOBALS['_JREQUEST'][$name][$sig];
  142. }
  143. return $var;
  144. }
  145. /**
  146. * Fetches and returns a given filtered variable. The integer
  147. * filter will allow only digits to be returned. This is currently
  148. * only a proxy function for getVar().
  149. *
  150. * See getVar() for more in-depth documentation on the parameters.
  151. *
  152. * @param string $name Variable name.
  153. * @param string $default Default value if the variable does not exist.
  154. * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD).
  155. * @return integer Requested variable.
  156. * @since 1.5
  157. */
  158. public static function getInt($name, $default = 0, $hash = 'default')
  159. {
  160. return self::getVar($name, $default, $hash, 'int');
  161. }
  162. /**
  163. * Fetches and returns a given filtered variable. The float
  164. * filter only allows digits and periods. This is currently
  165. * only a proxy function for getVar().
  166. *
  167. * See getVar() for more in-depth documentation on the parameters.
  168. *
  169. * @param string $name Variable name.
  170. * @param string $default Default value if the variable does not exist.
  171. * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD).
  172. * @return float Requested variable.
  173. * @since 1.5
  174. */
  175. public static function getFloat($name, $default = 0.0, $hash = 'default')
  176. {
  177. return self::getVar($name, $default, $hash, 'float');
  178. }
  179. /**
  180. * Fetches and returns a given filtered variable. The bool
  181. * filter will only return true/false bool values. This is
  182. * currently only a proxy function for getVar().
  183. *
  184. * See getVar() for more in-depth documentation on the parameters.
  185. *
  186. * @param string $name Variable name.
  187. * @param string $default Default value if the variable does not exist.
  188. * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD).
  189. * @return bool Requested variable.
  190. * @since 1.5
  191. */
  192. public static function getBool($name, $default = false, $hash = 'default')
  193. {
  194. return self::getVar($name, $default, $hash, 'bool');
  195. }
  196. /**
  197. * Fetches and returns a given filtered variable. The word
  198. * filter only allows the characters [A-Za-z_]. This is currently
  199. * only a proxy function for getVar().
  200. *
  201. * See getVar() for more in-depth documentation on the parameters.
  202. *
  203. * @param string $name Variable name.
  204. * @param string $default Default value if the variable does not exist.
  205. * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD).
  206. * @return string Requested variable.
  207. * @since 1.5
  208. */
  209. public static function getWord($name, $default = '', $hash = 'default')
  210. {
  211. return self::getVar($name, $default, $hash, 'word');
  212. }
  213. /**
  214. * Fetches and returns a given filtered variable. The cmd
  215. * filter only allows the characters [A-Za-z0-9.-_]. This is
  216. * currently only a proxy function for getVar().
  217. *
  218. * See getVar() for more in-depth documentation on the parameters.
  219. *
  220. * @param string $name Variable name
  221. * @param string $default Default value if the variable does not exist
  222. * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
  223. * @return string Requested variable
  224. * @since 1.5
  225. */
  226. public static function getCmd($name, $default = '', $hash = 'default')
  227. {
  228. return self::getVar($name, $default, $hash, 'cmd');
  229. }
  230. /**
  231. * Fetches and returns a given filtered variable. The string
  232. * filter deletes 'bad' HTML code, if not overridden by the mask.
  233. * This is currently only a proxy function for getVar().
  234. *
  235. * See getVar() for more in-depth documentation on the parameters.
  236. *
  237. * @param string $name Variable name
  238. * @param string $default Default value if the variable does not exist
  239. * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
  240. * @param int $mask Filter mask for the variable
  241. * @return string Requested variable
  242. * @since 1.5
  243. */
  244. public static function getString($name, $default = '', $hash = 'default', $mask = 0)
  245. {
  246. // Cast to string, in case JREQUEST_ALLOWRAW was specified for mask
  247. return (string) self::getVar($name, $default, $hash, 'string', $mask);
  248. }
  249. /**
  250. * Set a variabe in on of the request variables.
  251. *
  252. * @param string $name Name
  253. * @param string $value Value
  254. * @param string $hash Hash
  255. * @param boolean $overwrite Boolean
  256. * @return string Previous value
  257. * @since 1.5
  258. */
  259. public static function setVar($name, $value = null, $hash = 'method', $overwrite = true)
  260. {
  261. //If overwrite is true, makes sure the variable hasn't been set yet
  262. if (!$overwrite && array_key_exists($name, $_REQUEST)) {
  263. return $_REQUEST[$name];
  264. }
  265. // Clean global request var
  266. $GLOBALS['_JREQUEST'][$name] = array();
  267. // Get the request hash value
  268. $hash = strtoupper($hash);
  269. if ($hash === 'METHOD') {
  270. $hash = strtoupper($_SERVER['REQUEST_METHOD']);
  271. }
  272. $previous = array_key_exists($name, $_REQUEST) ? $_REQUEST[$name] : null;
  273. switch ($hash)
  274. {
  275. case 'GET' :
  276. $_GET[$name] = $value;
  277. $_REQUEST[$name] = $value;
  278. break;
  279. case 'POST' :
  280. $_POST[$name] = $value;
  281. $_REQUEST[$name] = $value;
  282. break;
  283. case 'COOKIE' :
  284. $_COOKIE[$name] = $value;
  285. $_REQUEST[$name] = $value;
  286. break;
  287. case 'FILES' :
  288. $_FILES[$name] = $value;
  289. break;
  290. case 'ENV' :
  291. $_ENV['name'] = $value;
  292. break;
  293. case 'SERVER' :
  294. $_SERVER['name'] = $value;
  295. break;
  296. }
  297. // Mark this variable as 'SET'
  298. $GLOBALS['_JREQUEST'][$name]['SET.'.$hash] = true;
  299. $GLOBALS['_JREQUEST'][$name]['SET.REQUEST'] = true;
  300. return $previous;
  301. }
  302. /**
  303. * Fetches and returns a request array.
  304. *
  305. * The default behaviour is fetching variables depending on the
  306. * current request method: GET and HEAD will result in returning
  307. * $_GET, POST and PUT will result in returning $_POST.
  308. *
  309. * You can force the source by setting the $hash parameter:
  310. *
  311. * post $_POST
  312. * get $_GET
  313. * files $_FILES
  314. * cookie $_COOKIE
  315. * env $_ENV
  316. * server $_SERVER
  317. * method via current $_SERVER['REQUEST_METHOD']
  318. * default $_REQUEST
  319. *
  320. * @param string $hash to get (POST, GET, FILES, METHOD).
  321. * @param int $mask Filter mask for the variable.
  322. * @return mixed Request hash.
  323. * @since 1.5
  324. */
  325. public static function get($hash = 'default', $mask = 0)
  326. {
  327. $hash = strtoupper($hash);
  328. if ($hash === 'METHOD') {
  329. $hash = strtoupper($_SERVER['REQUEST_METHOD']);
  330. }
  331. switch ($hash)
  332. {
  333. case 'GET' :
  334. $input = $_GET;
  335. break;
  336. case 'POST' :
  337. $input = $_POST;
  338. break;
  339. case 'FILES' :
  340. $input = $_FILES;
  341. break;
  342. case 'COOKIE' :
  343. $input = $_COOKIE;
  344. break;
  345. case 'ENV' :
  346. $input = &$_ENV;
  347. break;
  348. case 'SERVER' :
  349. $input = &$_SERVER;
  350. break;
  351. default:
  352. $input = $_REQUEST;
  353. break;
  354. }
  355. $result = self::_cleanVar($input, $mask);
  356. // Handle magic quotes compatability
  357. if (get_magic_quotes_gpc() && ($hash != 'FILES')) {
  358. $result = self::_stripSlashesRecursive($result);
  359. }
  360. return $result;
  361. }
  362. /**
  363. * Sets a request variable.
  364. *
  365. * @param array An associative array of key-value pairs.
  366. * @param string The request variable to set (POST, GET, FILES, METHOD).
  367. * @param boolean If true and an existing key is found, the value is overwritten, otherwise it is ignored.
  368. */
  369. public static function set($array, $hash = 'default', $overwrite = true)
  370. {
  371. foreach ($array as $key => $value) {
  372. self::setVar($key, $value, $hash, $overwrite);
  373. }
  374. }
  375. /**
  376. * Checks for a form token in the request.
  377. *
  378. * Use in conjuction with JHtml::_('form.token').
  379. *
  380. * @param string The request method in which to look for the token key.
  381. * @return boolean True if found and valid, false otherwise.
  382. */
  383. public static function checkToken($method = 'post')
  384. {
  385. $token = JUtility::getToken();
  386. if (!self::getVar($token, '', $method, 'alnum'))
  387. {
  388. $session = JFactory::getSession();
  389. if ($session->isNew()) {
  390. // Redirect to login screen.
  391. $app = &JFactory::getApplication();
  392. $return = JRoute::_('index.php');
  393. $app->redirect($return, JText::_('SESSION_EXPIRED'));
  394. $app->close();
  395. } else {
  396. return false;
  397. }
  398. } else {
  399. return true;
  400. }
  401. }
  402. /**
  403. * Cleans the request from script injection.
  404. *
  405. * @return void
  406. * @since 1.5
  407. */
  408. public static function clean()
  409. {
  410. self::_cleanArray($_FILES);
  411. self::_cleanArray($_ENV);
  412. self::_cleanArray($_GET);
  413. self::_cleanArray($_POST);
  414. self::_cleanArray($_COOKIE);
  415. self::_cleanArray($_SERVER);
  416. if (isset($_SESSION)) {
  417. self::_cleanArray($_SESSION);
  418. }
  419. $REQUEST = $_REQUEST;
  420. $GET = $_GET;
  421. $POST = $_POST;
  422. $COOKIE = $_COOKIE;
  423. $FILES = $_FILES;
  424. $ENV = $_ENV;
  425. $SERVER = $_SERVER;
  426. if (isset ($_SESSION)) {
  427. $SESSION = $_SESSION;
  428. }
  429. foreach ($GLOBALS as $key => $value)
  430. {
  431. if ($key != 'GLOBALS') {
  432. unset ($GLOBALS [ $key ]);
  433. }
  434. }
  435. $_REQUEST = $REQUEST;
  436. $_GET = $GET;
  437. $_POST = $POST;
  438. $_COOKIE = $COOKIE;
  439. $_FILES = $FILES;
  440. $_ENV = $ENV;
  441. $_SERVER = $SERVER;
  442. if (isset ($SESSION)) {
  443. $_SESSION = $SESSION;
  444. }
  445. // Make sure the request hash is clean on file inclusion
  446. $GLOBALS['_JREQUEST'] = array();
  447. }
  448. /**
  449. * Adds an array to the GLOBALS array and checks that the GLOBALS variable is not being attacked.
  450. *
  451. * @param array $array Array to clean.
  452. * @param boolean True if the array is to be added to the GLOBALS.
  453. * @since 1.5
  454. */
  455. protected static function _cleanArray(&$array, $globalise=false)
  456. {
  457. static $banned = array('_files', '_env', '_get', '_post', '_cookie', '_server', '_session', 'globals');
  458. foreach ($array as $key => $value)
  459. {
  460. // PHP GLOBALS injection bug
  461. $failed = in_array(strtolower($key), $banned);
  462. // PHP Zend_Hash_Del_Key_Or_Index bug
  463. $failed |= is_numeric($key);
  464. if ($failed) {
  465. jexit('Illegal variable <b>' . implode('</b> or <b>', $banned) . '</b> passed to script.');
  466. }
  467. if ($globalise) {
  468. $GLOBALS[$key] = $value;
  469. }
  470. }
  471. }
  472. /**
  473. * Clean up an input variable.
  474. *
  475. * @param mixed The input variable.
  476. * @param int Filter bit mask. 1=no trim: If this flag is cleared and the
  477. * input is a string, the string will have leading and trailing whitespace
  478. * trimmed. 2=allow_raw: If set, no more filtering is performed, higher bits
  479. * are ignored. 4=allow_html: HTML is allowed, but passed through a safe
  480. * HTML filter first. If set, no more filtering is performed. If no bits
  481. * other than the 1 bit is set, a strict filter is applied.
  482. * @param string The variable type {@see JFilterInput::clean()}.
  483. */
  484. protected static function _cleanVar($var, $mask = 0, $type=null)
  485. {
  486. // Static input filters for specific settings
  487. static $noHtmlFilter = null;
  488. static $safeHtmlFilter = null;
  489. // If the no trim flag is not set, trim the variable
  490. if (!($mask & 1) && is_string($var)) {
  491. $var = trim($var);
  492. }
  493. // Now we handle input filtering
  494. if ($mask & 2)
  495. {
  496. // If the allow raw flag is set, do not modify the variable
  497. $var = $var;
  498. }
  499. elseif ($mask & 4)
  500. {
  501. // If the allow html flag is set, apply a safe html filter to the variable
  502. if (is_null($safeHtmlFilter)) {
  503. $safeHtmlFilter = & JFilterInput::getInstance(null, null, 1, 1);
  504. }
  505. $var = $safeHtmlFilter->clean($var, $type);
  506. }
  507. else
  508. {
  509. // Since no allow flags were set, we will apply the most strict filter to the variable
  510. if (is_null($noHtmlFilter)) {
  511. $noHtmlFilter = & JFilterInput::getInstance(/* $tags, $attr, $tag_method, $attr_method, $xss_auto */);
  512. }
  513. $var = $noHtmlFilter->clean($var, $type);
  514. }
  515. return $var;
  516. }
  517. /**
  518. * Strips slashes recursively on an array.
  519. *
  520. * @param array $array Array of (nested arrays of) strings.
  521. * @return array The input array with stripshlashes applied to it.
  522. */
  523. protected static function _stripSlashesRecursive($value)
  524. {
  525. $value = is_array($value) ? array_map(array('JRequest', '_stripSlashesRecursive'), $value) : stripslashes($value);
  526. return $value;
  527. }
  528. }