Location: PHPKode > projects > Bblocked -:- Unleash The Web > bblocked-5.6.3/includes/rewrite.php
<?php
         /*********************************************************\
        ******              bblocked Rewrite class             ******
       *****                                                     *****
      ****               Copyleft (C) 2007  bblocked               ****
     ***                                                             ***
    **  This program is free software; you can redistribute it and/or  **
   **   modify it under the terms of the GNU General Public License     **
  **    as published by the Free Software Foundation; either version 2   **
 **     of the License, or (at your option) any later version.            **
 **                                                                       **
 **     This program is distributed in the hope that it will be useful,   **
  **    but WITHOUT ANY WARRANTY; without even the implied warranty of   **
   **   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   **
    **  GNU General Public License for more details.                   **
     ***                                                             ***
      ****                                                         ****
       ****               http://www.bblocked.org/               *****
        ******                                                 ******
         \*********************************************************/


/* Do not remove, prevents direct file access */
if(!defined('BB'))
	die();



// Class containing bblocked Rwrite engine

class Rewrite {

	var $_dir;
	var $_host;
	var $_tags = array("META",
                           "STYLE",
                           "SCRIPT",
                           "FORM"
                           );

	var $_events = array("ONABORT",
                           "ONBLUR",
                           "ONCHANGE",
                           "ONCLICK",
                           "ONDBLCLICK",
                           "ONDRAGDROP",
                           "ONERROR",
                           "ONFOCUS",
                           "ONKEYDOWN",
                           "ONKEYPRESS",
                           "ONKEYUP",
                           "ONLOAD",
                           "ONMOUSEDOWN",
                           "ONMOUSEOUT",
                           "ONMOUSEOVER",
                           "ONMOUSEUP",
                           "ONMOVE",
                           "ONRESET",
                           "ONRESIZE",
                           "ONSELECT",
                           "ONSUBMIT",
                           "ONUNLOAD"
                           );
	
	function Rewrite($urls, $source, $content_type='text/plain', &$output) {

		list($this->_host, $this->_dir) = $urls;
		switch(strtolower($content_type)) {
			
			case 'text/css':
				$output = $this->css_parse($source); break;
			
			case 'text/javascript':
			case 'application/x-javascript':
				$output = $this->js_parse($source); break;
				
			case 'text/html':
				$output = $this->html_parse($source);
			
			break;
			
/*			
			case 'text/xml':
			case 'application/xml':
			case 'application/xhtml+xml':
				return $this->xml_parse(); break;
			
			case 'text/plain':
			case 'text/richtext':
			case 'text/x-setext':
			case 'text/enriched':
			case 'text/x-speech':
			case 'text/tab-separated-values':
				return $source; break;
*/
			default:
				$output = $source; break;
		}
		
		if(strtolower($content_type) === 'text/html') // HTML only
		{
			if($GLOBALS['_config']['scramble_bad_words'] == 1 && $GLOBALS['_config']['scramble_bad_words'] != 2) {
			
				function sort_strlen($a, $b) {
				
					$a = strlen($a); $b = strlen($b);
					return ($a>$b ? 1 : ($a<$b ? -1 : 0));
				}
				
				$words = explode(',', $GLOBALS['_config']['bad_words']);
				
				usort($words, "sort_strlen");
				foreach($words as $word)
					$output = preg_replace("'\b\Q{$word}\E\b'i", '<script>document.write(\'' . implode(preg_split("''", $word, -1, PREG_SPLIT_NO_EMPTY), '\',\'') . '\');</script>', $output);
			}
			/*elseif($GLOBALS['_config']['scramble_bad_words'] == 2)
			{
				require($GLOBALS['_config']['rewrite_dir'].'/'.'html_base64.php'); //It already takes care of $output.
			}*/
		}
	}

	function redir_url($in, $htmlify = true) {

		return "{$GLOBALS['_config']['script_url_full']}?{$GLOBALS['_config']['arg_page']}={$GLOBALS['_config']['request_page']}".(($htmlify) ? '&amp;' : '&')."{$GLOBALS['_config']['arg_url']}=" . encode_url($in);
	}

	function alter_url($value) {
	
		if(preg_match("'^[\\\/]'", $value{0})) { $value = $this->_host . $value; }
		else if(!preg_match("'^[a-z]{3,6}:\/\/[a-z0-9]+'i", $value)) { $value = $this->_dir . preg_replace("'^\.+'", "", $value); }
		else if(preg_match("'^[a-z]{3,6}:\/\/[a-z0-9]+'i", $value)) { $value = $value; }
		else { $value = $this->_dir . $value; }

		return $value;
	}

