From 5c8843704c2b953d5fb790ca084c700ea685d252 Mon Sep 17 00:00:00 2001 From: Dries Buytaert Date: Wed, 22 Jun 2005 20:19:58 +0000 Subject: - Patch #18213 by chx: boostrap system. Modified to work with HEAD, tidied up the documentation a little. chx: can you double-check whether the global $conf variable is secure? (That is, make sure it can't be send using the URL or something.) --- cron.php | 2 +- includes/bootstrap.inc | 80 +++++++++++++++++++++++++++++++---------- includes/common.inc | 88 ++++++++++++++++++++++----------------------- includes/database.inc | 3 -- includes/database.mysql.inc | 9 +++-- includes/database.pgsql.inc | 9 +++-- includes/menu.inc | 2 +- includes/session.inc | 3 -- includes/theme.inc | 1 + index.php | 8 ++--- modules/node.module | 2 +- modules/node/node.module | 2 +- xmlrpc.php | 3 +- 13 files changed, 128 insertions(+), 84 deletions(-) diff --git a/cron.php b/cron.php index 98026de15..51afe406b 100644 --- a/cron.php +++ b/cron.php @@ -7,7 +7,7 @@ */ include_once 'includes/bootstrap.inc'; -include_once 'includes/common.inc' ; +drupal_bootstrap('full'); // If not in 'safe mode', increase the maximum execution time: if (!ini_get('safe_mode')) { diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index 0fde1d259..0e8df86e4 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -789,27 +789,71 @@ function drupal_is_denied($type, $mask) { return $deny && !$allow; } +/** + * A string describing a phase of Drupal to load. Each phase adds to the + * previous one, so invoking a later phase automatically runs the earlier + * phases too. The most important usage is that if you want to access + * Drupal database from a script without loading anything else, you can + * include bootstrap.inc, and call drupal_bootstrap('database'). + * + * @param $phase + * A string. Allowed values are: + * 'database': initialize database layer. + * 'session': initialize session handling. + * 'page cache': load bootstrap.inc and module.inc, start the variable + * system and try to serve a page from the cache. + * 'full': Drupal is fully loaded, validate and fix input data. + */ +function drupal_bootstrap($phase) { + static $phases = array('database', 'session', 'page cache', 'full'); + + while ($current_phase = array_shift($phases)) { + _drupal_bootstrap($current_phase); + if ($phase == $current_phase) { + return; + } + } +} -// Start a page timer: -timer_start('page'); - -unset($conf); -$config = conf_init(); +function _drupal_bootstrap($phase) { + global $conf; -include_once "$config/settings.php"; -include_once 'includes/database.inc'; + switch ($phase) { + case 'database': + global $db_url, $base_url; + unset($conf); + require_once conf_init() .'/settings.php'; + require_once './includes/database.inc'; + // Initialize the default database. + db_set_active(); + break; + case 'session': + require_once './includes/session.inc'; + session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc"); + session_start(); + break; + case 'page cache': + require_once './includes/bootstrap.inc'; + require_once './includes/module.inc'; + // Start a page timer: + timer_start('page'); + + // deny access to hosts which were banned. t() is not yet available. + if (drupal_is_denied('host', $_SERVER['REMOTE_ADDR'])) { + header('HTTP/1.0 403 Forbidden'); + print "Sorry, ". $_SERVER['REMOTE_ADDR']. " has been banned."; + exit(); + } -// deny access to hosts which were banned. t() is not yet available. -if (drupal_is_denied('host', $_SERVER['REMOTE_ADDR'])) { - header('HTTP/1.0 403 Forbidden'); - print "Sorry, ". $_SERVER['REMOTE_ADDR']. " has been banned."; - exit(); + // Initialize configuration variables, using values from conf.php if available. + $conf = variable_init(isset($conf) ? $conf : array()); + drupal_page_header(); + break; + case 'full': + require_once './includes/common.inc'; + _drupal_bootstrap_full(); + break; + } } -include_once 'includes/session.inc'; -include_once 'includes/module.inc'; - -// Initialize configuration variables, using values from conf.php if available. -$conf = variable_init(isset($conf) ? $conf : array()); - ?> diff --git a/includes/common.inc b/includes/common.inc index 0cd68bb4a..020d0c5d8 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -812,7 +812,7 @@ function format_plural($count, $singular, $plural) { if ($count == 1) return t($singular, array("%count" => $count)); // get the plural index through the gettext formula - $index = (function_exists('locale')) ? locale_get_plural($count) : -1; + $index = (function_exists('locale_get_plural')) ? locale_get_plural($count) : -1; if ($index < 0) { // backward compatibility return t($plural, array("%count" => $count)); } @@ -2001,12 +2001,8 @@ function drupal_get_path($type, $name) { /** * Provide a substitute clone() function for PHP4. */ -if (version_compare(phpversion(), '5.0') < 0) { - eval(' - function clone($object) { - return $object; - } - '); +function drupal_clone($object) { + return version_compare(phpversion(), '5.0') < 0 ? $object : clone($object); } /** @@ -2054,44 +2050,48 @@ function drupal_implode_autocomplete($array) { return implode('||', $output); } -// Set the Drupal custom error handler. -set_error_handler('error_handler'); - -include_once 'includes/theme.inc'; -include_once 'includes/pager.inc'; -include_once 'includes/menu.inc'; -include_once 'includes/tablesort.inc'; -include_once 'includes/file.inc'; -include_once 'includes/xmlrpc.inc'; -include_once 'includes/image.inc'; - -// Emit the correct charset HTTP header. -drupal_set_header('Content-Type: text/html; charset=utf-8'); - -// Initialize $_GET['q'] prior to loading modules and invoking hook_init(). -if (!empty($_GET['q'])) { - $_GET['q'] = drupal_get_normal_path(trim($_GET['q'], '/')); -} -else { - $_GET['q'] = drupal_get_normal_path(variable_get('site_frontpage', 'node')); -} - -// Initialize all enabled modules. -module_init(); +function _drupal_bootstrap_full() { + static $called; + global $locale; -if (!user_access('bypass input data check')) { - // We can't use $_REQUEST because it consists of the contents of $_POST, - // $_GET and $_COOKIE: if any of the input arrays share a key, only one - // value will be verified. - if (!valid_input_data($_GET) - || !valid_input_data($_POST) - || !valid_input_data($_COOKIE) - || !valid_input_data($_FILES)) { - die('Terminated request because of suspicious input data.'); + if ($called) { + return; + } + $called = 1; + require_once './includes/theme.inc'; + require_once './includes/pager.inc'; + require_once './includes/menu.inc'; + require_once './includes/tablesort.inc'; + require_once './includes/file.inc'; + require_once './includes/xmlrpc.inc'; + require_once './includes/image.inc'; + // Set the Drupal custom error handler. + set_error_handler('error_handler'); + // Emit the correct charset HTTP header. + drupal_set_header('Content-Type: text/html; charset=utf-8'); + // Initialize $_GET['q'] prior to loading modules and invoking hook_init(). + if (!empty($_GET['q'])) { + $_GET['q'] = drupal_get_normal_path(trim($_GET['q'], '/')); + } + else { + $_GET['q'] = drupal_get_normal_path(variable_get('site_frontpage', 'node')); + } + // Initialize all enabled modules. + module_init(); + if (!user_access('bypass input data check')) { + // We can't use $_REQUEST because it consists of the contents of $_POST, + // $_GET and $_COOKIE: if any of the input arrays share a key, only one + // value will be verified. + if (!valid_input_data($_GET) + || !valid_input_data($_POST) + || !valid_input_data($_COOKIE) + || !valid_input_data($_FILES)) { + die('Terminated request because of suspicious input data.'); + } } + fix_gpc_magic(); + fix_checkboxes(); + // Initialize the localization system. + $locale = locale_initialize(); } - -// Initialize the localization system. -$locale = locale_initialize(); - ?> diff --git a/includes/database.inc b/includes/database.inc index 06d150d30..c76b0083d 100644 --- a/includes/database.inc +++ b/includes/database.inc @@ -279,7 +279,4 @@ function db_rewrite_sql($query, $primary_table = 'n', $primary_field = 'nid', $ * @} End of "defgroup database". */ -// Initialize the default database. -db_set_active(); - ?> diff --git a/includes/database.mysql.inc b/includes/database.mysql.inc index 786a1dfd8..78bd24656 100644 --- a/includes/database.mysql.inc +++ b/includes/database.mysql.inc @@ -47,15 +47,20 @@ function db_connect($url) { function _db_query($query, $debug = 0) { global $active_db; global $queries; + static $dev_query; - if (variable_get('dev_query', 0)) { + if (!isset($dev_query)) { + $dev_query = function_exists('dev_query') ? variable_get('dev_query', 0) : $GLOBALS['conf']['dev_query']; + } + + if ($dev_query) { list($usec, $sec) = explode(' ', microtime()); $timer = (float)$usec + (float)$sec; } $result = mysql_query($query, $active_db); - if (variable_get('dev_query', 0)) { + if ($dev_query) { list($usec, $sec) = explode(' ', microtime()); $stop = (float)$usec + (float)$sec; $diff = $stop - $timer; diff --git a/includes/database.pgsql.inc b/includes/database.pgsql.inc index 15eda4d83..9e4ecf21b 100644 --- a/includes/database.pgsql.inc +++ b/includes/database.pgsql.inc @@ -36,15 +36,20 @@ function db_connect($url) { function _db_query($query, $debug = 0) { global $active_db, $last_result; global $queries; + static $dev_query; - if (variable_get('dev_query', 0)) { + if (!isset($dev_query)) { + $dev_query = function_exists('dev_query') ? variable_get('dev_query', 0) : $GLOBALS['conf']['dev_query']; + } + + if ($dev_query) { list($usec, $sec) = explode(' ', microtime()); $timer = (float)$usec + (float)$sec; } $last_result = pg_query($active_db, $query); - if (variable_get('dev_query', 0)) { + if ($dev_query) { list($usec, $sec) = explode(' ', microtime()); $stop = (float)$usec + (float)$sec; $diff = $stop - $timer; diff --git a/includes/menu.inc b/includes/menu.inc index cf8a7c007..67b474b3a 100644 --- a/includes/menu.inc +++ b/includes/menu.inc @@ -351,7 +351,7 @@ function menu_execute_active_handler() { $arguments = array_merge($arguments, explode('/', $arg)); } - return call_user_func_array($menu['items'][$mid]['callback'], $arguments); + return function_exists($menu['items'][$mid]['callback']) ? call_user_func_array($menu['items'][$mid]['callback'], $arguments) : ''; } /** diff --git a/includes/session.inc b/includes/session.inc index 126c56f02..d1dde2f2a 100644 --- a/includes/session.inc +++ b/includes/session.inc @@ -6,9 +6,6 @@ * User session handling functions. */ -session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc"); -session_start(); - /*** Session functions *****************************************************/ function sess_open($save_path, $session_name) { diff --git a/includes/theme.inc b/includes/theme.inc index d35e83fea..7d3cd8cbd 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -34,6 +34,7 @@ define('MARK_UPDATED', 2); function init_theme() { global $user, $custom_theme, $theme_engine, $theme_key; + drupal_bootstrap('database'); $themes = list_themes(); // Only select the user selected theme if it is available in the diff --git a/index.php b/index.php index c2e7647fc..6816599b8 100644 --- a/index.php +++ b/index.php @@ -9,12 +9,8 @@ * prints the appropriate page. */ -include_once 'includes/bootstrap.inc'; -drupal_page_header(); -include_once 'includes/common.inc'; - -fix_gpc_magic(); -fix_checkboxes(); +require_once './includes/bootstrap.inc'; +drupal_bootstrap('full'); $return = menu_execute_active_handler(); switch ($return) { diff --git a/modules/node.module b/modules/node.module index 5f22252d6..54a6285e7 100644 --- a/modules/node.module +++ b/modules/node.module @@ -1470,7 +1470,7 @@ function node_preview($node) { // Display a preview of the node: // Previewing alters $node so it needs to be cloned. - $output = theme('node_preview', clone($node)); + $output = theme('node_preview', drupal_clone($node)); $output .= node_form($node); diff --git a/modules/node/node.module b/modules/node/node.module index 5f22252d6..54a6285e7 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -1470,7 +1470,7 @@ function node_preview($node) { // Display a preview of the node: // Previewing alters $node so it needs to be cloned. - $output = theme('node_preview', clone($node)); + $output = theme('node_preview', drupal_clone($node)); $output .= node_form($node); diff --git a/xmlrpc.php b/xmlrpc.php index 11f6ab74f..d93055075 100644 --- a/xmlrpc.php +++ b/xmlrpc.php @@ -7,8 +7,7 @@ */ include_once 'includes/bootstrap.inc'; -include_once 'includes/common.inc'; -include_once 'includes/xmlrpc.inc'; +drupal_bootstrap('full'); include_once 'includes/xmlrpcs.inc'; $functions = module_invoke_all('xmlrpc'); -- cgit v1.2.3