sanitize.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: sanitize_8php-source.html 675 2008-12-26 00:27:14Z gwoo $ */
00003 /**
00004  * Washes strings from unwanted noise.
00005  *
00006  * Helpful methods to make unsafe strings usable.
00007  *
00008  * PHP versions 4 and 5
00009  *
00010  * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
00011  * Copyright 2005-2008, Cake Software Foundation, Inc.
00012  *                              1785 E. Sahara Avenue, Suite 490-204
00013  *                              Las Vegas, Nevada 89104
00014  *
00015  * Licensed under The MIT License
00016  * Redistributions of files must retain the above copyright notice.
00017  *
00018  * @filesource
00019  * @copyright       Copyright 2005-2008, Cake Software Foundation, Inc.
00020  * @link                http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00021  * @package         cake
00022  * @subpackage      cake.cake.libs
00023  * @since           CakePHP(tm) v 0.10.0.1076
00024  * @version         $Revision: 675 $
00025  * @modifiedby      $LastChangedBy: gwoo $
00026  * @lastmodified    $Date: 2008-12-25 16:27:14 -0800 (Thu, 25 Dec 2008) $
00027  * @license         http://www.opensource.org/licenses/mit-license.php The MIT License
00028  */
00029 /**
00030  * Data Sanitization.
00031  *
00032  * Removal of alpahnumeric characters, SQL-safe slash-added strings, HTML-friendly strings,
00033  * and all of the above on arrays.
00034  *
00035  * @package     cake
00036  * @subpackage  cake.cake.libs
00037  */
00038 class Sanitize{
00039 /**
00040  * Removes any non-alphanumeric characters.
00041  *
00042  * @param string $string
00043  * @return string
00044  * @access public
00045  */
00046     function paranoid($string, $allowed = array()) {
00047         $allow = null;
00048         if (!empty($allowed)) {
00049             foreach ($allowed as $value) {
00050                 $allow .= "\\$value";
00051             }
00052         }
00053 
00054         if (is_array($string)) {
00055             foreach ($string as $key => $clean) {
00056                 $cleaned[$key] = preg_replace("/[^{$allow}a-zA-Z0-9]/", "", $clean);
00057             }
00058         } else {
00059             $cleaned = preg_replace("/[^{$allow}a-zA-Z0-9]/", "", $string);
00060         }
00061         return $cleaned;
00062     }
00063 /**
00064  * Makes a string SQL-safe by adding slashes (if needed).
00065  *
00066  * @param string $string
00067  * @return string
00068  * @access public
00069  */
00070     function sql($string) {
00071         if (!ini_get('magic_quotes_gpc')) {
00072             $string = addslashes($string);
00073         }
00074         return $string;
00075     }
00076 /**
00077  * Returns given string safe for display as HTML. Renders entities.
00078  *
00079  * @param string $string
00080  * @param boolean $remove If true, the string is stripped of all HTML tags
00081  * @return string
00082  * @access public
00083  */
00084     function html($string, $remove = false) {
00085         if ($remove) {
00086             $string = strip_tags($string);
00087         } else {
00088             $patterns = array("/\&/", "/%/", "/</", "/>/", '/"/', "/'/", "/\(/", "/\)/", "/\+/", "/-/");
00089             $replacements = array("&amp;", "&#37;", "&lt;", "&gt;", "&quot;", "&#39;", "&#40;", "&#41;", "&#43;", "&#45;");
00090             $string = preg_replace($patterns, $replacements, $string);
00091         }
00092         return $string;
00093     }
00094 /**
00095  * Recursively sanitizes given array of data for safe input.
00096  *
00097  * @param mixed $toClean
00098  * @return mixed
00099  * @access public
00100  */
00101     function cleanArray(&$toClean) {
00102         return $this->cleanArrayR($toClean);
00103     }
00104 /**
00105  * Method used for recursively sanitizing arrays of data
00106  * for safe input
00107  *
00108  * @param array $toClean
00109  * @return array The clean array
00110  * @access public
00111  */
00112     function cleanArrayR(&$toClean) {
00113         if (is_array($toClean)) {
00114             while (list($k, $v) = each($toClean)) {
00115                 if (is_array($toClean[$k])) {
00116                     $this->cleanArray($toClean[$k]);
00117                 } else {
00118                     $toClean[$k] = $this->cleanValue($v);
00119                 }
00120             }
00121         } else {
00122             return null;
00123         }
00124     }
00125 /**
00126  * Do we really need to sanitize array keys? If so, we can use this code...
00127     function cleanKey($key) {
00128         if ($key == "")
00129         {
00130             return "";
00131         }
00132         //URL decode and convert chars to HTML entities
00133         $key = htmlspecialchars(urldecode($key));
00134         //Remove ..
00135         $key = preg_replace( "/\.\./", "", $key );
00136         //Remove __FILE__, etc.
00137         $key = preg_replace( "/\_\_(.+?)\_\_/", "", $key );
00138         //Trim word chars, '.', '-', '_'
00139         $key = preg_replace( "/^([\w\.\-\_]+)$/", "$1", $key );
00140         return $key;
00141     }
00142  */
00143 
00144 /**
00145  * Method used by cleanArray() to sanitize array nodes.
00146  *
00147  * @param string $val
00148  * @return string
00149  * @access public
00150  */
00151     function cleanValue($val) {
00152         if ($val == "") {
00153             return "";
00154         }
00155         //Replace odd spaces with safe ones
00156         $val = str_replace(" ", " ", $val);
00157         $val = str_replace(chr(0xCA), "", $val);
00158         //Encode any HTML to entities.
00159         $val = $this->html($val);
00160         //Double-check special chars and replace carriage returns with new lines
00161         $val = preg_replace("/\\\$/", "$", $val);
00162         $val = preg_replace("/\r\n/", "\n", $val);
00163         $val = str_replace("!", "!", $val);
00164         $val = str_replace("'", "'", $val);
00165         //Allow unicode (?)
00166         $val = preg_replace("/&amp;#([0-9]+);/s", "&#\\1;", $val);
00167         //Add slashes for SQL
00168         $val = $this->sql($val);
00169         //Swap user-inputted backslashes (?)
00170         $val = preg_replace("/\\\(?!&amp;#|\?#)/", "\\", $val);
00171         return $val;
00172     }
00173 
00174 /**
00175  * Formats column data from definition in DBO's $columns array
00176  *
00177  * @param Model $model The model containing the data to be formatted
00178  * @return void
00179  * @access public
00180  */
00181     function formatColumns(&$model) {
00182         foreach ($model->data as $name => $values) {
00183             if ($name == $model->name) {
00184                 $curModel =& $model;
00185             } elseif (isset($model->{$name}) && is_object($model->{$name}) && is_subclass_of($model->{$name}, 'Model')) {
00186                 $curModel =& $model->{$name};
00187             } else {
00188                 $curModel = null;
00189             }
00190 
00191             if ($curModel != null) {
00192                 foreach ($values as $column => $data) {
00193                     $colType = $curModel->getColumnType($column);
00194 
00195                     if ($colType != null) {
00196                         $db =& ConnectionManager::getDataSource($curModel->useDbConfig);
00197                         $colData = $db->columns[$colType];
00198 
00199                         if (isset($colData['limit']) && strlen(strval($data)) > $colData['limit']) {
00200                             $data = substr(strval($data), 0, $colData['limit']);
00201                         }
00202 
00203                         if (isset($colData['formatter']) || isset($colData['format'])) {
00204 
00205                             switch(strtolower($colData['formatter'])) {
00206                                 case 'date':
00207                                     $data = date($colData['format'], strtotime($data));
00208                                 break;
00209                                 case 'sprintf':
00210                                     $data = sprintf($colData['format'], $data);
00211                                 break;
00212                                 case 'intval':
00213                                     $data = intval($data);
00214                                 break;
00215                                 case 'floatval':
00216                                     $data = floatval($data);
00217                                 break;
00218                             }
00219                         }
00220                         $model->data[$name][$column]=$data;
00221                         /*
00222                         switch($colType) {
00223                             case 'integer':
00224                             case 'int':
00225                                 return  $data;
00226                             break;
00227                             case 'string':
00228                             case 'text':
00229                             case 'binary':
00230                             case 'date':
00231                             case 'time':
00232                             case 'datetime':
00233                             case 'timestamp':
00234                             case 'date':
00235                                 return "'" . $data . "'";
00236                             break;
00237                         }
00238                         */
00239                     }
00240                 }
00241             }
00242         }
00243     }
00244 }
00245 ?>