	function css_parse($source) {

		if($GLOBALS['_config']['rewrite_css'] == false)
			return "\n\n// Stylesheets has been disabled.\n\n";
		
		foreach(preg_split("'(\@import\s*(?:\"[^\"]*\"|\'[^\']*\'|[^\s\"\'>]+))'is", $source, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY) as $code) {
		
			if(preg_match("'\@import\s*(\"[^\"]*\"|\'[^\']*\'|[^\s\"\'>]+)'is", $code, $import)) {
					
				$import[1]{0} == '"' ? $delim = '"': $import[1]{0} == "'" ? $delim = '"': $value = $import[1];
				
				!isset($value) ? $value = substr($import[1], 1, -1) : $delim = '';
				
				$source = str_replace($import[1], $delim . $this->redir_url($this->alter_url($value),0) . $delim, $source);
			}
		}
		
		$split = preg_split("'(url\s?\((?:[^\(\)]+(?:\"[^\"]*\"|\'[^\']*\')?)+\))'i", $source, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

		foreach($split as $css) {

			if(preg_match("'^url\s?\('i", $css)) {


				list($open, $value, $close) = preg_split("'(\(|\))'", $css);

				if(preg_match("'^(\"[^\"]*\"|\'[^\']*\')$'", $value)) { $delim = $value{0}; $value = substr($value, 1, -1); }

				$out .= "{$open}({$delim}" . $this->redir_url($this->alter_url($value),0) . "{$delim}){$close}";
			}

			else { $out .= $css; }
		}

		return $out;
	}

	function js_parse($source) {
	
		if(preg_match("'^\s*<\!\-\-[.\s]*\-\->\s*$'m", $source))
			list($open, $source, $close) = preg_split("'(^\s*<\!\-\-|\-\->\s*$)'is", $source, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);


		if($GLOBALS['_config']['remove_script'] == true)
			return "// Javascript has been disabled.";

		if($GLOBALS['_config']['rewrite_script'] == false)
			return $open . $source . $close;


		if(preg_match("'new\s+SWFobject\s*\((.*?)\)'i", $source, $swf) && !preg_match("'^http\:\/\/(www\.)?youtube\.com'i", $GLOBALS['_config']['request_url'])) {
			
			$url = preg_replace("'^\s*(\'[^\']*\'|\"[^\"]*\"|[^)]*).*'", "\\1", $swf[1]);
			
			$url{0} == '"' ? $delim = '"': $url{0} == "'" ? $delim = '"': $value = $url;
			!isset($value) ? $value = substr($url, 1, -1) : $delim = '"';
			
			$source = str_replace($url, $delim . $this->redir_url($this->alter_url($value)) . $delim, $source);
		}
		
		
		//$source = preg_replace("'if\s*\(\s*\w*\.location\s*(\!\=)\s*\w*\.location\s*\)\s*\{?\s*top\.location\s*\=\s*(\w*\.)?location\.href\s*\;?\s*\}?'i", "", $source);
		$source = preg_replace("'((?:top\.|window\.|document\.|self\.)?location(?:\.href)?\s*\=)'ie", "'break; // Removed redirection by bblocked'", $source);

		preg_match_all("'[\w.-]+\.(?:href|location|action)[\t\s]*\=[\t\s]*(\"[^\"]*\"|\'[^\']*\'|[^\s\"\'\;]*)'i", $source, $action);

		foreach($action[1] as $k=>$v) {

			$value = $old_funtions[$k] = $v;

			if(preg_match("'^(\"[^\"]*\"|\'[^\']*\')$'", $value)) { $delim = $value{0}; $value = substr($value, 1, -1); }
			else { $delim = '"'; }

			if(preg_match("'\.action[\t\s]*\='", $action[0][$k]))
				$new_funtions[$k] = $delim . SCRIPT_URL_FULL . $delim;

			else { $new_funtions[$k] = $delim . $this->redir_url($this->alter_url($value)) . $delim; }
		}

		$source = str_replace($old_funtions, $new_funtions, $source);


		$split = preg_split("'(window\.open\s?\((?:(?:(?:\"[^\"]*\"|\'[^\']*\'|[^\(\)]*),?)?)+\))'i", $source, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

		foreach($split as $script) {

			if(preg_match("'^window\.open\s?\('i", $script)) {

				list($open, $atrs, $close) = preg_split("'(\(|\))'", $script);
				$atr = explode(",", $atrs);

				$value = $atr[0];

				if(preg_match("'^(\"[^\"]*\"|\'[^\']*\')$'", $value)) { $delim = $value{0}; $value = substr($value, 1, -1); }
				else { $delim = '"'; }

				$atr[0] = $delim . $this->redir_url($this->alter_url($value)) . $delim;
				$out .= "{$open}(" . implode(",", $atr) . "){$close}";

			}

			else { $out .= $script; }
		}

		return $open . $out . $close;
	}

	function html_parse($source) {
	
		if($GLOBALS['_config']['remove_script'] == true)
			$source = preg_replace("'<(\/)?noscript>'i", "<\\1span>", $source);
		
		$html = preg_split("'(<(?![^a-z0-9\/])(?:[^>]+(?:\"[^\"]*\"|\'[^\']*\')?)+>)'i", $source, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
		
		foreach($html as $code) {

			if(preg_match("'^<(?![^a-z0-9\/])(?:[^>]+(?:\"[^\"]*\"|\'[^\']*\')?)+>$'i", $code)) {

				if($code{1} == "/") { $out .= $code; }

				else {
					$tag_contents = substr($code, 1, -1);
					list($tag_name, $atributes) = preg_split("'\s'", $tag_contents, 2);

					if(array_search(strtoupper($tag_name), $this->_tags) === false) {

						$parse_tag = preg_split("'([^\s\"\'<>]+(?:\"[^\"]*\"|\'[^\']*\')?)'", $tag_contents, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

						$new_tag_contents = array_shift($parse_tag);

						foreach($parse_tag as $value) {

							if(preg_match("'^\s+$'", $value)) { $new_tag_contents .= $value; }
							else { $new_tag_contents .= $this->alter_general($value); }
						}

						$out .= "<{$new_tag_contents}>";
					}
					
					else if(preg_match("'^meta\s+http-equiv\s*=\s*(?:\'|\")?refresh(?:\'|\")?\s+content\s*\=\s*(?:\'|\")?[0-9\s]+;\s*url\s*\=\s*([^\s\"\']*)(?:\'|\")?'i", $tag_contents, $matches))
						$out .= '<' . str_replace($matches[1], "{$GLOBALS['_config']['script_url_full']}?{$GLOBALS['_config']['arg_page']}={$GLOBALS['_config']['page_proxy']}&{$GLOBALS['_config']['arg_url']}=" . encode_url($matches[1]), $tag_contents) . '>';
					
					else { $out .= $code; }					
				}
			}
			
			else
				$out .= $code;
		}	
			
		return $this->alter_specific($out);
	}
	
	function alter_general($tag_contents) {

		if(strpos($tag_contents, "=") !== false) {

			list($name, $value) = explode("=", $tag_contents, 2);

			if(preg_match("'^(\"[^\"]*\"|\'[^\']*\')$'", $value)) { $delim = $value{0}; $value = substr($value, 1, -1); }
			else { $delim = '"'; }

			switch(strtoupper($name)) {

				case 'ACTION':
				case 'BACKGROUND':
				case 'HREF':
				case 'SRC':
					if(!preg_match("'^(?:\#|(?:javascript|mailto)\:)'i", $value))
						$tag_contents = "{$name}=" . $delim . $this->redir_url($this->alter_url($value)) . $delim;

					break;


				case 'STYLE':
					$tag_contents = "{$name}=" . $delim . $this->css_parse($value) . $delim;

					break;


				case 'TARGET':
					if($value == ("_top"||"_blank"))  { $value = "mainFrame"; }
					$tag_contents = "{$name}={$delim}{$value}{$delim}";

					break;


				default:
					break;
			}
		}

		return $tag_contents;
	}

	function alter_specific($in) {

		$html = preg_split("'(<(?:form|style|script)(?:(?:[^>]+(?:\"[^\"]*\"|\'[^\']*\'|[^\s\"\'>]*)?)+)?>|<\/(?:form|style|script)>)'is", $in, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
		
		foreach($html as $k=>$code) {
		
			if(isset($last) && $k<=$last)
				continue;
				
			else if(preg_match("'^<form(\s|>)'i", $code)) {

				if(preg_match("'<form.*?action\s*\=\s*(\"[^\"]*\"|\'[^\']*\'|[^\s\"\'>]+).*?>'is", $code, $action)) {
				
					$action[1]{0} == '"' ? $delim = '"': $action[1]{0} == "'" ? $delim = '"': $value = $action[1];
				
					!isset($value) ? $value = substr($action[1], 1, -1) : $delim = '"';
					
					$out .= str_replace($action[1], $delim . $GLOBALS['_config']['script_url_full'] . '/' . rawurldecode(encode_url(str_replace('://', '/', $this->alter_url($value)))) . $delim, $code);
				}
				
				else {
				
					$out .= preg_replace("'^(<form)'i", '\1 action="' . $GLOBALS['_config']['script_url'] . '/' . rawurldecode(encode_url(str_replace('://', '/', $this->alter_url($value)))) . '"', $code);
				}
			}

			else if(preg_match("'^<style(\s|>)'i", $code)) {
			
				$out .= $code . $this->css_parse($html[$k+1]) . $html[$k+2];
				$last = $k+2;
			}

			else if(preg_match("'^<script(\s|>)'i", $code)) {

				$open = $code;
				$js = $html[$k+1];
				$close = $html[$k+2];
				$last = $k+2;
				
				if(stristr($open, 'src')) {
				
					preg_match("'src\s*\=\s*(\"[^\"]*\"|\'[^\']*\'|[^\s\"\'>]+)'i", $open, $src);
					$src[1]{0} == '"' ? $delim = '"': $src[1]{0} == "'" ? $delim = '"': $value = $src[1];
					!isset($value) ? $value = substr($src[1], 1, -1) : $delim = '"';
					
					$out .= str_replace($src[1], ($GLOBALS['_config']['remove_script'] == true ? '""' : $delim . $this->redir_url($this->alter_url($value)) . $delim), $open) . $js . $close;
				}
				
				else
					$out .= $open . $this->js_parse($js) . $close;
			}
			
			else
				$out .= $code;
				
			unset($delim, $value);
		}
		
		return $out;
	}
}

?>
Return current item: Bblocked -:- Unleash The Web