示例#1
0
/**
* Processes a raw template for conditionals, phrases etc into PHP code for eval()
*
* @param	string	Template
*
* @return	string
*/
function compile_template($template)
{
    $orig_template = $template;
    $template = addslashes($template);
    $template = process_template_conditionals($template);
    $template = process_template_phrases('phrase', $template, 'parse_phrase_tag');
    if (!function_exists('replace_template_variables')) {
        require_once DIR . '/includes/functions_misc.php';
    }
    $template = replace_template_variables($template, false);
    ($hook = vBulletinHook::fetch_hook('template_compile')) ? eval($hook) : 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;
                }
            }
        }
    }
    if (function_exists('verify_demo_template')) {
        verify_demo_template($template);
    }
    return $template;
}
/**
* 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;
}