add better checks for correctly nested tags when compiling

This commit is contained in:
messju
2003-12-08 10:44:21 +00:00
parent 74d69ccbc2
commit 1dd2246d8a
2 changed files with 76 additions and 9 deletions

1
NEWS
View File

@@ -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)

View File

@@ -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__);
}
} }
/** /**