sanitize.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: sanitize.php 7876 2008-11-16 05:00:41Z mark_story $ */
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. (http://www.cakefoundation.org)
00012  *
00013  * Licensed under The MIT License
00014  * Redistributions of files must retain the above copyright notice.
00015  *
00016  * @filesource
00017  * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00018  * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00019  * @package       cake
00020  * @subpackage    cake.cake.libs
00021  * @since         CakePHP(tm) v 0.10.0.1076
00022  * @version       $Revision: 7876 $
00023  * @modifiedby    $LastChangedBy: mark_story $
00024  * @lastmodified  $Date: 2008-11-16 00:00:41 -0500 (Sun, 16 Nov 2008) $
00025  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
00026  */
00027 /**
00028  * Data Sanitization.
00029  *
00030  * Removal of alpahnumeric characters, SQL-safe slash-added strings, HTML-friendly strings,
00031  * and all of the above on arrays.
00032  *
00033  * @package       cake
00034  * @subpackage    cake.cake.libs
00035  */
00036 class Sanitize {
00037 /**
00038  * Removes any non-alphanumeric characters.
00039  *
00040  * @param string $string String to sanitize
00041  * @return string Sanitized string
00042  * @access public
00043  * @static
00044  */
00045     function paranoid($string, $allowed = array()) {
00046         $allow = null;
00047         if (!empty($allowed)) {
00048             foreach ($allowed as $value) {
00049                 $allow .= "\\$value";
00050             }
00051         }
00052 
00053         if (is_array($string)) {
00054             $cleaned = array();
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.
00065  *
00066  * @param string $string String to sanitize
00067  * @param string $connection Database connection being used
00068  * @return string SQL safe string
00069  * @access public
00070  * @static
00071  */
00072     function escape($string, $connection = 'default') {
00073         $db =& ConnectionManager::getDataSource($connection);
00074         if (is_numeric($string) || $string === null || is_bool($string)) {
00075             return $string;
00076         }
00077         $string = substr($db->value($string), 1);
00078         $string = substr($string, 0, -1);
00079         return $string;
00080     }
00081 /**
00082  * Returns given string safe for display as HTML. Renders entities.
00083  *
00084  * @param string $string String from where to strip tags
00085  * @param boolean $remove If true, the string is stripped of all HTML tags
00086  * @return string Sanitized string
00087  * @access public
00088  * @static
00089  */
00090     function html($string, $remove = false) {
00091         if ($remove) {
00092             $string = strip_tags($string);
00093         } else {
00094             $patterns = array("/\&/", "/%/", "/</", "/>/", '/"/', "/'/", "/\(/", "/\)/", "/\+/", "/-/");
00095             $replacements = array("&amp;", "&#37;", "&lt;", "&gt;", "&quot;", "&#39;", "&#40;", "&#41;", "&#43;", "&#45;");
00096             $string = preg_replace($patterns, $replacements, $string);
00097         }
00098         return $string;
00099     }
00100 /**
00101  * Strips extra whitespace from output
00102  *
00103  * @param string $str String to sanitize
00104  * @return string whitespace sanitized string
00105  * @access public
00106  * @static
00107  */
00108     function stripWhitespace($str) {
00109         $r = preg_replace('/[\n\r\t]+/', '', $str);
00110         return preg_replace('/\s{2,}/', ' ', $r);
00111     }
00112 /**
00113  * Strips image tags from output
00114  *
00115  * @param string $str String to sanitize
00116  * @return string Sting with images stripped.
00117  * @access public
00118  * @static
00119  */
00120     function stripImages($str) {
00121         $str = preg_replace('/(<a[^>]*>)(<img[^>]+alt=")([^"]*)("[^>]*>)(<\/a>)/i', '$1$3$5<br />', $str);
00122         $str = preg_replace('/(<img[^>]+alt=")([^"]*)("[^>]*>)/i', '$2<br />', $str);
00123         $str = preg_replace('/<img[^>]*>/i', '', $str);
00124         return $str;
00125     }
00126 /**
00127  * Strips scripts and stylesheets from output
00128  *
00129  * @param string $str String to sanitize
00130  * @return string String with <script>, <style>, <link> elements removed.
00131  * @access public
00132  * @static
00133  */
00134     function stripScripts($str) {
00135         return preg_replace('/(<link[^>]+rel="[^"]*stylesheet"[^>]*>|<img[^>]*>|style="[^"]*")|<script[^>]*>.*?<\/script>|<style[^>]*>.*?<\/style>|<!--.*?-->/i', '', $str);
00136     }
00137 /**
00138  * Strips extra whitespace, images, scripts and stylesheets from output
00139  *
00140  * @param string $str String to sanitize
00141  * @return string sanitized string
00142  * @access public
00143  */
00144     function stripAll($str) {
00145         $str = Sanitize::stripWhitespace($str);
00146         $str = Sanitize::stripImages($str);
00147         $str = Sanitize::stripScripts($str);
00148         return $str;
00149     }
00150 /**
00151  * Strips the specified tags from output. First parameter is string from
00152  * where to remove tags. All subsequent parameters are tags.
00153  *
00154  * @param string $str String to sanitize
00155  * @param string $tag Tag to remove (add more parameters as needed)
00156  * @return string sanitized String
00157  * @access public
00158  * @static
00159  */
00160     function stripTags() {
00161         $params = params(func_get_args());
00162         $str = $params[0];
00163 
00164         for ($i = 1; $i < count($params); $i++) {
00165             $str = preg_replace('/<' . $params[$i] . '\b[^>]*>/i', '', $str);
00166             $str = preg_replace('/<\/' . $params[$i] . '[^>]*>/i', '', $str);
00167         }
00168         return $str;
00169     }
00170 /**
00171  * Sanitizes given array or value for safe input. Use the options to specify
00172  * the connection to use, and what filters should be applied (with a boolean
00173  * value). Valid filters: odd_spaces, encode, dollar, carriage, unicode,
00174  * escape, backslash.
00175  *
00176  * @param mixed $data Data to sanitize
00177  * @param mixed $options If string, DB connection being used, otherwise set of options
00178  * @return mixed Sanitized data
00179  * @access public
00180  * @static
00181  */
00182     function clean($data, $options = array()) {
00183         if (empty($data)) {
00184             return $data;
00185         }
00186 
00187         if (is_string($options)) {
00188             $options = array('connection' => $options);
00189         } else if (!is_array($options)) {
00190             $options = array();
00191         }
00192 
00193         $options = array_merge(array(
00194             'connection' => 'default',
00195             'odd_spaces' => true,
00196             'encode' => true,
00197             'dollar' => true,
00198             'carriage' => true,
00199             'unicode' => true,
00200             'escape' => true,
00201             'backslash' => true
00202         ), $options);
00203 
00204         if (is_array($data)) {
00205             foreach ($data as $key => $val) {
00206                 $data[$key] = Sanitize::clean($val, $options);
00207             }
00208             return $data;
00209         } else {
00210             if ($options['odd_spaces']) {
00211                 $data = str_replace(chr(0xCA), '', str_replace(' ', ' ', $data));
00212             }
00213             if ($options['encode']) {
00214                 $data = Sanitize::html($data);
00215             }
00216             if ($options['dollar']) {
00217                 $data = str_replace("\\\$", "$", $data);
00218             }
00219             if ($options['carriage']) {
00220                 $data = str_replace("\r", "", $data);
00221             }
00222 
00223             $data = str_replace("'", "'", str_replace("!", "!", $data));
00224 
00225             if ($options['unicode']) {
00226                 $data = preg_replace("/&amp;#([0-9]+);/s", "&#\\1;", $data);
00227             }
00228             if ($options['escape']) {
00229                 $data = Sanitize::escape($data, $options['connection']);
00230             }
00231             if ($options['backslash']) {
00232                 $data = preg_replace("/\\\(?!&amp;#|\?#)/", "\\", $data);
00233             }
00234             return $data;
00235         }
00236     }
00237 /**
00238  * Formats column data from definition in DBO's $columns array
00239  *
00240  * @param Model $model The model containing the data to be formatted
00241  * @access public
00242  * @static
00243  */
00244     function formatColumns(&$model) {
00245         foreach ($model->data as $name => $values) {
00246             if ($name == $model->alias) {
00247                 $curModel =& $model;
00248             } elseif (isset($model->{$name}) && is_object($model->{$name}) && is_subclass_of($model->{$name}, 'Model')) {
00249                 $curModel =& $model->{$name};
00250             } else {
00251                 $curModel = null;
00252             }
00253 
00254             if ($curModel != null) {
00255                 foreach ($values as $column => $data) {
00256                     $colType = $curModel->getColumnType($column);
00257 
00258                     if ($colType != null) {
00259                         $db =& ConnectionManager::getDataSource($curModel->useDbConfig);
00260                         $colData = $db->columns[$colType];
00261 
00262                         if (isset($colData['limit']) && strlen(strval($data)) > $colData['limit']) {
00263                             $data = substr(strval($data), 0, $colData['limit']);
00264                         }
00265 
00266                         if (isset($colData['formatter']) || isset($colData['format'])) {
00267 
00268                             switch (strtolower($colData['formatter'])) {
00269                                 case 'date':
00270                                     $data = date($colData['format'], strtotime($data));
00271                                 break;
00272                                 case 'sprintf':
00273                                     $data = sprintf($colData['format'], $data);
00274                                 break;
00275                                 case 'intval':
00276                                     $data = intval($data);
00277                                 break;
00278                                 case 'floatval':
00279                                     $data = floatval($data);
00280                                 break;
00281                             }
00282                         }
00283                         $model->data[$name][$column]=$data;
00284                         /*
00285                         switch ($colType) {
00286                             case 'integer':
00287                             case 'int':
00288                                 return  $data;
00289                             break;
00290                             case 'string':
00291                             case 'text':
00292                             case 'binary':
00293                             case 'date':
00294                             case 'time':
00295                             case 'datetime':
00296                             case 'timestamp':
00297                             case 'date':
00298                                 return "'" . $data . "'";
00299                             break;
00300                         }
00301                         */
00302                     }
00303                 }
00304             }
00305         }
00306     }
00307 }
00308 ?>

Generated on Sun Nov 22 00:30:54 2009 for CakePHP 1.2.x.x (v1.2.4.8284) by doxygen 1.4.7