mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-05 02:44:27 +02:00
add better checks for correctly nested tags when compiling
This commit is contained in:
1
NEWS
1
NEWS
@@ -1,3 +1,4 @@
|
|||||||
|
- add better checks for correctly nested tags when compiling (messju)
|
||||||
- remove {$SCRIPT_NAME}. use {$smarty.server.SCRIPT_NAME} instead (messju)
|
- remove {$SCRIPT_NAME}. use {$smarty.server.SCRIPT_NAME} instead (messju)
|
||||||
- remove $global_assign. assign global variables explicitly instead (messju)
|
- remove $global_assign. assign global variables explicitly instead (messju)
|
||||||
- remove warning in debug_print_var on php-resources (messju)
|
- remove warning in debug_print_var on php-resources (messju)
|
||||||
|
@@ -51,8 +51,6 @@ class Smarty_Compiler extends Smarty {
|
|||||||
/**#@+
|
/**#@+
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part
|
|
||||||
var $_foreachelse_stack = array(); // keeps track of whether foreach had 'else' part
|
|
||||||
var $_literal_blocks = array(); // keeps literal template blocks
|
var $_literal_blocks = array(); // keeps literal template blocks
|
||||||
var $_php_blocks = array(); // keeps php code blocks
|
var $_php_blocks = array(); // keeps php code blocks
|
||||||
var $_current_file = null; // the current template being compiled
|
var $_current_file = null; // the current template being compiled
|
||||||
@@ -316,6 +314,11 @@ class Smarty_Compiler extends Smarty {
|
|||||||
$compiled_tags[] = $this->_compile_tag($template_tags[$i]);
|
$compiled_tags[] = $this->_compile_tag($template_tags[$i]);
|
||||||
$this->_current_line_no += substr_count($template_tags[$i], "\n");
|
$this->_current_line_no += substr_count($template_tags[$i], "\n");
|
||||||
}
|
}
|
||||||
|
if (count($this->_tag_stack)>0) {
|
||||||
|
list($_open_tag, $_line_no) = end($this->_tag_stack);
|
||||||
|
$this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$compiled_content = '';
|
$compiled_content = '';
|
||||||
|
|
||||||
@@ -393,7 +396,6 @@ class Smarty_Compiler extends Smarty {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$compiled_content = $template_header . $compiled_content;
|
$compiled_content = $template_header . $compiled_content;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,15 +446,27 @@ class Smarty_Compiler extends Smarty {
|
|||||||
return $this->_compile_include_php_tag($tag_args);
|
return $this->_compile_include_php_tag($tag_args);
|
||||||
|
|
||||||
case 'if':
|
case 'if':
|
||||||
|
$this->_push_tag('if');
|
||||||
return $this->_compile_if_tag($tag_args);
|
return $this->_compile_if_tag($tag_args);
|
||||||
|
|
||||||
case 'else':
|
case 'else':
|
||||||
|
list($_open_tag) = end($this->_tag_stack);
|
||||||
|
if ($_open_tag != 'if' && $_open_tag != 'elseif')
|
||||||
|
$this->_syntax_error('unxepected {else}', E_USER_ERROR, __FILE__, __LINE__);
|
||||||
|
else
|
||||||
|
$this->_push_tag('else');
|
||||||
return '<?php else: ?>';
|
return '<?php else: ?>';
|
||||||
|
|
||||||
case 'elseif':
|
case 'elseif':
|
||||||
|
list($_open_tag) = end($this->_tag_stack);
|
||||||
|
if ($_open_tag != 'if' && $_open_tag != 'elseif')
|
||||||
|
$this->_syntax_error('unxepected {elseif}', E_USER_ERROR, __FILE__, __LINE__);
|
||||||
|
if ($_open_tag == 'if')
|
||||||
|
$this->_push_tag('elseif');
|
||||||
return $this->_compile_if_tag($tag_args, true);
|
return $this->_compile_if_tag($tag_args, true);
|
||||||
|
|
||||||
case '/if':
|
case '/if':
|
||||||
|
$this->_pop_tag('if');
|
||||||
return '<?php endif; ?>';
|
return '<?php endif; ?>';
|
||||||
|
|
||||||
case 'capture':
|
case 'capture':
|
||||||
@@ -468,42 +482,48 @@ class Smarty_Compiler extends Smarty {
|
|||||||
return $this->right_delimiter;
|
return $this->right_delimiter;
|
||||||
|
|
||||||
case 'section':
|
case 'section':
|
||||||
array_push($this->_sectionelse_stack, false);
|
$this->_push_tag('section');
|
||||||
return $this->_compile_section_start($tag_args);
|
return $this->_compile_section_start($tag_args);
|
||||||
|
|
||||||
case 'sectionelse':
|
case 'sectionelse':
|
||||||
$this->_sectionelse_stack[count($this->_sectionelse_stack)-1] = true;
|
$this->_push_tag('sectionelse');
|
||||||
return "<?php endfor; else: ?>";
|
return "<?php endfor; else: ?>";
|
||||||
|
break;
|
||||||
|
|
||||||
case '/section':
|
case '/section':
|
||||||
if (array_pop($this->_sectionelse_stack))
|
$_open_tag = $this->_pop_tag('section');
|
||||||
|
if ($_open_tag == 'sectionelse')
|
||||||
return "<?php endif; ?>";
|
return "<?php endif; ?>";
|
||||||
else
|
else
|
||||||
return "<?php endfor; endif; ?>";
|
return "<?php endfor; endif; ?>";
|
||||||
|
|
||||||
case 'foreach':
|
case 'foreach':
|
||||||
array_push($this->_foreachelse_stack, false);
|
$this->_push_tag('foreach');
|
||||||
return $this->_compile_foreach_start($tag_args);
|
return $this->_compile_foreach_start($tag_args);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'foreachelse':
|
case 'foreachelse':
|
||||||
$this->_foreachelse_stack[count($this->_foreachelse_stack)-1] = true;
|
$this->_push_tag('foreachelse');
|
||||||
return "<?php endforeach; unset(\$_from); else: ?>";
|
return "<?php endforeach; unset(\$_from); else: ?>";
|
||||||
|
|
||||||
case '/foreach':
|
case '/foreach':
|
||||||
if (array_pop($this->_foreachelse_stack))
|
$_open_tag = $this->_pop_tag('foreach');
|
||||||
|
if ($_open_tag == 'foreachelse')
|
||||||
return "<?php endif; ?>";
|
return "<?php endif; ?>";
|
||||||
else
|
else
|
||||||
return "<?php endforeach; unset(\$_from); endif; ?>";
|
return "<?php endforeach; unset(\$_from); endif; ?>";
|
||||||
|
break;
|
||||||
|
|
||||||
case 'strip':
|
case 'strip':
|
||||||
case '/strip':
|
case '/strip':
|
||||||
if ($tag_command{0}=='/') {
|
if ($tag_command{0}=='/') {
|
||||||
|
$this->_pop_tag('strip');
|
||||||
if (--$this->_strip_depth==0) { /* outermost closing {/strip} */
|
if (--$this->_strip_depth==0) { /* outermost closing {/strip} */
|
||||||
$this->_additional_newline = "\n";
|
$this->_additional_newline = "\n";
|
||||||
return $this->left_delimiter.$tag_command.$this->right_delimiter;
|
return $this->left_delimiter.$tag_command.$this->right_delimiter;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
$this->_push_tag('strip');
|
||||||
if ($this->_strip_depth++==0) { /* outermost opening {strip} */
|
if ($this->_strip_depth++==0) { /* outermost opening {strip} */
|
||||||
$this->_additional_newline = "";
|
$this->_additional_newline = "";
|
||||||
return $this->left_delimiter.$tag_command.$this->right_delimiter;
|
return $this->left_delimiter.$tag_command.$this->right_delimiter;
|
||||||
@@ -674,6 +694,11 @@ class Smarty_Compiler extends Smarty {
|
|||||||
*/
|
*/
|
||||||
$this->_add_plugin('block', $tag_command);
|
$this->_add_plugin('block', $tag_command);
|
||||||
|
|
||||||
|
if ($start_tag)
|
||||||
|
$this->_push_tag($tag_command);
|
||||||
|
else
|
||||||
|
$this->_pop_tag($tag_command);
|
||||||
|
|
||||||
if ($start_tag) {
|
if ($start_tag) {
|
||||||
$output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
|
$output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
|
||||||
$attrs = $this->_parse_attrs($tag_args);
|
$attrs = $this->_parse_attrs($tag_args);
|
||||||
@@ -2098,6 +2123,47 @@ class Smarty_Compiler extends Smarty {
|
|||||||
. '}\';}';
|
. '}\';}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* push opening tag-name, file-name and line-number on the tag-stack
|
||||||
|
* @param: string the opening tag's name
|
||||||
|
*/
|
||||||
|
function _push_tag($open_tag)
|
||||||
|
{
|
||||||
|
array_push($this->_tag_stack, array($open_tag, $this->_current_line_no));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pop closing tag-name
|
||||||
|
* raise an error if this stack-top doesn't match with the closing tag
|
||||||
|
* @param: string the closing tag's name
|
||||||
|
* @return: string the opening tag's name
|
||||||
|
*/
|
||||||
|
function _pop_tag($close_tag)
|
||||||
|
{
|
||||||
|
$message = '';
|
||||||
|
if (count($this->_tag_stack)>0) {
|
||||||
|
list($_open_tag, $_line_no) = array_pop($this->_tag_stack);
|
||||||
|
if ($close_tag == $_open_tag) {
|
||||||
|
return $_open_tag;
|
||||||
|
}
|
||||||
|
if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) {
|
||||||
|
return $this->_pop_tag($close_tag);
|
||||||
|
}
|
||||||
|
if ($close_tag == 'section' && $_open_tag == 'sectionelse') {
|
||||||
|
$this->_pop_tag($close_tag);
|
||||||
|
return $_open_tag;
|
||||||
|
}
|
||||||
|
if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') {
|
||||||
|
$this->_pop_tag($close_tag);
|
||||||
|
return $_open_tag;
|
||||||
|
}
|
||||||
|
$message = " expected {/$_open_tag} (opened line $_line_no).";
|
||||||
|
}
|
||||||
|
$this->_syntax_error("mismatched tag {/$close_tag}.$message",
|
||||||
|
E_USER_ERROR, __FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user