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

/cake/libs/sanitize.php

https://github.com/cgajardo/repositorium
PHP | 348 lines | 167 code | 26 blank | 155 comment | 37 complexity | 6a8a3a271915a6675b058b626cfd70df MD5 | raw file
  1. <?php
  2. /**
  3. * Washes strings from unwanted noise.
  4. *
  5. * Helpful methods to make unsafe strings usable.
  6. *
  7. * PHP versions 4 and 5
  8. *
  9. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  10. * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. *
  12. * Licensed under The MIT License
  13. * Redistributions of files must retain the above copyright notice.
  14. *
  15. * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
  16. * @link http://cakephp.org CakePHP(tm) Project
  17. * @package cake
  18. * @subpackage cake.cake.libs
  19. * @since CakePHP(tm) v 0.10.0.1076
  20. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  21. */
  22. /**
  23. * Data Sanitization.
  24. *
  25. * Removal of alpahnumeric characters, SQL-safe slash-added strings, HTML-friendly strings,
  26. * and all of the above on arrays.
  27. *
  28. * @package cake
  29. * @subpackage cake.cake.libs
  30. */
  31. class Sanitize {
  32. /**
  33. * Removes any non-alphanumeric characters.
  34. *
  35. * @param string $string String to sanitize
  36. * @param array $allowed An array of additional characters that are not to be removed.
  37. * @return string Sanitized string
  38. * @access public
  39. * @static
  40. */
  41. function paranoid($string, $allowed = array()) {
  42. $allow = null;
  43. if (!empty($allowed)) {
  44. foreach ($allowed as $value) {
  45. $allow .= "\\$value";
  46. }
  47. }
  48. if (is_array($string)) {
  49. $cleaned = array();
  50. foreach ($string as $key => $clean) {
  51. $cleaned[$key] = preg_replace("/[^{$allow}a-zA-Z0-9]/", '', $clean);
  52. }
  53. } else {
  54. $cleaned = preg_replace("/[^{$allow}a-zA-Z0-9]/", '', $string);
  55. }
  56. return $cleaned;
  57. }
  58. /**
  59. * Makes a string SQL-safe.
  60. *
  61. * @param string $string String to sanitize
  62. * @param string $connection Database connection being used
  63. * @return string SQL safe string
  64. * @access public
  65. * @static
  66. */
  67. function escape($string, $connection = 'default') {
  68. $db =& ConnectionManager::getDataSource($connection);
  69. if (is_numeric($string) || $string === null || is_bool($string)) {
  70. return $string;
  71. }
  72. $string = substr($db->value($string), 1);
  73. $string = substr($string, 0, -1);
  74. return $string;
  75. }
  76. /**
  77. * Returns given string safe for display as HTML. Renders entities.
  78. *
  79. * strip_tags() does not validating HTML syntax or structure, so it might strip whole passages
  80. * with broken HTML.
  81. *
  82. * ### Options:
  83. *
  84. * - remove (boolean) if true strips all HTML tags before encoding
  85. * - charset (string) the charset used to encode the string
  86. * - quotes (int) see http://php.net/manual/en/function.htmlentities.php
  87. *
  88. * @param string $string String from where to strip tags
  89. * @param array $options Array of options to use.
  90. * @return string Sanitized string
  91. * @access public
  92. * @static
  93. */
  94. function html($string, $options = array()) {
  95. static $defaultCharset = false;
  96. if ($defaultCharset === false) {
  97. $defaultCharset = Configure::read('App.encoding');
  98. if ($defaultCharset === null) {
  99. $defaultCharset = 'UTF-8';
  100. }
  101. }
  102. $default = array(
  103. 'remove' => false,
  104. 'charset' => $defaultCharset,
  105. 'quotes' => ENT_QUOTES
  106. );
  107. $options = array_merge($default, $options);
  108. if ($options['remove']) {
  109. $string = strip_tags($string);
  110. }
  111. return htmlentities($string, $options['quotes'], $options['charset']);
  112. }
  113. /**
  114. * Strips extra whitespace from output
  115. *
  116. * @param string $str String to sanitize
  117. * @return string whitespace sanitized string
  118. * @access public
  119. * @static
  120. */
  121. function stripWhitespace($str) {
  122. $r = preg_replace('/[\n\r\t]+/', '', $str);
  123. return preg_replace('/\s{2,}/', ' ', $r);
  124. }
  125. /**
  126. * Strips image tags from output
  127. *
  128. * @param string $str String to sanitize
  129. * @return string Sting with images stripped.
  130. * @access public
  131. * @static
  132. */
  133. function stripImages($str) {
  134. $str = preg_replace('/(<a[^>]*>)(<img[^>]+alt=")([^"]*)("[^>]*>)(<\/a>)/i', '$1$3$5<br />', $str);
  135. $str = preg_replace('/(<img[^>]+alt=")([^"]*)("[^>]*>)/i', '$2<br />', $str);
  136. $str = preg_replace('/<img[^>]*>/i', '', $str);
  137. return $str;
  138. }
  139. /**
  140. * Strips scripts and stylesheets from output
  141. *
  142. * @param string $str String to sanitize
  143. * @return string String with <script>, <style>, <link> elements removed.
  144. * @access public
  145. * @static
  146. */
  147. function stripScripts($str) {
  148. return preg_replace('/(<link[^>]+rel="[^"]*stylesheet"[^>]*>|<img[^>]*>|style="[^"]*")|<script[^>]*>.*?<\/script>|<style[^>]*>.*?<\/style>|<!--.*?-->/is', '', $str);
  149. }
  150. /**
  151. * Strips extra whitespace, images, scripts and stylesheets from output
  152. *
  153. * @param string $str String to sanitize
  154. * @return string sanitized string
  155. * @access public
  156. */
  157. function stripAll($str) {
  158. $str = Sanitize::stripWhitespace($str);
  159. $str = Sanitize::stripImages($str);
  160. $str = Sanitize::stripScripts($str);
  161. return $str;
  162. }
  163. /**
  164. * Strips the specified tags from output. First parameter is string from
  165. * where to remove tags. All subsequent parameters are tags.
  166. *
  167. * Ex.`$clean = Sanitize::stripTags($dirty, 'b', 'p', 'div');`
  168. *
  169. * Will remove all `<b>`, `<p>`, and `<div>` tags from the $dirty string.
  170. *
  171. * @param string $str String to sanitize
  172. * @param string $tag Tag to remove (add more parameters as needed)
  173. * @return string sanitized String
  174. * @access public
  175. * @static
  176. */
  177. function stripTags() {
  178. $params = params(func_get_args());
  179. $str = $params[0];
  180. for ($i = 1, $count = count($params); $i < $count; $i++) {
  181. $str = preg_replace('/<' . $params[$i] . '\b[^>]*>/i', '', $str);
  182. $str = preg_replace('/<\/' . $params[$i] . '[^>]*>/i', '', $str);
  183. }
  184. return $str;
  185. }
  186. /**
  187. * Sanitizes given array or value for safe input. Use the options to specify
  188. * the connection to use, and what filters should be applied (with a boolean
  189. * value). Valid filters:
  190. *
  191. * - odd_spaces - removes any non space whitespace characters
  192. * - encode - Encode any html entities. Encode must be true for the `remove_html` to work.
  193. * - dollar - Escape `$` with `\$`
  194. * - carriage - Remove `\r`
  195. * - unicode -
  196. * - escape - Should the string be SQL escaped.
  197. * - backslash -
  198. * - remove_html - Strip HTML with strip_tags. `encode` must be true for this option to work.
  199. *
  200. * @param mixed $data Data to sanitize
  201. * @param mixed $options If string, DB connection being used, otherwise set of options
  202. * @return mixed Sanitized data
  203. * @access public
  204. * @static
  205. */
  206. function clean($data, $options = array()) {
  207. if (empty($data)) {
  208. return $data;
  209. }
  210. if (is_string($options)) {
  211. $options = array('connection' => $options);
  212. } else if (!is_array($options)) {
  213. $options = array();
  214. }
  215. $options = array_merge(array(
  216. 'connection' => 'default',
  217. 'odd_spaces' => true,
  218. 'remove_html' => false,
  219. 'encode' => true,
  220. 'dollar' => true,
  221. 'carriage' => true,
  222. 'unicode' => true,
  223. 'escape' => true,
  224. 'backslash' => true
  225. ), $options);
  226. if (is_array($data)) {
  227. foreach ($data as $key => $val) {
  228. $data[$key] = Sanitize::clean($val, $options);
  229. }
  230. return $data;
  231. } else {
  232. if ($options['odd_spaces']) {
  233. $data = str_replace(chr(0xCA), '', str_replace(' ', ' ', $data));
  234. }
  235. if ($options['encode']) {
  236. $data = Sanitize::html($data, array('remove' => $options['remove_html']));
  237. }
  238. if ($options['dollar']) {
  239. $data = str_replace("\\\$", "$", $data);
  240. }
  241. if ($options['carriage']) {
  242. $data = str_replace("\r", "", $data);
  243. }
  244. $data = str_replace("'", "'", str_replace("!", "!", $data));
  245. if ($options['unicode']) {
  246. $data = preg_replace("/&amp;#([0-9]+);/s", "&#\\1;", $data);
  247. }
  248. if ($options['escape']) {
  249. $data = Sanitize::escape($data, $options['connection']);
  250. }
  251. if ($options['backslash']) {
  252. $data = preg_replace("/\\\(?!&amp;#|\?#)/", "\\", $data);
  253. }
  254. return $data;
  255. }
  256. }
  257. /**
  258. * Formats column data from definition in DBO's $columns array
  259. *
  260. * @param Model $model The model containing the data to be formatted
  261. * @access public
  262. * @static
  263. */
  264. function formatColumns(&$model) {
  265. foreach ($model->data as $name => $values) {
  266. if ($name == $model->alias) {
  267. $curModel =& $model;
  268. } elseif (isset($model->{$name}) && is_object($model->{$name}) && is_subclass_of($model->{$name}, 'Model')) {
  269. $curModel =& $model->{$name};
  270. } else {
  271. $curModel = null;
  272. }
  273. if ($curModel != null) {
  274. foreach ($values as $column => $data) {
  275. $colType = $curModel->getColumnType($column);
  276. if ($colType != null) {
  277. $db =& ConnectionManager::getDataSource($curModel->useDbConfig);
  278. $colData = $db->columns[$colType];
  279. if (isset($colData['limit']) && strlen(strval($data)) > $colData['limit']) {
  280. $data = substr(strval($data), 0, $colData['limit']);
  281. }
  282. if (isset($colData['formatter']) || isset($colData['format'])) {
  283. switch (strtolower($colData['formatter'])) {
  284. case 'date':
  285. $data = date($colData['format'], strtotime($data));
  286. break;
  287. case 'sprintf':
  288. $data = sprintf($colData['format'], $data);
  289. break;
  290. case 'intval':
  291. $data = intval($data);
  292. break;
  293. case 'floatval':
  294. $data = floatval($data);
  295. break;
  296. }
  297. }
  298. $model->data[$name][$column]=$data;
  299. /*
  300. switch ($colType) {
  301. case 'integer':
  302. case 'int':
  303. return $data;
  304. break;
  305. case 'string':
  306. case 'text':
  307. case 'binary':
  308. case 'date':
  309. case 'time':
  310. case 'datetime':
  311. case 'timestamp':
  312. case 'date':
  313. return "'" . $data . "'";
  314. break;
  315. }
  316. */
  317. }
  318. }
  319. }
  320. }
  321. }
  322. }