PHP- Kodu:
<?php
/** @class: InputFilter;
* @project: Filter User Input Source;
* @date: 18-03-2005;
* @version: 1.1.1_php5;
* @author: Daniel Morris;
* @copyright: Daniel Morris;
* @email: dan@rootcube.com;
* @license: GNU General Public License (GPL);
*/
class InputFilter {
// class config vars
private $tagsArray; // required
private $attrArray; // default = empty array
private $tagsMethod; // default = 0
private $attrMethod; // default = 0
/**
* Constructor for inputFilter class. Only first parameter is required.
* @access constructor
* @param Array $tagsArray - list of user-defined tags
* @param Array $attrArray - list of user-defined attributes
* @param int $tagsMethod - 0= allow just user-defined, 1= allow all but user-defined
* @param int $attrMethod - 0= allow just user-defined, 1= allow all but user-defined
*/
public function __construct($tagsArray, $attrArray = array(), $tagsMethod = 0, $attrMethod = 0) {
$this->tagsArray = $tagsArray;
$this->attrArray = $attrArray;
$this->tagsMethod = $tagsMethod;
$this->attrMethod = $attrMethod;
}
/**
* Method to be called by another php script.
* @access public
* @param Mixed $source - input string/array-of-string to be 'cleaned'
* @return String $source - 'cleaned' version of input parameter
*/
public function process($source) {
if (is_array($source)) { // clean all elements in this array
for ($i = 0; $i < count($source); $i++)
if (is_string($source[$i])) $source[$i] = $this->remove($source[$i]);
return $source;
} else if (is_string($source)) return $this->remove($source); // clean this string
else return $source; // return parameter as given
}
/**
* Internal method to iteratively remove all unwanted tags and attributes
* @access private
* @param String $source - input string to be 'cleaned'
* @return String $source - 'cleaned' version of input parameter
*/
private function remove($source) {
$loopCounter=0;
// provides nested-tag protection
while($source != $this->filterTags($source)) {
$source = $this->filterTags($source);
$loopCounter++;
}
return $source;
}
/**
* Internal method to strip a string of certain tags
* @access private
* @param String $source - input string to be 'cleaned'
* @return String $source - 'cleaned' version of input parameter
*/
private function filterTags($source) {
// filter pass setup
$preTag = NULL;
$postTag = $source;
// find initial tag's position
$tagOpen_start = strpos($source, '<');
// interate through string until no tags left
while($tagOpen_start !== FALSE) {
// tag setup
$fromTagOpen = substr($postTag, $tagOpen_start);
$tagOpen_end = strpos($fromTagOpen, '>');
$tagOpen_nested = (strpos(substr($fromTagOpen, 1), '<')+1);
$tagOpen_length = $tagOpen_end - 1;
$currentTag = substr($fromTagOpen, 1, $tagOpen_length);
// iterate through tag finding attribute pairs - setup
$tagLeft = $currentTag;
$attrSet = array();
$currentSpace = strpos($tagLeft, ' ');
// is end tag
if (substr($currentTag, 0, 1) == "/") {
$isCloseTag = TRUE;
list($tagName) = explode(' ', $currentTag);
$tagName = substr($tagName, 1);
// is start tag
} else {
$isCloseTag = FALSE;
list($tagName) = explode(' ', $currentTag);
}
// this while is needed to support attribute values with spaces in!
while ($currentSpace !== FALSE) {
$fromSpace = substr($tagLeft, ($currentSpace+1));
$nextSpace = strpos($fromSpace, ' ');
$openQuotes = strpos($fromSpace, '"');
$closeQuotes = strpos(substr($fromSpace, ($openQuotes+1)), '"') + $openQuotes + 1;
// another equals exists
if (strpos($fromSpace, '=') !== FALSE) {
// opening and closing quotes exists
if (($openQuotes !== FALSE) && (strpos(substr($fromSpace, ($openQuotes+1)), '"') !== FALSE))
$attr = substr($fromSpace, 0, ($closeQuotes+1));
// one or neither exist
else $attr = substr($fromSpace, 0, $nextSpace);
// no more equals exist
} else $attr = substr($fromSpace, 0, $nextSpace);
// last attr pair
if (!$attr) $attr = $fromSpace;
// add to attribute pairs array
$attrSet[] = $attr;
// next inc
$tagLeft = substr($fromSpace, strlen($attr));
$currentSpace = strpos($tagLeft, ' ');
}
// deals with nexted tags
if (($tagOpen_nested < $tagOpen_end) && ($fromTagOpen[$tagOpen_nested] == '<')) {
$preTag .= substr($postTag, 0, ($tagOpen_start + ($tagOpen_end - $tagOpen_nested) - 1));
$postTag = substr($fromTagOpen, $tagOpen_nested);
$tagOpen_start = strpos($postTag, '<');
continue;
// doesn't contain nested tag
} else $preTag .= substr($postTag, 0, $tagOpen_start);
// appears in array specified by user
$tagFound = in_array(strtolower($tagName), $this->tagsArray);
// remove this tag on condition
if ((!$tagFound && $this->tagsMethod) || ($tagFound && !$this->tagsMethod)) {
// reconstruct tag with allowed attributes
if (!$isCloseTag) {
$attrSet = $this->filterAttr($attrSet);
$preTag .= '<' . $tagName;
for ($i = 0; $i < count($attrSet); $i++)
$preTag .= ' ' . $attrSet[$i];
// reformat single tags to XHTML
if (strpos($fromTagOpen, "</" . $tagName)) $preTag .= '>';
else $preTag .= ' />';
// just the tagname
} else $preTag .= '</' . $tagName . '>';
}
// find next tag's start
$postTag = substr($postTag, ($tagOpen_start + $tagOpen_length + 2));
$tagOpen_start = strpos($postTag, '<');
}
// append any code after end of tags
$preTag .= $postTag;
return $preTag;
}
/**
* Internal method to strip a tag of certain attributes
* @access private
* @param Array $attrSet
* @return Array $newSet
*/
private function filterAttr($attrSet) {
$newSet = array();
// has attributes
for ($i = 0; $i <count($attrSet); $i++) {
$attrSubSet = explode('=', $attrSet[$i]);
list($attrSubSet[0]) = explode(' ', $attrSubSet[0]);
$attrFound = in_array(strtolower($attrSubSet[0]), $this->attrArray);
// keep this attr on condition
if ((!$attrFound && $this->attrMethod) || ($attrFound && !$this->attrMethod)) {
// attr has value
if ($attrSubSet[1]) $newSet[] = $attrSubSet[0] . '=' . $attrSubSet[1];
// reformat single attributes to XHTML
else $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[0] . '"';
}
}
return $newSet;
}
}
?>