class SecureHTML
{
public function _secure_html($text)
{
$text = preg_replace_callback($expr = '~'.$this->_html_expr('\w+').'~si',array($this,'_secure_html_callback'),$text);
return $text;
}
public function _prepare_val($string)
{
return html_entity_decode($string,ENT_QUOTES,'UTF-8');
}
public function _xml_parse_attrs($string)
{
preg_match_all('~([^\s=]+)=(?:([\'"])(.*?)\2|([^\s>]+))~si',$string,$mm,PREG_SET_ORDER);
$attrs = array();
for ($j = 0,$ss = sizeof($mm); $j < $ss; ++$j)
{
$attrs[strtolower($mm[$j][1])] = $this->_prepare_val((isset($mm[$j][4]) and $mm[$j][4] !== '')?$mm[$j][4]:$mm[$j][3]);
}
return $attrs;
}
public function _html_expr($name_expr = '\w+',$short = FALSE)
{
return '<('.$name_expr.')(?:\s+((?:[^>\'"]*(?:([\'"]).*?\3)?)*))?\s*'.($short?'>':'(?:(?<=/)>|>(?:((?:(?R)|.)*?)</\1>)?)');
}
public function _secure_html_callback($m)
{
static $allowed_tags = array(
'html','body','a','table','td','tr','b','i','u','s','strike','p','img','div','span','head'
);
static $strip_blocks = NULL;
if ($strip_blocks == NULL) {$strip_blocks = explode('|','script|applet|embed|style|iframe|object|frameset|frame|noscript|select|noindex|title');}
static $allowed_params = array(
'src','alt','title'
);
$name = strtolower($m[1]);
$params = isset($m[2])?$this->_xml_parse_attrs($m[2]):array();
$content = isset($m[4])?$this->_secure_html($m[4]):NULL;
if (!in_array($name,$allowed_tags))
{
if (in_array($name,$strip_blocks)) {return '';}
else {return $content;}
}
$str = '<'.$name;
foreach ($params as $k => $v)
{
if (!in_array($k,$allowed_params)) {continue;}
$str .= ' '.$k.'="'.htmlspecialchars($v).'"';
}
$str .= ($content === NULL)?' />':'>'.$content.'</'.$name.'>';
return $str;
}
}