php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #18160 setlocale() affect apache bad behavior
Submitted: 2002-07-04 07:02 UTC Modified: 2002-10-23 01:00 UTC
From: neat at 263 dot net Assigned:
Status: No Feedback Package: Apache related
PHP Version: 4.2.1 OS: RedHat Linux 7.2
Private report: No CVE-ID: None
 [2002-07-04 07:02 UTC] neat at 263 dot net
apache 1.3.20 with php 4.2.1
setlocale get my apache vitural host not work (can not find any file I requested, all 404).

repeat step(on my linux):
1.write a test file setlocale.php:
<?
//any valid setlocale will all repeat the bug.
setlocale(LCTIME,"C"); 
?>
2.place the file into my default virtual host htdocs dirtory.
3.in the browser refresh the url of setlocale.php. so first several time get empty page, then get some 404 error, and then all is 404 error, any page in the virtual host will not be accessed again until I reload or stop-start apache.

I notice my env var LANG in the phpinfo page is setting to "zh_CN.GB2312" because I use chinese interface of kde.

I consider that this bug is because the php module does not restore the correct locale setting before the script execute. so I try to fix this bug by comment the line 1107 of file ext/standard/basic_functions.c
    if (BG(locale_string) != NULL) {
        setlocale(LC_ALL, "C"); <---change the second paremeter to "" will be ok

        setlocale(LC_CTYPE, "");<---comment this line will also be ok
    }
after this simple fix, the bug not repeated.
but I think this is not a best way to fix this bug, so please check it. (I think this is not a correct way to fix it, but 
when apache starting, I get 2 group locale value from a little code in the main.c php_module_startup() line 920:
#if HAVE_SETLOCALE
        if (sapi_module.log_message) {
                sapi_module.log_message(setlocale(LC_ALL,NULL));
                sapi_module.log_message(setlocale(LC_CTYPE,NULL));
        }
        setlocale(LC_CTYPE, "");
        if (sapi_module.log_message) {
                sapi_module.log_message(setlocale(LC_CTYPE,NULL));
        }
#endif

the result:
first group:
C
C
zh_CN.GB2312

second group:(seems apache or php sometimes has set all locales)
LC_CTYPE=zh_CN.GB2312;LC_NUMERIC=C;LC_TIME=zh_CN.GB2312;LC_COLLATE=zh_CN.GB2312;LC_MONETARY=zh_CN.GB2312;LC_MESSAGES=zh_CN.GB2312;LC_PAPER=zh_CN.GB2312;LC_NAME=zh_CN.GB2312;LC_ADDRESS=zh_CN.GB2312;LC_TELEPHONE=zh_CN.GB2312;LC_MEASUREMENT=zh_CN.GB2312;LC_IDENTIFICATION=zh_CN.GB2312
zh_CN.GB2312
zh_CN.GB2312

and I add some print code into ext/standard/basic_functions.c: 
    /* Check if locale was changed and change it back
       to the value in startup environment */
    if (BG(locale_string) != NULL) {
        php_error(E_WARNING, "LC_ALL before shutdown function: '%s'", setlocale(LC_ALL,NULL));
        setlocale(LC_ALL, "C");
        php_error(E_WARNING, "LC_ALL after set LC_ALL->C: '%s'", setlocale(LC_ALL,NULL));
        setlocale(LC_CTYPE, "");
        php_error(E_WARNING, "LC_ALL after set LC_CTYPE->'': '%s'", setlocale(LC_ALL,NULL));
    }
    STR_FREE(BG(locale_string));

---------
the result:
at the top of script I print original LC_ALL: LC_CTYPE=zh_CN.GB2312;LC_NUMERIC=C;LC_TIME=zh_CN.GB2312;LC_COLLATE=zh_CN.GB2312;LC_MONETARY=zh_CN.GB2312;LC_MESSAGES=zh_CN.GB2312;LC_PAPER=zh_CN.GB2312;LC_NAME=zh_CN.GB2312;LC_ADDRESS=zh_CN.GB2312;LC_TELEPHONE=zh_CN.GB2312;LC_MEASUREMENT=zh_CN.GB2312;LC_IDENTIFICATION=zh_CN.GB2312

when exec shutdown function, get result:
Warning: LC_ALL before shutdown function: 'LC_CTYPE=zh_CN.GB2312;LC_NUMERIC=C;LC_TIME=C;LC_COLLATE=zh_CN.GB2312;LC_MONETARY=zh_CN.GB2312;LC_MESSAGES=zh_CN.GB2312;LC_PAPER=zh_CN.GB2312;LC_NAME=zh_CN.GB2312;LC_ADDRESS=zh_CN.GB2312;LC_TELEPHONE=zh_CN.GB2312;LC_MEASUREMENT=zh_CN.GB2312;LC_IDENTIFICATION=zh_CN.GB2312' in Unknown on line 0

Warning: LC_ALL after set LC_ALL->C: 'C' in Unknown on line 0

Warning: LC_ALL after set LC_CTYPE->'': 'LC_CTYPE=zh_CN.GB2312;LC_NUMERIC=C;LC_TIME=C;LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=C;LC_PAPER=C;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=C;LC_IDENTIFICATION=C' in Unknown on line 0


definitely this setting does same with the value before the setlocale executed. the fixs I used just now is indeed set LC_CTYPE and other LC*s(mostly) to a same value('C' or 'zh_CN.GB2312', it just make my apache can find my virtual host path, but not a good fix. good fix should restore this values into it's original value before script executed.
SO, we need a good perfect way to restory the locale values.

by the way, if several threads of apache share a common locale, it will cause some another problems. if we can not resolve this problem, we have to declare the setlocale is a dangerous function which should not called by muti-user php applications.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-07-04 07:11 UTC] neat at 263 dot net
and if client put some env vars like LANG into some other value, will this be set back to the original value when script shutdown?
 [2002-10-07 22:06 UTC] iliaa@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php4-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php4-win32-latest.zip


 [2002-10-23 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over 2 weeks, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 30 14:01:28 2024 UTC