47 'applet',
'body',
'bgsound',
'base',
'basefont',
'embed',
'frame',
48 'frameset',
'head',
'html',
'id',
'iframe',
'ilayer',
'layer',
49 'link',
'meta',
'name',
'object',
'script',
'style',
'title',
'xml'
52 protected $attrBlacklist = array(
'action',
'background',
'codebase',
'dynsrc',
'lowsrc');
72 for (
$i = 0;
$i < $countTagsArray; ++
$i) {
76 for (
$i = 0;
$i < $countAttrArray; ++
$i) {
115 if (!isset ($instances)) {
116 $instances = array();
119 if (empty ($instances[$sig])) {
120 $classname = __CLASS__ ;
124 return $instances[$sig];
137 if (is_array($source)) {
139 foreach ($source as $key => $value) {
141 if (is_string($value)) {
142 $source[$key] = $this->
remove($this->
decode($value));
146 } elseif (is_string($source)) {
148 return $this->
remove($this->
decode($source));
174 if (isset($this) && is_a($this, __CLASS__)) {
177 $classname = __CLASS__ ;
178 $filter = $classname::getInstance();
183 switch (strtoupper(
$type)) {
187 preg_match(
'/-?[0-9]+/', (
string) $source, $matches);
194 preg_match(
'/-?[0-9]+(\.[0-9]+)?/', (
string) $source, $matches);
195 $result = @ (float) $matches[0];
204 $result = (string) preg_replace(
'/[^A-Z_]/i',
'', $source);
208 $result = (string) preg_replace(
'/[^A-Z0-9]/i',
'', $source);
212 $result = (string) preg_replace(
'/[^A-Z0-9_\.-]/i',
'', $source);
217 $result = (string) preg_replace(
'/[^A-Z0-9\/+=]/i',
'', $source);
229 $source = trim((
string) $source);
230 $pattern =
'/^([-_\.\/A-Z0-9=&%?~]+)(.*)$/i';
231 preg_match($pattern, $source, $matches);
232 $result = @ (string) $matches[1];
236 $result = (string) preg_replace(
'/[\x00-\x1F\x7F<>"\'%&]/',
'', $source);
243 if (!empty($urlparts[
'scheme'])
244 && !($urlparts[
'scheme']==
'http' || $urlparts[
'scheme']==
'https')
249 if (!preg_match(
'#^[^"<>\x00-\x1F]+$#',
$result)) {
256 if (!filter_var((
string) $source, FILTER_VALIDATE_EMAIL)) {
265 if (!filter_var((
string) $source, FILTER_VALIDATE_IP)) {
285 protected function remove($source)
289 while ($source != $this->
filterTags($source)) {
310 $tagOpen_start = strpos($source,
'<');
312 while ($tagOpen_start !==
false) {
314 $preTag .= substr($postTag, 0, $tagOpen_start);
315 $postTag = substr($postTag, $tagOpen_start);
316 $fromTagOpen = substr($postTag, 1);
318 $tagOpen_end = strpos($fromTagOpen,
'>');
319 if ($tagOpen_end ===
false) {
323 $tagOpen_nested = strpos($fromTagOpen,
'<');
324 if (($tagOpen_nested !==
false) && ($tagOpen_nested < $tagOpen_end)) {
325 $preTag .= substr($postTag, 0, ($tagOpen_nested+1));
326 $postTag = substr($postTag, ($tagOpen_nested+1));
327 $tagOpen_start = strpos($postTag,
'<');
330 $tagOpen_nested = (strpos($fromTagOpen,
'<') + $tagOpen_start + 1);
331 $currentTag = substr($fromTagOpen, 0, $tagOpen_end);
332 $tagLength = strlen($currentTag);
335 $tagOpen_start = strpos($postTag,
'<');
338 $tagLeft = $currentTag;
340 $currentSpace = strpos($tagLeft,
' ');
341 if (substr($currentTag, 0, 1) ==
"/") {
344 list($tagName) = explode(
' ', $currentTag);
345 $tagName = substr($tagName, 1);
349 list($tagName) = explode(
' ', $currentTag);
352 if ((!preg_match(
"/^[a-z][a-z0-9]*$/i", $tagName))
354 || ((in_array(strtolower($tagName), $this->tagBlacklist))
357 $postTag = substr($postTag, ($tagLength + 2));
358 $tagOpen_start = strpos($postTag,
'<');
363 while ($currentSpace !==
false) {
364 $fromSpace = substr($tagLeft, ($currentSpace+1));
365 $nextSpace = strpos($fromSpace,
' ');
366 $openQuotes = strpos($fromSpace,
'"');
367 $closeQuotes = strpos(substr($fromSpace, ($openQuotes+1)),
'"') + $openQuotes + 1;
369 if (strpos($fromSpace,
'=') !==
false) {
371 if (($openQuotes !==
false)
372 && (strpos(substr($fromSpace, ($openQuotes+1)),
'"') !==
false)
374 $attr = substr($fromSpace, 0, ($closeQuotes+1));
376 $attr = substr($fromSpace, 0, $nextSpace);
382 $attr = substr($fromSpace, 0, $nextSpace);
391 $tagLeft = substr($fromSpace, strlen($attr));
392 $currentSpace = strpos($tagLeft,
' ');
395 $tagFound = in_array(strtolower($tagName), $this->tagsArray);
397 if ((!$tagFound && $this->tagsMethod) || ($tagFound && !$this->tagsMethod)) {
401 $preTag .=
'<' . $tagName;
402 $countAttrSet = count($attrSet);
403 for (
$i = 0;
$i < $countAttrSet; ++
$i) {
404 $preTag .=
' ' . $attrSet[
$i];
407 if (strpos($fromTagOpen,
"</" . $tagName)) {
414 $preTag .=
'</' . $tagName .
'>';
418 $postTag = substr($postTag, ($tagLength + 2));
419 $tagOpen_start = strpos($postTag,
'<');
438 $countAttrSet = count($attrSet);
439 for (
$i = 0;
$i < $countAttrSet; ++
$i) {
445 $attrSubSet = explode(
'=', trim($attrSet[$i]));
446 list($attrSubSet[0]) = explode(
' ', $attrSubSet[0]);
448 if ((!preg_match(
'/[a-z]*$/i', $attrSubSet[0]))
450 && ((in_array(strtolower($attrSubSet[0]), $this->attrBlacklist))
451 || (substr($attrSubSet[0], 0, 2) ==
'on')))
456 if ($attrSubSet[1]) {
458 $attrSubSet[1] = str_replace(
'&#',
'', $attrSubSet[1]);
460 $attrSubSet[1] = preg_replace(
'/\s+/',
'', $attrSubSet[1]);
462 $attrSubSet[1] = str_replace(
'"',
'', $attrSubSet[1]);
465 if ((substr($attrSubSet[1], 0, 1) ==
"'")
466 && (substr($attrSubSet[1], (strlen($attrSubSet[1]) - 1), 1) ==
"'")
468 $attrSubSet[1] = substr($attrSubSet[1], 1, (strlen($attrSubSet[1]) - 2));
471 $attrSubSet[1] = stripslashes($attrSubSet[1]);
474 if (((strpos(strtolower($attrSubSet[1]),
'expression') !==
false)
475 && (strtolower($attrSubSet[0]) ==
'style')) ||
476 (strpos(strtolower($attrSubSet[1]),
'javascript:') !==
false) ||
477 (strpos(strtolower($attrSubSet[1]),
'behaviour:') !==
false) ||
478 (strpos(strtolower($attrSubSet[1]),
'vbscript:') !==
false) ||
479 (strpos(strtolower($attrSubSet[1]),
'mocha:') !==
false) ||
480 (strpos(strtolower($attrSubSet[1]),
'livescript:') !==
false)
486 $attrFound = in_array(strtolower($attrSubSet[0]), $this->attrArray);
488 if ((!$attrFound && $this->attrMethod) || ($attrFound && !$this->attrMethod)) {
489 if ($attrSubSet[1]) {
491 $newSet[] = $attrSubSet[0] .
'="' . $attrSubSet[1] .
'"';
492 } elseif ($attrSubSet[1] ==
"0") {
494 $newSet[] = $attrSubSet[0] .
'="0"';
497 $newSet[] = $attrSubSet[0] .
'="' . $attrSubSet[0] .
'"';
515 $charset = defined(
'_CHARSET') ? constant(
'_CHARSET') :
'utf-8';
516 $source = html_entity_decode($source, ENT_QUOTES, $charset);
518 $source = preg_replace_callback(
520 function ($matches) {
521 return chr($matches[1]);
526 $source = preg_replace_callback(
527 '/&#x([a-f0-9]+);/mi',
528 function ($matches) {
529 return chr(
'0x'.$matches[1]);
557 public static function gather($source, $input_map, $require =
false)
561 if (!empty($source)) {
562 $source = strtolower($source);
563 foreach ($input_map as $input) {
565 if (isset($input[0])) {
567 $type = isset($input[1]) ? $input[1] :
'string';
568 $default = isset($input[2]) ?
569 (($require && $require==
$name) ?
'': $input[2]) :
'';
570 $trim = isset($input[3]) ? $input[3] :
true;
571 $maxlen = isset($input[4]) ? $input[4] : 0;
575 if (isset($_GET[
$name])) {
580 if (isset($_POST[$name])) {
581 $value=$_POST[
$name];
585 if (isset($_COOKIE[$name])) {
586 $value=$_COOKIE[
$name];
591 $value = trim($value);
594 if (function_exists(
'mb_strlen')) {
595 if (mb_strlen($value)>$maxlen) {
596 $value=mb_substr($value, 0, $maxlen);
599 $value=substr($value, 0, $maxlen);
602 $value = trim($value);
610 if (empty($output[$require])) {