Ejemplo n.º 1
0
/**
* Processes a raw template for conditionals, phrases etc into PHP code for eval()
*
* @param	string	Template
*
* @return	string
*/
function compile_template($template, &$errors = array())
{
	$orig_template = $template;


	$template = preg_replace('#[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]#', '', $template);
	$new_syntax = (strpos($template, '<vb:') !== false OR strpos($template, '{vb:') !== false);
	$old_syntax = (strpos($template, '<if') !== false OR strpos($template, '<phrase') !== false);
	$maybe_old_syntax = preg_match('/(^|[^{])\$[a-z0-9_]+\[?/si', $template);

	if (!$new_syntax AND ($old_syntax OR $maybe_old_syntax))
	{
		$template = addslashes($template);
		$template = process_template_conditionals($template);
		$template = process_template_phrases('phrase', $template, 'parse_phrase_tag');
		$template = process_seo_urls($template);

		if (!function_exists('replace_template_variables') OR !function_exists('validate_string_for_interpolation'))
		{
			require_once(DIR . '/includes/functions_misc.php');
		}

		//only check the old style syntax, the new style doesn't use string interpolation and isn't affected
		//by this exploit.  The new syntax doesn't 100% pass this check.
		if(!validate_string_for_interpolation($template))
		{
			global $vbphrase;
			echo "<p>&nbsp;</p><p>&nbsp;</p>";
			print_form_header('', '', 0, 1, '', '65%');
			print_table_header($vbphrase['vbulletin_message']);
			print_description_row($vbphrase['template_text_not_safe']);
			print_table_footer(2, construct_button_code($vbphrase['go_back'], 'javascript:history.back(1)'));
			print_cp_footer();
			exit;
		}


		$template = replace_template_variables($template, false);

		$template = str_replace('\\\\$', '\\$', $template);

		if (function_exists('token_get_all'))
		{
			$tokens = @token_get_all('<?php $var = "' . $template . '"; ?>');

			foreach ($tokens AS $token)
			{
				if (is_array($token))
				{
					switch ($token[0])
					{
						case T_INCLUDE:
						case T_INCLUDE_ONCE:
						case T_REQUIRE:
						case T_REQUIRE_ONCE:
						{
							global $vbphrase;
							echo "<p>&nbsp;</p><p>&nbsp;</p>";
							print_form_header('', '', 0, 1, '', '65%');
							print_table_header($vbphrase['vbulletin_message']);
							print_description_row($vbphrase['file_inclusion_not_permitted']);
							print_table_footer(2, construct_button_code($vbphrase['go_back'], 'javascript:history.back(1)'));
							print_cp_footer();
							exit;
						}
					}
				}
			}
		}
	}
	else
	{
		require_once(DIR . '/includes/class_template_parser.php');
		$parser = new vB_TemplateParser($orig_template);

		try
		{
			$parser->validate($errors);
		}
		catch (vB_Exception_TemplateFatalError $e)
		{
			global $vbphrase;
			echo "<p>&nbsp;</p><p>&nbsp;</p>";
			print_form_header('', '', 0, 1, '', '65%');
			print_table_header($vbphrase['vbulletin_message']);
			print_description_row($vbphrase[$e->getMessage()]);
			print_table_footer(2, construct_button_code($vbphrase['go_back'], 'javascript:history.back(1)'));
			print_cp_footer();
			exit;
		}

		$template = $parser->compile();

		// TODO: Reimplement these - if done, $session[], $bbuserinfo[], $vboptions will parse in the template without using {vb:raw, which isn't what we
		// necessarily want to happen
		/*
		if (!function_exists('replace_template_variables'))
		{
			require_once(DIR . '/includes/functions_misc.php');
		}
		$template = replace_template_variables($template, false);
		*/
	}

	if (function_exists('verify_demo_template'))
	{
		verify_demo_template($template);
	}

	($hook = vBulletinHook::fetch_hook('template_compile')) ? eval($hook) : false;

	return $template;
}
Ejemplo n.º 2
0
 /**
  * Compile a template.
  *
  * @param string $template_un The uncompiled content of a template.
  */
 public function compile($template, $forcesaveonerror)
 {
     // @todo
     // Incorrect hack warning!!!
     // The legacy code in class_template_parser.php needs this to be set
     // but it apparrently does not actually need to be an instance of the
     // legacy db class for purposes of compiling a template.
     if (empty($GLOBALS['vbulletin']->db)) {
         $GLOBALS['vbulletin']->db = false;
     }
     require_once DIR . '/includes/class_template_parser.php';
     require_once DIR . '/includes/adminfunctions_template.php';
     // Required for check_template_errors()
     $parser = new vB_TemplateParser($template);
     try {
         $parser->validate($errors);
     } catch (vB_Exception_TemplateFatalError $e) {
         throw new vB_Exception_Api($e->getMessage());
     }
     $template = $parser->compile();
     // This is a comment from vB4 moved here.  Need to figure out what replace_template_variables
     // is supposed to do.
     // TODO: Reimplement these - if done, $session[], $bbuserinfo[], $vboptions
     // will parse in the template without using {vb:raw, which isn't what we
     // necessarily want to happen
     /*
     if (!function_exists('replace_template_variables'))
     {
     	require_once(DIR . '/includes/functions_misc.php');
     }
     $template = replace_template_variables($template, false);
     */
     if (function_exists('verify_demo_template')) {
         verify_demo_template($template);
     }
     // Legacy Hook 'template_compile' Removed //
     if (!$forcesaveonerror and !empty($errors)) {
         throw new vB_Exception_Api('template_compile_error', array($errors));
     }
     //extra set of error checking.  This can be skipped in many situations.
     if (!$forcesaveonerror) {
         $errors = check_template_errors($template);
         if (!empty($errors)) {
             $vb5_config =& vB::getConfig();
             if (!is_array($errors) and $vb5_config['Misc']['debug']) {
                 // show compiled template code with line numbers to debug the problem
                 $errors .= '<h4>Compiled Template Code:</h4><div style="height:200px; overflow:auto; border:1px solid silver; font-style:normal; font-family:Courier New;"><ol><li>' . implode('</li><li>', explode("\n", htmlspecialchars($template))) . '</li></ol></div>';
             }
             throw new vB_Exception_Api('template_eval_error', array($errors));
         }
     }
     return $template;
 }