Skip to content

Commit

Permalink
Before this commit, we were loading language files at compile time, w…
Browse files Browse the repository at this point in the history
…hich means we had to choose between pretty error messages when the database connect failed and obeying the user's preferred language.

With the help of Julian (nice suggestion, that get_defined_vars()), I've modified lang_api to load language files at compile time and made some other modifications to ensure that a failed database connect prints a nice message again.

M core.php
- Reordered the includes again

M core/authentication_api.php
- (auth_user_is_authenticated) Every function that was going to access the database first checked this function, so I've defined the lack of database connection as not authenticated

M core/database_api.php
- Now remembers whether a db_connect or db_pconnect succesfully terminated
- Added db_is_connected(), which returns this remembered state

M core/lang_api.php
- Now loads the language into $g_lang_strings (as opposed to defining every language variable as global, because you were including a file in a function). This has the added benefit that language variables can only be defined in strings_<lang>.txt and custom_strings_inc.php, hopefully preventing all string-spoofing-vulnerabilities)
- Remembers which language is loaded. I only need to know whether a language was loaded, but this has the added benefit of possibly preventing a language from loaded twice
- Added lang_load(lang), which loads a language, and lang_load_default(), which loads the user's language (or default_language). lang_load_default might be wrongly named? Opinions?
- Added lang_ensure_loaded, which calls lang_load_default if no language has previously been loaded
- Modified lang_get and lang_exists to use $g_lang_strings, and call lang_ensure_loaded
- Removed the 'main code', which was loading languages at compile time.


git-svn-id: http://mantisbt.svn.sourceforge.net/svnroot/mantisbt/trunk@1906 f5dc347c-c33d-0410-90a0-b07cc1902cb9
  • Loading branch information
Jeroen Latour committed Feb 17, 2003
1 parent de1bec6 commit 36f1cfc
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 46 deletions.
6 changes: 3 additions & 3 deletions core.php
Expand Up @@ -6,7 +6,7 @@
# See the README and LICENSE files for details

# --------------------------------------------------------
# $Id: core.php,v 1.23 2003-02-17 03:35:26 jfitzell Exp $
# $Id: core.php,v 1.24 2003-02-17 13:16:28 jlatour Exp $
# --------------------------------------------------------

###########################################################################
Expand Down Expand Up @@ -55,8 +55,10 @@
require_once( $t_core_path.'lang_api.php' );

# error functions should be loaded to allow database to print errors
require_once( $t_core_path.'authentication_api.php' );
require_once( $t_core_path.'html_api.php' );
require_once( $t_core_path.'error_api.php' );
require_once( $t_core_path.'gpc_api.php' );

# initialize our timer
$g_timer = new BC_Timer;
Expand All @@ -75,8 +77,6 @@
}

require_once( $t_core_path.'project_api.php' );
require_once( $t_core_path.'gpc_api.php' );
require_once( $t_core_path.'authentication_api.php' );
require_once( $t_core_path.'access_api.php' );
require_once( $t_core_path.'print_api.php' );
require_once( $t_core_path.'helper_api.php' );
Expand Down
4 changes: 2 additions & 2 deletions core/authentication_api.php
Expand Up @@ -6,7 +6,7 @@
# See the README and LICENSE files for details

# --------------------------------------------------------
# $Id: authentication_api.php,v 1.23 2003-02-16 10:52:17 jfitzell Exp $
# $Id: authentication_api.php,v 1.24 2003-02-17 13:16:28 jlatour Exp $
# --------------------------------------------------------

