GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — develop ( 92c79f...f4bfda )
by gyeong-won
06:35
created

TemplateHandler::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 23
rs 9.552
c 0
b 0
f 0
1
<?php
2
/* Copyright (C) NAVER <http://www.navercorp.com> */
3
4
/**
5
 * @class TemplateHandler
6
 * @author NAVER ([email protected])
7
 * template compiler
8
 * @version 0.1
9
 * @remarks It compiles template file by using regular expression into php
10
 *          code, and XE caches compiled code for further uses
11
 */
12
class TemplateHandler
13
{
14
15
	private $compiled_path = 'files/cache/template_compiled/'; ///< path of compiled caches files
16
	private $path = NULL; ///< target directory
17
	private $filename = NULL; ///< target filename
18
	private $file = NULL; ///< target file (fullpath)
19
	private $xe_path = NULL;  ///< XpressEngine base path
20
	private $web_path = NULL; ///< tpl file web path
21
	private $compiled_file = NULL; ///< tpl file web path
22
	private $config = NULL;
23
	private $skipTags = NULL;
24
	private $handler_mtime = 0;
25
	private $autoescape = false;
26
	static private $rootTpl = NULL;
27
28
	/**
29
	 * constructor
30
	 * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
31
	 */
32
	public function __construct()
33
	{
34
		ini_set('pcre.jit', "0");
35
		$this->xe_path = rtrim(getScriptPath(), '/');
36
		$this->compiled_path = _XE_PATH_ . $this->compiled_path;
37
		$this->config = new stdClass();
38
39
		$this->ignoreEscape = array(
0 ignored issues
show
Bug introduced by
The property ignoreEscape does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
40
			'functions' => function ($m) {
41
				$list = array(
42
					'htmlspecialchars',
43
					'nl2br',
44
				);
45
				return preg_match('/^(' . implode('|', $list) . ')\(/', $m[1]);
46
			},
47
			'lang' => function ($m) {
48
				// 다국어
49
				return preg_match('/^\$lang\-\>/', trim($m[1]));
50
			}
51
		);
52
53
		$this->dbinfo = Context::getDBInfo();
0 ignored issues
show
Bug introduced by
The property dbinfo does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
54
	}
55
56
	/**
57
	 * returns TemplateHandler's singleton object
58
	 * @return TemplateHandler instance
59
	 */
60
	static public function &getInstance()
61
	{
62
		static $oTemplate = NULL;
63
64
		if(__DEBUG__ == 3)
65
		{
66
			if(!isset($GLOBALS['__TemplateHandlerCalled__']))
67
			{
68
				$GLOBALS['__TemplateHandlerCalled__'] = 1;
69
			}
70
			else
71
			{
72
				$GLOBALS['__TemplateHandlerCalled__']++;
73
			}
74
		}
75
76
		if(!$oTemplate)
77
		{
78
			$oTemplate = new TemplateHandler();
79
		}
80
81
		return $oTemplate;
82
	}
83
84
	/**
85
	 * set variables for template compile
86
	 * @param string $tpl_path
87
	 * @param string $tpl_filename
88
	 * @param string $tpl_file
89
	 * @return void
90
	 */
91
	protected function init($tpl_path, $tpl_filename, $tpl_file = '')
92
	{
93
		// verify arguments
94
		if(substr($tpl_path, -1) != '/')
95
		{
96
			$tpl_path .= '/';
97
		}
98
		if(!is_dir($tpl_path))
99
		{
100
			return;
101
		}
102
		if(!file_exists($tpl_path . $tpl_filename) && file_exists($tpl_path . $tpl_filename . '.html'))
103
		{
104
			$tpl_filename .= '.html';
105
		}
106
107
		// create tpl_file variable
108
		if(!$tpl_file)
109
		{
110
			$tpl_file = $tpl_path . $tpl_filename;
111
		}
112
113
		// set template file infos.
114
		$this->path = $tpl_path;
115
		$this->filename = $tpl_filename;
116
		$this->file = $tpl_file;
117
118
		$this->web_path = $this->xe_path . '/' . ltrim(preg_replace('@^' . preg_quote(_XE_PATH_, '@') . '|\./@', '', $this->path), '/');
119
120
		// get compiled file name
121
		$hash = md5($this->file . __XE_VERSION__);
122
		$this->compiled_file = "{$this->compiled_path}{$hash}.compiled.php";
123
124
		$this->autoescape = $this->isAutoescape();
125
126
		// compare various file's modified time for check changed
127
		$this->handler_mtime = filemtime(__FILE__);
128
129
		$skip = array('');
0 ignored issues
show
Unused Code introduced by
$skip is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
130
	}
131
132
	/**
133
	 * compiles specified tpl file and execution result in Context into resultant content
134
	 * @param string $tpl_path path of the directory containing target template file
135
	 * @param string $tpl_filename target template file's name
136
	 * @param string $tpl_file if specified use it as template file's full path
137
	 * @return string Returns compiled result in case of success, NULL otherwise
138
	 */
139
	public function compile($tpl_path, $tpl_filename, $tpl_file = '')
140
	{
141
		$buff = false;
142
143
		// store the starting time for debug information
144
		if(__DEBUG__ == 3)
145
		{
146
			$start = getMicroTime();
147
		}
148
149
		// initiation
150
		$this->init($tpl_path, $tpl_filename, $tpl_file);
151
152
		// if target file does not exist exit
153
		if(!$this->file || !file_exists($this->file))
154
		{
155
			return "Err : '{$this->file}' template file does not exists.";
156
		}
157
158
		// for backward compatibility
159
		if(is_null(self::$rootTpl))
160
		{
161
			self::$rootTpl = $this->file;
162
		}
163
164
		$source_template_mtime = filemtime($this->file);
165
		$latest_mtime = $source_template_mtime > $this->handler_mtime ? $source_template_mtime : $this->handler_mtime;
166
167
		// cache control
168
		$oCacheHandler = CacheHandler::getInstance('template');
169
170
		// get cached buff
171
		if($oCacheHandler->isSupport())
172
		{
173
			$cache_key = 'template:' . $this->file;
174
			$buff = $oCacheHandler->get($cache_key, $latest_mtime);
175
		}
176
		else
177
		{
178
			if(is_readable($this->compiled_file) && filemtime($this->compiled_file) > $latest_mtime && filesize($this->compiled_file))
179
			{
180
				$buff = 'file://' . $this->compiled_file;
181
			}
182
		}
183
184
		if($buff === FALSE)
185
		{
186
			$buff = $this->parse();
187
			if($oCacheHandler->isSupport())
188
			{
189
				$oCacheHandler->put($cache_key, $buff);
0 ignored issues
show
Bug introduced by
The variable $cache_key does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
190
			}
191
			else
192
			{
193
				FileHandler::writeFile($this->compiled_file, $buff);
194
			}
195
		}
196
197
		$output = $this->_fetch($buff);
0 ignored issues
show
Bug introduced by
It seems like $buff can also be of type boolean or null; however, TemplateHandler::_fetch() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
198
199
		if($__templatehandler_root_tpl == $this->file)
0 ignored issues
show
Bug introduced by
The variable $__templatehandler_root_tpl seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
200
		{
201
			$__templatehandler_root_tpl = null;
0 ignored issues
show
Unused Code introduced by
$__templatehandler_root_tpl is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
202
		}
203
204
		// store the ending time for debug information
205
		if(__DEBUG__ == 3)
206
		{
207
			$GLOBALS['__template_elapsed__'] += getMicroTime() - $start;
0 ignored issues
show
Bug introduced by
The variable $start does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
208
		}
209
210
		return $output;
211
	}
212
213
	/**
214
	 * compile specified file and immediately return
215
	 * @param string $tpl_path path of the directory containing target template file
216
	 * @param string $tpl_filename target template file's name
217
	 * @return string Returns compiled content in case of success or NULL in case of failure
218
	 */
219
	public function compileDirect($tpl_path, $tpl_filename)
220
	{
221
		$this->init($tpl_path, $tpl_filename, null);
222
223
		// if target file does not exist exit
224
		if(!$this->file || !file_exists($this->file))
225
		{
226
			Context::close();
227
			exit("Cannot find the template file: '{$this->file}'");
228
		}
229
230
		return $this->parse();
231
	}
232
233
	/**
234
	 * parse syntax.
235
	 * @param string $buff template file
236
	 * @return string compiled result in case of success or NULL in case of error
237
	 */
238
	protected function parse($buff = null)
239
	{
240
		if(is_null($buff))
241
		{
242
			if(!is_readable($this->file))
243
			{
244
				return;
245
			}
246
247
			// read tpl file
248
			$buff = FileHandler::readFile($this->file);
249
		}
250
251
		// HTML tags to skip
252
		if(is_null($this->skipTags))
253
		{
254
			$this->skipTags = array('marquee');
255
		}
256
257
		// reset config for this buffer (this step is necessary because we use a singleton for every template)
258
		$previous_config = clone $this->config;
259
		$this->config = new stdClass();
260
		$this->config->autoescape = null;
261
262
		if(preg_match('/\<config( [^\>\/]+)/', $buff, $config_match))
263
		{
264
			if(preg_match_all('@ (?<name>\w+)="(?<value>[^"]+)"@', $config_match[1], $config_matches, PREG_SET_ORDER))
265
			{
266
				foreach($config_matches as $config_match)
267
				{
268
					if($config_match['name'] === 'autoescape')
269
					{
270
						$this->config->autoescape = $config_match['value'];
271
					}
272
				}
273
			}
274
		}
275
276
		if($this->config->autoescape === 'on') $this->autoescape = true;
277
278
		// replace comments
279
		$buff = preg_replace('@<!--//.*?-->@s', '', $buff);
280
281
		// replace value of src in img/input/script tag
282
		$buff = preg_replace_callback('/<(?:img|input|script)(?:[^<>]*?)(?(?=cond=")(?:cond="[^"]+"[^<>]*)+|)[^<>]* src="(?!(?:https?|file):\/\/|[\/\{])([^"]+)"/is', array($this, '_replacePath'), $buff);
283
284
		// replace loop and cond template syntax
285
		$buff = $this->_parseInline($buff);
286
287
		// include, unload/load, import
288
		$buff = preg_replace_callback('/{(@[\s\S]+?|(?=\$\w+|_{1,2}[A-Z]+|[!\(+-]|\w+(?:\(|::)|\d+|[\'"].*?[\'"]).+?)}|<(!--[#%])?(include|import|(un)?load(?(4)|(?:_js_plugin)?)|config)(?(2)\(["\']([^"\']+)["\'])(.*?)(?(2)\)--|\/)>|<!--(@[a-z@]*)([\s\S]*?)-->(\s*)/', array($this, '_parseResource'), $buff);
289
290
		// remove block which is a virtual tag
291
		$buff = preg_replace('@</?block\s*>@is', '', $buff);
292
293
		// form auto generation
294
		$temp = preg_replace_callback('/(<form(?:<\?php.+?\?>|[^<>]+)*?>)(.*?)(<\/form>)/is', array($this, '_compileFormAuthGeneration'), $buff);
295
		if($temp)
296
		{
297
			$buff = $temp;
298
		}
299
300
		// prevent from calling directly before writing into file
301
		$buff = '<?php if(!defined("__XE__"))exit;?>' . $buff;
302
303
		// remove php script reopening
304
		$buff = preg_replace(array('/(\n|\r\n)+/', '/(;)?( )*\?\>\<\?php([\n\t ]+)?/'), array("\n", ";\n"), $buff);
305
306
		// restore config to previous value
307
		$this->config = $previous_config;
308
309
		return $buff;
310
	}
311
312
	/**
313
	 * preg_replace_callback handler
314
	 * 1. remove ruleset from form tag
315
	 * 2. add hidden tag with ruleset value
316
	 * 3. if empty default hidden tag, generate hidden tag (ex:mid, vid, act...)
317
	 * 4. generate return url, return url use in server side validator
318
	 * @param array $matches
319
	 * @return string
320
	 */
321
	private function _compileFormAuthGeneration($matches)
322
	{
323
		// form ruleset attribute move to hidden tag
324
		if($matches[1])
325
		{
326
			preg_match('/ruleset="([^"]*?)"/is', $matches[1], $m);
327
			if($m[0])
328
			{
329
				$matches[1] = preg_replace('/' . addcslashes($m[0], '?$') . '/i', '', $matches[1]);
330
331
				if(strpos($m[1], '@') !== FALSE)
332
				{
333
					$path = str_replace('@', '', $m[1]);
334
					$path = './files/ruleset/' . $path . '.xml';
335
				}
336
				else if(strpos($m[1], '#') !== FALSE)
337
				{
338
					$fileName = str_replace('#', '', $m[1]);
339
					$fileName = str_replace('<?php echo ', '', $fileName);
340
					$fileName = str_replace(' ?>', '', $fileName);
341
					$path = '#./files/ruleset/' . $fileName . '.xml';
342
343
					preg_match('@(?:^|\.?/)(modules/[\w-]+)@', $this->path, $mm);
344
					$module_path = $mm[1];
345
					list($rulsetFile) = explode('.', $fileName);
346
					$autoPath = $module_path . '/ruleset/' . $rulsetFile . '.xml';
347
					$m[1] = $rulsetFile;
348
				}
349
				else if(preg_match('@(?:^|\.?/)(modules/[\w-]+)@', $this->path, $mm))
350
				{
351
					$module_path = $mm[1];
352
					$path = $module_path . '/ruleset/' . $m[1] . '.xml';
353
				}
354
355
				$matches[2] = '<input type="hidden" name="ruleset" value="' . $m[1] . '" />' . $matches[2];
356
				//assign to addJsFile method for js dynamic recache
357
				$matches[1] = '<?php Context::addJsFile("' . $path . '", FALSE, "", 0, "body", TRUE, "' . $autoPath . '") ?' . '>' . $matches[1];
0 ignored issues
show
Bug introduced by
The variable $path does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $autoPath does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
358
			}
359
		}
360
361
		// if not exists default hidden tag, generate hidden tag
362
		preg_match_all('/<input[^>]* name="(act|mid|vid)"/is', $matches[2], $m2);
363
		$checkVar = array('act', 'mid', 'vid');
364
		$resultArray = array_diff($checkVar, $m2[1]);
365
		if(is_array($resultArray))
366
		{
367
			$generatedHidden = '';
368
			foreach($resultArray AS $key => $value)
369
			{
370
				$generatedHidden .= '<input type="hidden" name="' . $value . '" value="<?php echo $__Context->' . $value . ' ?>" />';
371
			}
372
			$matches[2] = $generatedHidden . $matches[2];
373
		}
374
375
		// return url generate
376
		if(!preg_match('/no-error-return-url="true"/i', $matches[1]))
377
		{
378
			preg_match('/<input[^>]*name="error_return_url"[^>]*>/is', $matches[2], $m3);
379
			if(!$m3[0])
380
				$matches[2] = '<input type="hidden" name="error_return_url" value="<?php echo htmlspecialchars(getRequestUriByServerEnviroment(), ENT_COMPAT | ENT_HTML401, \'UTF-8\', false) ?>" />' . $matches[2];
381
		}
382
		else
383
		{
384
			$matches[1] = preg_replace('/no-error-return-url="true"/i', '', $matches[1]);
385
		}
386
387
		$matches[0] = '';
388
		return implode($matches);
389
	}
390
391
	/**
392
	 * fetch using ob_* function
393
	 * @param string $buff if buff is not null, eval it instead of including compiled template file
394
	 * @return string
395
	 */
396
	private function _fetch($buff)
397
	{
398
		if(!$buff)
399
		{
400
			return;
401
		}
402
403
		$__Context = &$GLOBALS['__Context__'];
404
		$__Context->tpl_path = $this->path;
405
406
		if($_SESSION['is_logged'])
407
		{
408
			$__Context->logged_info = Context::get('logged_info');
409
		}
410
411
		$level = ob_get_level();
412
		ob_start();
413
		if(substr($buff, 0, 7) == 'file://')
414
		{
415
			if(__DEBUG__)
416
			{
417
				//load cache file from disk
418
				$eval_str = FileHandler::readFile(substr($buff, 7));
419
				$eval_str_buffed = "?>" . $eval_str;
420
				@eval($eval_str_buffed);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
421
				$error_info = error_get_last();
422
				//parse error
423
				if ($error_info['type'] == 4)
424
				{
425
				    throw new Exception("Error Parsing Template - {$error_info['message']} in template file {$this->file}");
426
				}
427
			}
428
			else
429
			{
430
				include(substr($buff, 7));
431
			}
432
		}
433
		else
434
		{
435
			$eval_str = "?>" . $buff;
436
			@eval($eval_str);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
437
			$error_info = error_get_last();
438
			//parse error
439
			if ($error_info['type'] == 4)
440
			{
441
			    throw new Exception("Error Parsing Template - {$error_info['message']} in template file {$this->file}");
442
			}
443
		}
444
445
		$contents = '';
446
		while (ob_get_level() - $level > 0) {
447
			$contents .= ob_get_contents();
448
			ob_end_clean();
449
		}
450
		return $contents;
451
	}
452
453
	/**
454
	 * preg_replace_callback hanlder
455
	 *
456
	 * replace image path
457
	 * @param array $match
458
	 *
459
	 * @return string changed result
460
	 */
461
	private function _replacePath($match)
462
	{
463
		//return origin conde when src value started '${'.
464
		if(preg_match('@^\${@', $match[1]))
465
		{
466
			return $match[0];
467
		}
468
469
		//return origin code when src value include variable.
470
		if(preg_match('@^[\'|"]\s*\.\s*\$@', $match[1]))
471
		{
472
			return $match[0];
473
		}
474
475
		$src = preg_replace('@^(\./)+@', '', trim($match[1]));
476
477
		$src = $this->web_path . $src;
478
		$src = str_replace('/./', '/', $src);
479
480
		// for backward compatibility
481
		$src = preg_replace('@/((?:[\w-]+/)+)\1@', '/\1', $src);
482
483
		while(($tmp = preg_replace('@[^/]+/\.\./@', '', $src, 1)) !== $src)
484
		{
485
			$src = $tmp;
486
		}
487
488
		return substr($match[0], 0, -strlen($match[1]) - 6) . "src=\"{$src}\"";
489
	}
490
491
	/**
492
	 * replace loop and cond template syntax
493
	 * @param string $buff
494
	 * @return string changed result
495
	 */
496
	private function _parseInline($buff)
497
	{
498
		if(!preg_match_all('/<([a-zA-Z]+\d?)(?:\s)/', $buff, $match))
499
		{
500
			return $buff;
501
		}
502
503
		$tags = array_diff(array_unique($match[1]), $this->skipTags);
504
505
		if(!count($tags))
506
		{
507
			return $buff;
508
		}
509
510
		$tags = '(?:' . implode('|', $tags) . ')';
511
		$split_regex = "@(<(?>/?{$tags})(?>[^<>\{\}\"']+|<!--.*?-->|{[^}]+}|\".*?\"|'.*?'|.)*?>)@s";
512
513
		$nodes = preg_split($split_regex, $buff, -1, PREG_SPLIT_DELIM_CAPTURE);
514
515
		// list of self closing tags
516
		$self_closing = array('area' => 1, 'base' => 1, 'basefont' => 1, 'br' => 1, 'hr' => 1, 'input' => 1, 'img' => 1, 'link' => 1, 'meta' => 1, 'param' => 1, 'frame' => 1, 'col' => 1);
517
518
		for($idx = 1, $node_len = count($nodes); $idx < $node_len; $idx+=2)
519
		{
520
			if(!($node = $nodes[$idx]))
521
			{
522
				continue;
523
			}
524
525
			if(preg_match_all('@\s(loop|cond)="([^"]+)"@', $node, $matches))
526
			{
527
				// this tag
528
				$tag = substr($node, 1, strpos($node, ' ') - 1);
529
530
				// if the vale of $closing is 0, it means 'skipping'
531
				$closing = 0;
532
533
				// process opening tag
534
				foreach($matches[1] as $n => $stmt)
535
				{
536
					$expr = $matches[2][$n];
537
					$expr = $this->_replaceVar($expr);
538
					$closing++;
539
540
					switch($stmt)
541
					{
542
						case 'cond':
543
							$nodes[$idx - 1] .= "<?php if({$expr}){ ?>";
544
							break;
545
						case 'loop':
546
							if(!preg_match('@^(?:(.+?)=>(.+?)(?:,(.+?))?|(.*?;.*?;.*?)|(.+?)\s*=\s*(.+?))$@', $expr, $expr_m))
547
							{
548
								break;
549
							}
550
							if($expr_m[1])
551
							{
552
								$expr_m[1] = trim($expr_m[1]);
553
								$expr_m[2] = trim($expr_m[2]);
554
								if($expr_m[3])
555
								{
556
									$expr_m[2] .= '=>' . trim($expr_m[3]);
557
								}
558
								$nodes[$idx - 1] .= "<?php if({$expr_m[1]}&&count({$expr_m[1]}))foreach({$expr_m[1]} as {$expr_m[2]}){ ?>";
559
							}
560
							elseif($expr_m[4])
561
							{
562
								$nodes[$idx - 1] .= "<?php for({$expr_m[4]}){ ?>";
563
							}
564
							elseif($expr_m[5])
565
							{
566
								$nodes[$idx - 1] .= "<?php while({$expr_m[5]}={$expr_m[6]}){ ?>";
567
							}
568
							break;
569
					}
570
				}
571
				$node = preg_replace('@\s(loop|cond)="([^"]+)"@', '', $node);
572
573
				// find closing tag
574
				$close_php = '<?php ' . str_repeat('}', $closing) . ' ?>';
575
				//  self closing tag
576
				if($node{1} == '!' || substr($node, -2, 1) == '/' || isset($self_closing[$tag]))
577
				{
578
					$nodes[$idx + 1] = $close_php . $nodes[$idx + 1];
579
				}
580
				else
581
				{
582
					$depth = 1;
583
					for($i = $idx + 2; $i < $node_len; $i+=2)
584
					{
585
						$nd = $nodes[$i];
586
						if(strpos($nd, $tag) === 1)
587
						{
588
							$depth++;
589
						}
590
						elseif(strpos($nd, '/' . $tag) === 1)
591
						{
592
							$depth--;
593
							if(!$depth)
594
							{
595
								$nodes[$i - 1] .= $nodes[$i] . $close_php;
596
								$nodes[$i] = '';
597
								break;
598
							}
599
						}
600
					}
601
				}
602
			}
603
604
			if(strpos($node, '|cond="') !== false)
605
			{
606
				$node = preg_replace('@(\s[-\w:]+(?:="[^"]+?")?)\|cond="(.+?)"@s', '<?php if($2){ ?>$1<?php } ?>', $node);
607
				$node = $this->_replaceVar($node);
608
			}
609
610
			if($nodes[$idx] != $node)
611
			{
612
				$nodes[$idx] = $node;
613
			}
614
		}
615
616
		$buff = implode('', $nodes);
617
618
		return $buff;
619
	}
620
621
	/**
622
	 * preg_replace_callback hanlder
623
	 * replace php code.
624
	 * @param array $m
625
	 * @return string changed result
626
	 */
627
	private function _parseResource($m)
628
	{
629
		$escape_option = 'noescape';
630
631
		if($this->autoescape)
632
		{
633
			$escape_option = 'autoescape';
634
		}
635
636
		// 템플릿에서 명시적으로 off이면 'noescape' 적용
637
		if ($this->config->autoescape === 'off') {
638
			$escape_option = 'noescape';
639
		}
640
641
		// {@ ... } or {$var} or {func(...)}
642
		if($m[1])
643
		{
644
			if(preg_match('@^(\w+)\(@', $m[1], $mm) && !function_exists($mm[1]))
645
			{
646
				return $m[0];
647
			}
648
			
649
			if($m[1]{0} == '@')
650
			{
651
				$m[1] = $this->_replaceVar(substr($m[1], 1));
652
				return "<?php {$m[1]} ?>";
653
			}
654
			else
655
			{
656
				// Get escape options.
657
				foreach ($this->ignoreEscape as $key => $value)
658
				{
659
					if($this->ignoreEscape[$key]($m))
660
					{
661
						$escape_option = 'noescape';
662
						break;
663
					}
664
				}
665
666
				// Separate filters from variable.
667
				if (preg_match('@^(.+?)(?<![|\s])((?:\|[a-z]{2}[a-z0-9_]+(?::.+)?)+)$@', $m[1], $mm))
668
				{
669
					$m[1] = $mm[1];
670
					$filters = array_map('trim', explode_with_escape('|', substr($mm[2], 1)));
671
				}
672
				else
673
				{
674
					$filters = array();
675
				}
676
677
				// Process the variable.
678
				$var = self::_replaceVar($m[1]);
679
680
				// Apply filters.
681
				foreach ($filters as $filter)
682
				{
683
					// Separate filter option from the filter name.
684
					if (preg_match('/^([a-z0-9_-]+):(.+)$/', $filter, $matches))
685
					{
686
						$filter = $matches[1];
687
						$filter_option = $matches[2];
688
						if (!self::_isVar($filter_option) && !preg_match("/^'.*'$/", $filter_option) && !preg_match('/^".*"$/', $filter_option))
689
						{
690
							$filter_option = "'" . escape_sqstr($filter_option) . "'";
691
						}
692
						else
693
						{
694
							$filter_option = self::_replaceVar($filter_option);
695
						}
696
					}
697
					else
698
					{
699
						$filter_option = null;
700
					}
701
702
					// Apply each filter.
703
					switch ($filter)
704
					{
705
						case 'auto':
706
						case 'autoescape':
707
						case 'escape':
708
						case 'noescape':
709
							$escape_option = $filter;
710
							break;
711
712
						case 'escapejs':
713
							$var = "escape_js({$var})";
714
							$escape_option = 'noescape';
715
							break;
716
717
						case 'json':
718
							$var = "json_encode({$var})";
719
							$escape_option = 'noescape';
720
							break;
721
722
						case 'strip':
723
						case 'strip_tags':
724
							$var = $filter_option ? "strip_tags({$var}, {$filter_option})" : "strip_tags({$var})";
725
							$escape_option = 'noescape';
726
							break;
727
728
						case 'trim':
729
							$var = "trim({$var})";
730
							break;
731
732
						case 'urlencode':
733
							$var = "rawurlencode({$var})";
734
							$escape_option = 'noescape';
735
							break;
736
737
						case 'lower':
738
							$var = "strtolower({$var})";
739
							break;
740
741
						case 'upper':
742
							$var = "strtoupper({$var})";
743
							break;
744
745
						case 'nl2br':
746
							$var = $this->_applyEscapeOption($var, $escape_option);
747
							$var = "nl2br({$var})";
748
							$escape_option = 'noescape';
749
							break;
750
751
						case 'join':
752
							$var = $filter_option ? "implode({$filter_option}, {$var})" : "implode(', ', {$var})";
753
							$escape_option = 'noescape';
754
							break;
755
756
						case 'date':
757
							$var = $filter_option ? "getDisplayDateTime(ztime({$var}), {$filter_option})" : "getDisplayDateTime(ztime({$var}), 'Y-m-d H:i:s')";
758
							$escape_option = 'noescape';
759
							break;
760
761
						case 'format':
762
						case 'number_format':
763
							$var = $filter_option ? "number_format({$var}, {$filter_option})" : "number_format({$var})";
764
							$escape_option = 'noescape';
765
							break;
766
767
						case 'link':
768
							$var = $this->_applyEscapeOption($var, 'autoescape');
769
							if ($filter_option)
0 ignored issues
show
Bug Best Practice introduced by
The expression $filter_option of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
770
							{
771
								$filter_option = $this->_applyEscapeOption($filter_option, 'autoescape');
772
								$var = "'<a href=\"' . {$filter_option} . '\">' . {$var} . '</a>'";
773
							}
774
							else
775
							{
776
								$var = "'<a href=\"' . {$var} . '\">' . {$var} . '</a>'";
777
							}
778
							$escape_option = 'noescape';
779
							break;
780
781
						default:
782
							$filter = escape_sqstr($filter);
783
							$var = "'INVALID FILTER ({$filter})'";
784
							$escape_option = 'noescape';
785
					}
786
				}
787
788
				// Apply the escape option and return.
789
				return '<?php echo ' . $this->_applyEscapeOption($var, $escape_option) . ' ?>';
790
			}
791
		}
792
793
		if($m[3])
794
		{
795
			$attr = array();
796
			if($m[5])
797
			{
798 View Code Duplication
				if(preg_match_all('@,(\w+)="([^"]+)"@', $m[6], $mm))
799
				{
800
					foreach($mm[1] as $idx => $name)
801
					{
802
						$attr[$name] = $mm[2][$idx];
803
					}
804
				}
805
				$attr['target'] = $m[5];
806
			}
807 View Code Duplication
			else
808
			{
809
				if(!preg_match_all('@ (\w+)="([^"]+)"@', $m[6], $mm))
810
				{
811
					return $m[0];
812
				}
813
				foreach($mm[1] as $idx => $name)
814
				{
815
					$attr[$name] = $mm[2][$idx];
816
				}
817
			}
818
819
			switch($m[3])
820
			{
821
				// <!--#include--> or <include ..>
822
				case 'include':
823
					if(!$this->file || !$attr['target'])
824
					{
825
						return '';
826
					}
827
828
					$pathinfo = pathinfo($attr['target']);
829
					$fileDir = $this->_getRelativeDir($pathinfo['dirname']);
830
831
					if(!$fileDir)
832
					{
833
						return '';
834
					}
835
836
					return "<?php \$__tpl=TemplateHandler::getInstance();echo \$__tpl->compile('{$fileDir}','{$pathinfo['basename']}') ?>";
837
				// <!--%load_js_plugin-->
838
				case 'load_js_plugin':
839
					$plugin = $this->_replaceVar($m[5]);
840
					$s = "<!--#JSPLUGIN:{$plugin}-->";
841
					if(strpos($plugin, '$__Context') === false)
842
					{
843
						$plugin = "'{$plugin}'";
844
					}
845
846
					$s .= "<?php Context::loadJavascriptPlugin({$plugin}); ?>";
847
					return $s;
848
				// <load ...> or <unload ...> or <!--%import ...--> or <!--%unload ...-->
849
				case 'import':
850
				case 'load':
851
				case 'unload':
852
					$metafile = '';
853
					$pathinfo = pathinfo($attr['target']);
854
					$doUnload = ($m[3] === 'unload');
855
					$isRemote = !!preg_match('@^(https?:)?//@i', $attr['target']);
856
857
					if(!$isRemote)
858
					{
859
						if(!preg_match('@^\.?/@', $attr['target']))
860
						{
861
							$attr['target'] = './' . $attr['target'];
862
						}
863
						if(substr($attr['target'], -5) == '/lang')
864
						{
865
							$pathinfo['dirname'] .= '/lang';
866
							$pathinfo['basename'] = '';
867
							$pathinfo['extension'] = 'xml';
868
						}
869
870
						$relativeDir = $this->_getRelativeDir($pathinfo['dirname']);
871
872
						$attr['target'] = $relativeDir . '/' . $pathinfo['basename'];
873
					}
874
875
					switch($pathinfo['extension'])
876
					{
877
						case 'xml':
878
							if($isRemote || $doUnload)
879
							{
880
								return '';
881
							}
882
							// language file?
883
							if($pathinfo['basename'] == 'lang.xml' || substr($pathinfo['dirname'], -5) == '/lang')
884
							{
885
								$result = "Context::loadLang('{$relativeDir}');";
0 ignored issues
show
Bug introduced by
The variable $relativeDir does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
886
							}
887
							else
888
							{
889
								$result = "require_once('./classes/xml/XmlJsFilter.class.php');\$__xmlFilter=new XmlJsFilter('{$relativeDir}','{$pathinfo['basename']}');\$__xmlFilter->compile();";
890
							}
891
							break;
892 View Code Duplication
						case 'js':
893
							if($doUnload)
894
							{
895
								$result = "Context::unloadFile('{$attr['target']}','{$attr['targetie']}');";
896
							}
897
							else
898
							{
899
								$metafile = $attr['target'];
900
								$result = "\$__tmp=array('{$attr['target']}','{$attr['type']}','{$attr['targetie']}','{$attr['index']}');Context::loadFile(\$__tmp);unset(\$__tmp);";
901
							}
902
							break;
903 View Code Duplication
						case 'css':
904
							if($doUnload)
905
							{
906
								$result = "Context::unloadFile('{$attr['target']}','{$attr['targetie']}','{$attr['media']}');";
907
							}
908
							else
909
							{
910
								$metafile = $attr['target'];
911
								$result = "\$__tmp=array('{$attr['target']}','{$attr['media']}','{$attr['targetie']}','{$attr['index']}');Context::loadFile(\$__tmp);unset(\$__tmp);";
912
							}
913
							break;
914
					}
915
916
					$result = "<?php {$result} ?>";
0 ignored issues
show
Bug introduced by
The variable $result does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
917
					if($metafile)
918
					{
919
						$result = "<!--#Meta:{$metafile}-->" . $result;
920
					}
921
922
					return $result;
923
				// <config ...>
924
				case 'config':
925
					$result = '';
926
					if(preg_match_all('@ (\w+)="([^"]+)"@', $m[6], $config_matches, PREG_SET_ORDER))
927
					{
928
						foreach($config_matches as $config_match)
929
						{
930
							$result .= "\$this->config->{$config_match[1]} = '" . trim(strtolower($config_match[2])) . "';";
931
						}
932
					}
933
					return "<?php {$result} ?>";
934
			}
935
		}
936
937
		// <[email protected]> such as <!--@if($cond)-->, <!--@else-->, <!--@end-->
938
		if($m[7])
939
		{
940
			$m[7] = substr($m[7], 1);
941 View Code Duplication
			if(!$m[7])
942
			{
943
				return '<?php ' . $this->_replaceVar($m[8]) . '{ ?>' . $m[9];
944
			}
945
			if(!preg_match('/^(?:((?:end)?(?:if|switch|for(?:each)?|while)|end)|(else(?:if)?)|(break@)?(case|default)|(break))$/', $m[7], $mm))
946
			{
947
				return '';
948
			}
949
			if($mm[1])
950
			{
951
				if($mm[1]{0} == 'e')
952
				{
953
					return '<?php } ?>' . $m[9];
954
				}
955
956
				$precheck = '';
957
				if($mm[1] == 'switch')
958
				{
959
					$m[9] = '';
960
				}
961
				elseif($mm[1] == 'foreach')
962
				{
963
					$var = preg_replace('/^\s*\(\s*(.+?) .*$/', '$1', $m[8]);
964
					$precheck = "if({$var}&&count({$var}))";
965
				}
966
				return '<?php ' . $this->_replaceVar($precheck . $m[7] . $m[8]) . '{ ?>' . $m[9];
967
			}
968 View Code Duplication
			if($mm[2])
969
			{
970
				return "<?php }{$m[7]}" . $this->_replaceVar($m[8]) . "{ ?>" . $m[9];
971
			}
972
			if($mm[4])
973
			{
974
				return "<?php " . ($mm[3] ? 'break;' : '') . "{$m[7]} " . trim($m[8], '()') . ": ?>" . $m[9];
975
			}
976
			if($mm[5])
977
			{
978
				return "<?php break; ?>";
979
			}
980
			return '';
981
		}
982
		return $m[0];
983
	}
984
985
	/**
986
 	 * Apply escape option to an expression.
987
 	 */
988
 	private function _applyEscapeOption($str, $escape_option = 'noescape')
989
 	{
990
 		switch($escape_option)
991
 		{
992
 			case 'escape':
993
 				return "escape({$str}, true)";
994
 			case 'noescape':
995
 				return "{$str}";
996
 			case 'autoescape':
997
 				return "escape({$str}, false)";
998
 			case 'auto':
999
 			default:
1000
 				return "(\$this->config->autoescape === 'on' ? escape({$str}, false) : {$str})";
1001
 		}
1002
 	}
1003
1004
	/**
1005
	 * change relative path
1006
	 * @param string $path
1007
	 * @return string
1008
	 */
1009
	function _getRelativeDir($path)
1010
	{
1011
		$_path = $path;
1012
1013
		$fileDir = strtr(realpath($this->path), '\\', '/');
1014
		if($path{0} != '/')
1015
		{
1016
			$path = strtr(realpath($fileDir . '/' . $path), '\\', '/');
1017
		}
1018
1019
		// for backward compatibility
1020
		if(!$path)
1021
		{
1022
			$dirs = explode('/', $fileDir);
1023
			$paths = explode('/', $_path);
1024
			$idx = array_search($paths[0], $dirs);
1025
1026
			if($idx !== false)
1027
			{
1028
				while($dirs[$idx] && $dirs[$idx] === $paths[0])
1029
				{
1030
					array_splice($dirs, $idx, 1);
1031
					array_shift($paths);
1032
				}
1033
				$path = strtr(realpath($fileDir . '/' . implode('/', $paths)), '\\', '/');
1034
			}
1035
		}
1036
1037
		$path = preg_replace('/^' . preg_quote(_XE_PATH_, '/') . '/', '', $path);
1038
1039
		return $path;
1040
	}
1041
1042
	/**
1043
 	 * Check if a string seems to contain a variable.
1044
 	 * 
1045
 	 * @param string $str
1046
 	 * @return bool
1047
 	 */
1048
 	private static function _isVar($str)
1049
 	{
1050
 		return preg_match('@(?<!::|\\\\|(?<!eval\()\')\$([a-z_][a-z0-9_]*)@i', $str) ? true : false;
1051
 	}
1052
1053
	/**
1054
	 * Replace PHP variables of $ character
1055
	 * @param string $php
1056
	 * @return string $__Context->varname
1057
	 */
1058
	function _replaceVar($php)
1059
	{
1060
		if(!strlen($php))
1061
		{
1062
			return '';
1063
		}
1064
		return preg_replace('@(?<!::|\\\\|(?<!eval\()\')\$([a-z]|_[a-z0-9])@i', '\$__Context->$1', $php);
1065
	}
1066
1067
	function isAutoescape()
1068
	{
1069
		$absPath = str_replace(_XE_PATH_, '', $this->path);
1070
		$dirTpl = '(addon|admin|adminlogging|autoinstall|board|comment|communication|counter|document|editor|file|importer|install|integration_search|krzip|layout|member|menu|message|module|page|point|poll|rss|seo|session|spamfilter|syndication|tag|trash|widget)';
1071
		$dirSkins = '(layouts\/default|layouts\/user_layout|layouts\/xedition|layouts\/xedition\/demo|m\.layouts\/colorCode|m\.layouts\/default|m\.layouts\/simpleGray|modules\/board\/m\.skins\/default|modules\/board\/m\.skins\/simpleGray|modules\/board\/skins\/default|modules\/board\/skins\/xedition|modules\/communication\/m\.skins\/default|modules\/communication\/skins\/default|modules\/editor\/skins\/ckeditor|modules\/editor\/skins\/xpresseditor|modules\/integration_search\/skins\/default|modules\/layout\/faceoff|modules\/member\/m\.skins\/default|modules\/member\/skins\/default|modules\/message\/m\.skins\/default|modules\/message\/skins\/default|modules\/message\/skins\/xedition|modules\/page\/m\.skins\/default|modules\/page\/skins\/default|modules\/poll\/skins\/default|modules\/poll\/skins\/simple|widgets\/content\/skins\/default|widgets\/counter_status\/skins\/default|widgets\/language_select\/skins\/default|widgets\/login_info\/skins\/default|widgets\/mcontent\/skins\/default|widgetstyles\/simple)';
0 ignored issues
show
Unused Code introduced by
$dirSkins is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1072
1073
		// 'tpl'
1074
		if(preg_match('/^(\.\/)?(modules\/' . $dirTpl . '|common)\/tpl\//', $absPath))
1075
		{
1076
			return true;
1077
		}
1078
1079
		// skin, layout
1080
		if(preg_match('/^(\.\/)?(' . $dirSkin . '\//', $absPath))
0 ignored issues
show
Bug introduced by
The variable $dirSkin does not exist. Did you mean $dirSkins?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
1081
		{
1082
			return true;
1083
		}
1084
1085
		return false;
1086
	}
1087
1088
	public function setAutoescape($val = true)
1089
	{
1090
		$this->autoescape = $val;
1091
	}
1092
}
1093
/* End of File: TemplateHandler.class.php */
1094
/* Location: ./classes/template/TemplateHandler.class.php */
1095