HTML_filter class

From: Date: Tue, 23 Oct 2001 14:50:52 +0000
Subject: HTML_filter class
Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-2364@lists.php.net to get a copy of this message
Hello pear-dev pear-dev, As I wrote here couple weeks before I'm working on filtering class for HTML Here goes first draft version for that with example of use It can filter HTML string to escape "unsafe" tags with &lt; &gt;, and leave safe tags untouched There is possibility to filter attributes, leaving only safe attributes To add "safe" tags to class use addTag($tagname[, $attr1name, [$attr2name ...]]) method, which accepts safe tag name as first parameter, and any count of attribute names as following parameters. So, if u pass only one parameter to that method, then all attributes of that tag will be stripped. If u call this method second time with same tagname - it will substitute previous settings for that tag to get a filtered string use filter($stringtoparse) method. It accepts a string, and then return filtered variant of it. If u dont pass a parameter there, this method will return a filtered variant of internal storage string, which is setup in constructor HTML_filter($html); That's pretty it any input is welcome <?php /* vim: set expandtab tabstop=4 shiftwidth=4: */ // +----------------------------------------------------------------------+ // | PHP version 4.0 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/2_02.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Author: Maxim Vysotskiy <maxy_v@mail.ru> | // +----------------------------------------------------------------------+ // // $Id$ /** * Short description. * Class for filtering an HTML text. * * Detail description * * * @author Maxim Vysotskiy * @version 0.1 * @copyright * @since * @access public */ class HTML_filter { /** * Description * @var * @since 1.0 * @access private */ var $_storage = ""; /** * Description * @var * @since 1.0 * @access private */ var $_tagsNA = array(); /** * Description * @var * @since 1.0 * @access private */ var $_tagsWA = array(); /** * Short description. * * Detail description * @param * @since 1.0 * @access private * @return void * @throws */ function HTML_filter($str='') { $this->_storage=$str; } // end func /** * Short description. * * Detail description * @param * @since 1.0 * @access private * @return void * @throws */ function _addTag($tag) { $fnd=false; reset ($this->_tagsNA); while (list($key,$val) = each($this->_tagsNA)) { if (strtoupper($val)==strtoupper($tag)) { $fnd=true; break; } } if (!$fnd) { array_push ($this->_tagsNA,$tag); } } // end func /** * Short description. * * Detail description * @param * @since 1.0 * @access private * @return void * @throws */ function removeTag($tag) { $fnd=false; reset ($this->_tagsNA); while (list($key,$val) = each($this->_tagsNA)) { if (strtoupper($val)==strtoupper($tag)) { $fnd=true; break; } } if ($fnd) { unset($this->_tagsNA[$key]); return true; } reset ($this->_tagsWA); while (list($key,$val) = each($this->_tagsWA)) { if (strtoupper($val[0])==strtoupper($tag)) { $fnd=true; break; } } if ($fnd) { unset($this->_tagsWA[$key]); return true; } } // end func /** * Short description. * * Detail description * @param * @since 1.0 * @access private * @return void * @throws */ function addTag($tag) { if (func_num_args()==1) { return $this->_addTag($tag); } reset ($this->_tagsWA); while (list($key,$val) = each($this->_tagsWA)) { if (strtoupper($val[0])==strtoupper($tag)) { $fnd=true; break; } } $args=func_get_args(); if ($fnd) { $this->_tagsWA[$key]=$args; } else { array_push ($this->_tagsWA,$args); } } // end func /** * Short description. * * Detail description * @param * @since 1.0 * @access private * @return void * @throws */ function _process($html,$arr_tags,$tags_a) { //this function has two filters: //first (tags that are in $arr_tags array) leave these tags, but strips all attrinutes from it //second (tags that) // why should there be a null character $html = preg_replace('/\0/', '', $html); // convert the ampersants to null characters $html = preg_replace('/\&/', '\0', $html); // convert the sharp brackets to there html code and excape special charachters such as " $html = preg_replace('/</', '&lt;', $html); $html = preg_replace('/>/', '&gt;', $html); // restore the tags that are concidered safe $tags=implode('|',$arr_tags); if ($tags) { //this statement not only escapes "unsafe" tags, but also removes all attributes from SAFE tags $html = preg_replace("/&lt;(($tags)(|\s.*)?)&gt;/i", '<\1>', $html); $html = preg_replace("/&lt;\\/($tags)&gt;/i", '</\1>', $html); } if (count($tags_a)){ while (list($k,$v)=each($tags_a)) { $a_tags.='|'.$v[0]; preg_match_all ("/&lt;((".$v[0].").*?)&gt;/i",$html,$out, PREG_PATTERN_ORDER); for ($i=0;$i<count($out[0]);$i++) { //echo $out[0][$i]."\n"; $tag_str=''; $pos=strpos($html,$out[0][$i]); if (!(is_string($pos) && !$pos)) { $tag_str.='<'.$v[0]; for ($j=1;$j<count($v);$j++) { if (preg_match( '/\\s*'.$v[$j].'(\\s*=\\s*(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9.\\/:;+*%?!&$()_#=~\'"]*))?/i' ,substr(substr($out[0][$i],4+strlen($v[0])),0,-4),$attrs_matches)) $tag_str.=' '.$v[$j].(strlen($attrs_matches[1])?'='.$attrs_matches[2]:''); } $tag_str.='>'; $html=substr($html,0,$pos).$tag_str.substr($html,$pos+strlen($out[0][$i])); } } } $a_tags=substr($a_tags,1); $html = preg_replace("/&lt;\\/($a_tags)&gt;/i", '</\1>', $html); } // restore the ampersants $html = preg_replace('/\0/', '&', $html); return($html); } // end func /** * Short description. * * Detail description * @param * @since 1.0 * @access private * @return void * @throws */ function filter($html='') { return $this->_process((strlen($html)?$html:$this->_storage),$this->_tagsNA,$this->_tagsWA); } // end func /** * Short description. * * Detail description * @param * @since 1.0 * @access private * @return void * @throws */ function printNATags() { echo "<PRE>"; reset ($this->_tagsNA); while (list($key,$val)=each($this->_tagsNA)) { echo "\n$val"; } echo "</PRE>"; } // end func /** * Short description. * * Detail description * @param * @since 1.0 * @access private * @return void * @throws */ function printWATags() { echo "<PRE>"; reset ($this->_tagsWA); while (list($key,$val)=each($this->_tagsWA)) { $f=true; reset ($val); while (list($k,$v)=each($val)) { if (!$f) { echo "\t"; } $f=false; echo $v."\n"; } } echo "</PRE>"; } // end func } // end class $html=' <!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title> New Document </title> <meta name="Generator" content="EditPlus"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> </head> <body> <!-- header --> <table cellpadding="0" cellspacing="0" border="0" bgcolor="#0087e6" width="740"> <tr> <td background="img/back.jpg" align="center" width="180"><img src="img/logo.gif" width="180" height="49" border="0" alt=" mobil.by "></td> <td align="right" background="img/back.jpg"><img src="img/468_01.gif" width="468" height="60" hspace="6" vspace="6" border="0" alt=""></td> </tr> <tr> <td colspan="2" height="1" background="img/dot_h.gif"><img src="img/x.gif" width="1" height="1" border="0"></td> </tr> <tr bgcolor="#339feb"> <td colspan="2"> <table cellpadding="2" cellspacing="0" border="0" width="100%"> <tr> <td align="left" class="taxText"><a href="index02.html"><b>mobil.by</a> \ каталог</b></td> <td align="right"> <table cellpadding="2" cellspacing="0" border="0"> <tr><form> <td><input type="text" value=" поиск" class="form" style="width: 130px"></td> <td><input type="image" src="img/but_srch.gif" width="29" height="14" border="0" alt=" Искать " hspace="2"></td> </tr></form> </table> </td> </tr> </table> </td> </tr> <tr> <td colspan="2" bgcolor="#ffffff"><img src="img/x.gif" width="1" height="4" border="0" alt=""></td> </tr> </table> <!-- end header --> <!-- body --> </body> </html> '; $p=new HTML_filter($html); $p->addTag('a','href','target'); $p->addTag('img','src','border'); $p->addTag('b'); $p->addTag('t'); $p->addTag('body'); $p->addTag('font'); $p->addTag('hr'); $p->addTag('h1','style','color'); $p->printWATags(); echo "<HR>"; echo "<PRE>"; echo $p->filter(); echo "</PRE>"; ?> --------------------- Maxim Vysotskiy VPISystems Programmer Minsk mailto:vysotmax@vpi-minsk.com ICQ: 44197964 ---------------------

« previous php.pear.dev (#2364) next »