###########################################################################
Expand Down Expand Up @@ -48,7 +48,7 @@ function auth_ensure_user_authenticated( $p_return_page='' ) {
# Return true if there is a currently logged in and authenticated user,
# false otherwise
function auth_is_user_authenticated() {
if ( '' == auth_get_current_user_cookie() ) {
if ( !db_is_connected() || '' == auth_get_current_user_cookie() ) {
return false;
} else {
return true;
Expand Down
22 changes: 21 additions & 1 deletion core/database_api.php
Expand Up @@ -6,7 +6,7 @@
# See the README and LICENSE files for details

# --------------------------------------------------------
# $Id: database_api.php,v 1.14 2003-02-17 03:42:16 jfitzell Exp $
# $Id: database_api.php,v 1.15 2003-02-17 13:16:28 jlatour Exp $
# --------------------------------------------------------

###########################################################################
Expand All @@ -18,34 +18,53 @@

# An array in which all executed queries are stored. This is used for profiling
$g_queries_array = array();

# Stores whether a database connection was succesfully opened.
$g_db_connected = false;

# --------------------
# Make a connection to the database
function db_connect( $p_hostname, $p_username, $p_password, $p_port ) {
global $g_db_connected;

$t_result = @mysql_connect( "$p_hostname:$p_port", $p_username, $p_password );

if ( !$t_result ) {
db_error();
trigger_error( ERROR_DB_CONNECT_FAILED, ERROR );
return false;
}

$g_db_connected = true;

return true;
}

# --------------------
# Make a persistent connection to the database
function db_pconnect( $p_hostname, $p_username, $p_password, $p_port ) {
global $g_db_connected;

$t_result = @mysql_pconnect( "$p_hostname:$p_port", $p_username, $p_password );

if ( !$t_result ) {
db_error();
trigger_error( ERROR_DB_CONNECT_FAILED, ERROR );
return false;
}

$g_db_connected = true;

return true;
}

# --------------------
# Returns whether a connection to the database exists
function db_is_connected() {
global $g_db_connected;

return $g_db_connected;
}

# --------------------
# execute query, requires connection to be opened
Expand All @@ -64,6 +83,7 @@ function db_query( $p_query, $p_error_on_failure=true ) {
# @@@ remove p_error_on_failure and use @ in every caller that used to use it
if ( !$t_result && $p_error_on_failure ) {
db_error($p_query);
var_dump($p_query);
trigger_error( ERROR_DB_QUERY_FAILED, ERROR );
return false;
} else {
Expand Down
130 changes: 90 additions & 40 deletions core/lang_api.php
Expand Up @@ -6,27 +6,110 @@
# See the README and LICENSE files for details

# --------------------------------------------------------
# $Id: lang_api.php,v 1.9 2003-01-23 21:44:44 jlatour Exp $
# $Id: lang_api.php,v 1.10 2003-02-17 13:16:28 jlatour Exp $
# --------------------------------------------------------

###########################################################################
# Language (Internationalization) API
###########################################################################

# Cache of localization strings in the language specified by the last
# lang_load call
$g_lang_strings = array();

# Currently loaded language
$g_lang_current = '';

# ------------------
# Loads the specified language and stores it in $g_lang_strings,
# to be used by lang_get
function lang_load( $p_lang ) {
global $g_lang_strings, $g_lang_current;

if ($g_lang_current == $p_lang) {
return;
}

$t_lang_dir = dirname ( dirname ( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR;
require_once( $t_lang_dir . 'strings_'.$p_lang.'.txt' );

# Allow overriding strings declared in the language file.
# custom_strings_inc.php can use $g_active_language
$t_custom_strings = dirname ( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'custom_strings_inc.php';
if ( file_exists( $t_custom_strings ) ) {
require_once( $t_custom_strings );
}

$t_vars = get_defined_vars();

foreach ( array_keys( $t_vars ) as $t_var ) {
$t_lang_var = ereg_replace( '^s_', '', $t_var );
if ( $t_lang_var != $t_var ) {
$g_lang_strings[$t_lang_var] = $$t_var;
}
}

$g_lang_current = $p_lang;
}

# ------------------
# Loads the user's language or, if the database is unavailable, the default language
function lang_load_default() {
global $g_string_cookie_val;

# Confirm that the user's language can be determined
if ( db_is_connected() && !is_blank( $g_string_cookie_val ) ) {

$t_mantis_user_pref_table = config_get( 'mantis_user_pref_table' );
$t_mantis_user_table = config_get( 'mantis_user_table' );

$query = "SELECT DISTINCT language
FROM $t_mantis_user_pref_table p, $t_mantis_user_table u
WHERE u.cookie_string='$g_string_cookie_val' AND
u.id=p.user_id";

$result = db_query( $query );
$t_active_language = db_result( $result, 0 , 0 );

if ( false == $t_active_language ) {
$t_active_language = config_get( 'default_language' );
}

} else {
$t_active_language = config_get( 'default_language' );
}

lang_load( $t_active_language );
}

# ------------------
# Ensures that a language file has been loaded
function lang_ensure_loaded() {
global $g_lang_current;

# Load the language, if necessary
if ( '' == $g_lang_current ) {
lang_load_default();
}
}

# ------------------
# Retrieves an internationalized string
# This function will return one of (in order of preference):
# 1. The string in the current user's preferred language (if defined)
# 2. The string in English
function lang_get( $p_string ) {
global $g_lang_strings;

lang_ensure_loaded();

# note in the current implementation we always return the same value
# because we don't have a concept of falling back on a language. The
# language files actually *contain* English strings if none has been
# defined in the correct language

if ( lang_exists( $p_string ) ) {
return $GLOBALS['s_'.$p_string];
return $g_lang_strings[$p_string];
} else {
trigger_error( ERROR_LANG_STRING_NOT_FOUND, WARNING );
return '';
Expand All @@ -36,7 +119,11 @@ function lang_get( $p_string ) {
# ------------------
# Check the language entry, if found return true, otherwise return false.
function lang_exists( $p_string ) {
return ( isset( $GLOBALS['s_' . $p_string] ) );
global $g_lang_strings;

lang_ensure_loaded();

return ( isset( $g_lang_strings[$p_string] ) );
}

# ------------------
Expand All @@ -55,41 +142,4 @@ function lang_get_defaulted( $p_string, $p_default = null ) {
}
}
}

# ------------------
# MAIN CODE
# ------------------

# Nasty code to select the proper language file
# Default language is used if database is unavailable (for error handling)
if ( function_exists('db_query') && !is_blank( $g_string_cookie_val ) ) {
$query = "SELECT DISTINCT language
FROM $g_mantis_user_pref_table p, $g_mantis_user_table u
WHERE u.cookie_string='$g_string_cookie_val' AND
u.id=p.user_id";
$result = db_query( $query );
$g_active_language = db_result( $result, 0 , 0 );
if ( false == $g_active_language ) {
$g_active_language = $g_default_language;
}
} else {
$g_active_language = $g_default_language;
}

# in most scenarios English is done first, then translated,
# hence including the English first would show non-translated
# strings in English rather than giving errors (if the copying
# script is not used)
$t_lang_dir = dirname ( dirname ( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR;
if ( $g_active_language != 'english' ) {
require_once( $t_lang_dir . 'strings_english.txt' );
}
require_once( $t_lang_dir . 'strings_'.$g_active_language.'.txt' );

# Allow overriding strings declared in the language file.
# custom_strings_inc.php can use $g_active_language
$t_custom_strings = dirname ( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'custom_strings_inc.php';
if ( file_exists( $t_custom_strings ) ) {
require_once( $t_custom_strings );
}
?>
3 changes: 3 additions & 0 deletions doc/ChangeLog
Expand Up @@ -7,8 +7,11 @@ Mantis ChangeLog
* Fix: #2937: 'Double quotes not handled correctly in version names'
* Fix: #2936: 'SYSTEM WARNING: ob_gzhandler() used twice'
* Fix: #2941: Checking that project upload path exists and is writable to webserver
* Fix: lang_api did not load the user's preferred language
* Fix: obscure error when database connect failed
* Removed config option (mail_send_crlf): having this option off (default) violated RFC 822bis and there shouldn't be any server which required it to be set to off
* Languages: Updated German and Italian localizations.
* Security enhancement: it is now impossible to 'fill in' forgotten language strings using GET/POST/COOKIE variables

2003.02.16 - 0.18.0a1

Expand Down

0 comments on commit 36f1cfc

Please sign in to comment.