Вход Регистрация
Файл: adultscript-2.0.3-pro/files/libraries/framework/filter/htmlfilter.php
Строк: 143
<?php
defined
('_VALID') or die('Restricted Access!');
class 
VFilter_htmlfilter extends VFilter
{
    const 
MATCHED_NAME 1;
    const 
MATCHED_VAL  2;
    
    private 
$allowed_tags = array();
    private 
$allowed_attrs = array();
    private 
$allowed_prots = array();
    private 
$default_prot;
    private 
$wrap_length;
    
    public function 
__construct($allowed_tags=array(), $allowed_attrs=array(), $allowed_prots=array(), $default_prot=NULL$wrap_length=NULL)
    {
        
parent::__construct();
        
        
$this->allowed_tags  = ($allowed_tags) ? implode('|'$allowed_tags) : implode('|'$this->cfg['allowed_tags']);
        
$allowed_attrs          = ($allowed_attrs) ? $allowed_attrs $this->cfg['allowed_attributes'];
        foreach (
$allowed_attrs as $attr) {
            
$this->allowed_attrs[$attr] = TRUE;
        }
        
$this->allowed_prots = ($allowed_prots) ? implode('|'$allowed_prots) : implode('|'$this->cfg['allowed_protocols']);
        
$this->default_prot  = ($default_prot) ? $default_prot $this->cfg['default_protocol'];
        
$this->wrap_length   = ($wrap_length) ? $wrap_length $this->cfg['wrap_length'];
    }
    
    public function 
set_tags($tags=array())
    {
        
$this->allowed_tags    implode('|'$tags);
    }
    
    public function 
set_attrs($attrs=array())
    {
        foreach (
$attrs as $attr) {
            
$this->allowed_attrs[$attr] = TRUE;
        }
    }
    
    public function 
clean($source)
    {
//        return $this->cleanNoBreak($this->__decode(utf8_clean($source)));
        
return $this->cleanNoBreak(utf8_clean($source));
    }
    
    public function 
cleanNoBreak($html)
    {
        static 
$notags = array('<' => '&lt;''>' => '&gt;');
        
        
$matches    = array();
        
$text         = array();
        
$tags         = array();
        
$tagLog     = array();
        if (!
preg_match('/[<>]/'$html)) {
            return 
$html;
        }

        
$html         preg_replace('#<!--.*?-->#s'''$html);
        
$tokens     preg_split("#<s*(/?s*(?:$this->allowed_tags.')[^<]*?)>#si"$html, -1PREG_SPLIT_DELIM_CAPTURE);
        
$tokensSize    sizeof($tokens);
        if (
$tokensSize === 0) {
            return 
strtr($html$notags);
        }
        
        for (
$tCtr 0$tCtr $tokensSize; ++$tCtr) {
            
$token = &$tokens[$tCtr];
          
            if (
$tCtr === 0) {//if it's text, escape all tags
                
$token strtr($token$notags);
                
$token preg_replace('#([^s]{80})#'"$1n"$token);
                continue;
            }
            
            
$killTag FALSE;
    
            
preg_match('#s*/?s*([wd-]+)s*#'$token$matches);
            
$name $matches[1];
            
$newTag $name;
    
            
//cut off everything but the arguments
            
$token preg_replace('#^s*/?s*[wd-]+s*(.*?)?/?$#'"$1"$token);
            
$floor 0;
            
$charNum 0;
            
$lastMatched NULL;
            
$params = array();
            while (
$charNum strlen($token)) {//if it is bare tag, then $token will be empty, so this loop will not even start
                
$char $token{$charNum};
                if (
$char == '=') {//equality sign that is not part of param
                    //this could be one name, or several names without values
                    
$paramNames preg_split('#s#'substr($token$floor$charNum $floor), -1PREG_SPLIT_NO_EMPTY);
                    
$lastParamName array_pop($paramNames);
                    foreach (
$paramNames as $paramName) {//this will give us correct xhtml syntax: name="name"
                        
$params[] = $paramName;
                        
$params[] = $paramName;
                    }
                    
$params[] = $lastParamName;
                    
$floor $charNum 1;
                    
$lastMatched self::MATCHED_NAME;
                } elseif ((
$char == "'" || $char == '"')) {//entrering quoted string
                    
$floor $charNum 1;
                    
$charNum strpos($token$char$floor);//find the closing quote
                    
if ($charNum !== FALSE) {//if its ordinary quoted value
                        
$params[] = trim(substr($token$floor$charNum $floor));
                        ++
$charNum;
                    } else {
//if quotes does not ends inside the tag (which is possible because of the way we search for tags)
                        
$params[] = trim(substr($token$floor));
                        
$charNum strlen($token);
                    }
                    
$floor $charNum;//just in case
                    //next char will be one after the ending quote, if there are any
                
} elseif ($lastMatched == self::MATCHED_NAME
                
&& preg_match('#s#'$char)) {//we match the space after unquoted value
                    
$params[] = trim(substr($token$floor$charNum $floor));
                    
$floor $charNum 1;
                    
$lastMatched self::MATCHED_VAL;
                } elseif (
$charNum == strlen($token) - 1) {//there is something between param name width equality sign and the end of array
                    //$params[] = trim(substr($token, $floor));
                    //could be just unquoted value, or value and single-word param like noshade
                    
$paramNames preg_split('#s#'substr($token$floor), -1PREG_SPLIT_NO_EMPTY);
                    
//$params[] = array_shift($paramNames);
                    
foreach ($paramNames as $paramName) {//this will give us correct xhtml syntax: name="name"
                        
$params[] = $paramName;
                        
$params[] = $paramName;
                    }
                }
                ++
$charNum;
            }
            
            
//if it is bare tag, then sizeof($params) will be 0, so this loop will not even start
            
$paramSize sizeof($params);
            for (
$ctr 0$ctr $paramSize; ++$ctr) {
                if (
$ctr == 1){// if it's odd param i.e. value
                    
if (($params[$ctr-1] == 'src' || $params[$ctr-1] == 'href')
                    && !
preg_match("#^($this->allowed_prots)s*:#"$params[$ctr])) {
                        
$params[$ctr] = $this->default_prot.':'.$params[$ctr];//neutralize possible javascript
                    
}
                } else {
//if it's even param i.e. param name
                    
$params[$ctr] = strtolower($params[$ctr]);//needed fo matching
                    
if (!isset($this->allowed_attrs[$params[$ctr]]) OR $this->allowed_attrs[$params[$ctr]] !== TRUE) {
                        
$params[$ctr] = '_'.$params[$ctr].'_';
                        
$killTag TRUE;
                    }
                }
            }
            
            
//okay, now we need to re-construct the tag
            //$newTag is now set to a tag name
            //it is 'bare' tag, than loop will not start
            
$paramsSize sizeof($params);
            for (
$ctr 0$ctr $paramsSize$ctr += 2) {
                
$newTag .= ' '.$params[$ctr].'="'.$params[$ctr+1].'"';
            }
    
            if (
$killTag) {
                
$newTag "&lt;$newTag&gt;";
            } else {
                
$newTag "<$newTag>";
            }
            
$token $newTag;
        }
        
        foreach (
$tagLog as $openedTagName) {
            
$tokens[] = "</$openedTagName>";
        }
        
        return 
join(''$tokens);
    }
}
?>
Онлайн: 0
Реклама