Commit a7043341 authored by Bong Cosca's avatar Bong Cosca
Browse files

Optimize code: Implement single-pass escaping

parent 02b7f88e
Loading
Loading
Loading
Loading
+35 −42
Original line number Diff line number Diff line
@@ -566,22 +566,37 @@ final class Base {
		return $var;
	}

	/**
	*	Attempt to clone object
	*	@return object
	*	@return $arg object
	**/
	function dupe($arg) {
		if (method_exists('ReflectionClass','iscloneable')) {
			$ref=new ReflectionClass($arg);
			if ($ref->iscloneable())
				$arg=clone($arg);
		}
		return $arg;
	}

	/**
	*	Encode characters to equivalent HTML entities
	*	@return string
	*	@param $arg mixed
	**/
	function esc($arg) {
		if (is_string($arg))
			return $this->encode($arg);
		if (is_array($arg) || is_a($arg,'ArrayAccess'))
			foreach ($arg as &$val) {
				$val=$this->esc($val);
				unset($val);
		if (is_array($arg) || is_a($arg,'ArrayAccess')) {
			$tmp=array();
			foreach ($arg as $key=>$val)
				$tmp[$key]=$this->esc($val);
			return $tmp;
		}
		if (is_object($arg))
			foreach (get_object_vars($arg) as $key=>$val)
				$arg->$key=$this->esc($val);
			return $this->dupe($arg);
		$arg=unserialize(serialize($arg));
		if (is_string($arg))
			$arg=$this->encode($arg);
		return $arg;
	}

@@ -591,16 +606,17 @@ final class Base {
	*	@param $arg mixed
	**/
	function raw($arg) {
		if (is_string($arg))
			return $this->decode($arg);
		if (is_array($arg) || is_a($arg,'ArrayAccess'))
			foreach ($arg as &$val) {
				$val=$this->raw($val);
				unset($val);
		if (is_array($arg) || is_a($arg,'ArrayAccess')) {
			$tmp=array();
			foreach ($arg as $key=>$val)
				$tmp[$key]=$this->raw($val);
			return $tmp;
		}
		if (is_object($arg))
			foreach (get_object_vars($arg) as $key=>$val)
				$arg->$key=$this->raw($val);
			return $this->dupe($arg);
		$arg=unserialize(serialize($arg));
		if (is_string($arg))
			$arg=$this->decode($arg);
		return $arg;
	}

@@ -1842,29 +1858,6 @@ class View extends Prefab {
		return ob_get_clean();
	}

	/**
	*	Return dereferenced value
	*	@return mixed
	*	@param mixed
	**/
	function deref($arg) {
		if (is_object($arg)) {
			if (method_exists('ReflectionClass','iscloneable')) {
				$ref=new ReflectionClass($arg);
				if ($ref->iscloneable())
					$arg=clone($arg);
			}
			return $arg;
		}
		if (is_array($arg)) {
			$tmp=array();
			foreach ($arg as $key=>$val)
				$tmp[$key]=$this->deref($val);
			return $tmp;
		}
		return unserialize(serialize($arg));
	}

	/**
	*	Render template
	*	@return string
@@ -1880,7 +1873,7 @@ class View extends Prefab {
					@session_start();
				$fw->sync('SESSION');
				if (!$hive)
					$hive=$this->deref($fw->hive());
					$hive=$fw->hive();
				if ($fw->get('ESCAPE'))
					$hive=$fw->esc($hive);
				if (PHP_SAPI!='cli')
+9 −5
Original line number Diff line number Diff line
@@ -252,7 +252,8 @@ class Template extends View {
					$str=trim($self->token($expr[1]));
					if (preg_match('/^(.+?)\h*\|\h*(raw|esc|format)$/',
						$str,$parts))
						$str='Base::instance()->'.$parts[2].'('.$parts[1].')';
						$str='Base::instance()->'.$parts[2].
							'('.$parts[1].')';
					return '<?php echo '.$str.'; ?>';
				},
				$node
@@ -307,12 +308,15 @@ class Template extends View {
					$fw->hash($view).'.php')) ||
					filemtime($this->view)<filemtime($view)) {
					// Remove PHP code and comments
					$text=preg_replace('/<\?(?:php)?.+?\?>|{{\*.+?\*}}/is','',
					$text=preg_replace(
						'/<\?(?:php)?.+?\?>|{{\*.+?\*}}/is','',
						$fw->read($view));
					// Build tree structure
					for ($ptr=0,$len=strlen($text),$tree=array(),$node=&$tree,
					for ($ptr=0,$len=strlen($text),
						$tree=array(),$node=&$tree,
						$stack=array(),$depth=0,$tmp='';$ptr<$len;)
						if (preg_match('/^<(\/?)(?:F3:)?('.$this->tags.')\b'.
						if (preg_match('/^<(\/?)(?:F3:)?'.
							'('.$this->tags.')\b'.
							'((?:\h+\w+\h*=\h*(?:"(?:.+?)"|\'(?:.+?)\'))*)'.
							'\h*(\/?)>/is',substr($text,$ptr),$match)) {
							if (strlen($tmp))
@@ -377,7 +381,7 @@ class Template extends View {
					@session_start();
				$fw->sync('SESSION');
				if (!$hive)
					$hive=$this->deref($fw->hive());
					$hive=$fw->hive();
				if ($fw->get('ESCAPE'))
					$hive=$fw->esc($hive);
				if (PHP_SAPI!='cli')