php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #38577 ini settings leak between virtual hosts with Apache 1.3
Submitted: 2006-08-24 10:17 UTC Modified: 2007-02-13 10:58 UTC
From: php at diptyque dot net Assigned:
Status: Not a bug Package: Apache related
PHP Version: 4.4.4 OS: FreeBSD 4.4
Private report: No CVE-ID: None
 [2006-08-24 10:17 UTC] php at diptyque dot net
Description:
------------
Changing internal character encoding during script 
execution apparently affects mbstring function overloading: 
strlen() returns the length of the string based on current 
internal encoding although function overloading is disabled 
(either through php.ini, vhost and/or .htaccess settings.)

On apache 1.3 startup or graceful restart, script may run 
as expected but repeated requests would inevitably trigger 
the bug -- on my server setup, MediaWiki cannot run 
reliably because of this weird behavior :-/

The bug is not triggered when I do run this script under 
other SAPIs such as CLI or FastCGI.

./configure --with-apxs=/usr/local/apache/bin/apxs
--with-mysql=/usr/local --with-openssl=/usr/local/apache
--with-gd=/usr/local --with-zlib --with-bz2 --with-xml
--with-freetype-dir=/usr/local --with-ttf --with-imap 
--with-curl
--with-jpeg-dir=/usr/local --with-png-dir=/usr/local
--with-readline=/usr/local --prefix=/usr/local/apache
--with-config-file-path=/usr/local/apache/etc 
--enable-mbstring
--enable-mbregex --enable-zend-multibyte
; configure line

Reproduce code:
---------------
http://www.diptyque.net/bugs/mbinfo.php
; running PHP 4.4 as an apache module
; display charset is set to UTF-8

; when internal encoding is set to UTF-8,
; strlen() returns the wrong character count
; (e.g. 18 instead of 19)

http://www.diptyque.net/bugs/mbinfo.phps
; source code


Expected result:
----------------
string(10) "ISO-8859-1"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "M?thodes de codage"
int(19)
--
bool(true)
string(5) "UTF-8"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "M?thodes de codage"
int(18)
--
bool(true)
string(10) "ISO-8859-1"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "M?thodes de codage"






Actual result:
--------------
string(10) "ISO-8859-1"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "M?thodes de codage"
int(19)
--
bool(true)
string(5) "UTF-8"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "M?thodes de codage"
int(19)
--
bool(true)
string(10) "ISO-8859-1"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "M?thodes de codage"




Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-08-24 11:03 UTC] tony2001@php.net
Can't reproduce. I get int(19) in all cases.
 [2006-08-24 12:28 UTC] php at diptyque dot net
Granted I could not reproduce either this bug using a WAMP 
setup but did you follow the hyperlink I gave on my 
FreeBSD-based server, where you can consistently replicate 
this bug on each GET request?
 [2006-08-24 12:33 UTC] php at diptyque dot net
Oops, my mistake. You should swap Expected and Actual 
results. Actual result is int(18) !? Expected result is 
int(19).
 [2006-08-24 12:41 UTC] tony2001@php.net
Right, int(19) is what I get on Linux and FreeBSD 5.4.
 [2006-08-24 15:04 UTC] php at diptyque dot net
I moved mbstring function overload initial setting (6) from 
my php.ini to specific virtual hosts configuration sections 
but to no avail.

It would seem that some Apache processes get it right while 
others get it wrong (!) This is quite weird -- for example, 
process #58902 returns int(18) while #58914 returns 
int(19).

[diptyque] % GET http://localhost/bugs/mbinfo2.php
<pre>int(58902)
string(10) "ISO-8859-1"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "Méthodes de codage"
int(19)
--
bool(true)
string(5) "UTF-8"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "Méthodes de codage"
int(18)
--
bool(true)
string(10) "ISO-8859-1"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "Méthodes de codage"
int(19)
</pre>

[diptyque] % GET http://localhost/bugs/mbinfo2.php
<pre>int(58914)
string(10) "ISO-8859-1"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "Méthodes de codage"
int(19)
--
bool(true)
string(5) "UTF-8"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "Méthodes de codage"
int(19)
--
bool(true)
string(10) "ISO-8859-1"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "Méthodes de codage"
int(19)
</pre>
 [2006-08-24 15:15 UTC] tony2001@php.net
Please try with minimal configuration (like ./configure --enable-mbstring) and PHP CLI.
If you're still able to reproduce it, you're likely to be the only person who can help you, since I really doubt anyone else can do it.
 [2006-08-24 16:20 UTC] php at diptyque dot net
Agreed but I'm not making things up, you know. Something is 
obviously wrong on my Apache 1.3.34 setup. Could this be a 
conflict with some extension or Apache module? Of course, 
no opcode cache is running. Any tip welcome.

This weird behavior has been plaguing me for 2 months now 
and rebuilding PHP doesn't seem to help. I wrote a second 
test case which demonstrates that function overloading is 
effectively taking place sporadically while running under 
apache SAPI -- strlen() may accept the optional encoding 
argument (!?) as shown in the script output below.

http://www.diptyque.net/bugs/mbinfo2.php

http://www.diptyque.net/bugs/mbinfo2.phps
; source code

=begin
[diptyque] % GET http://www.diptyque.net/bugs/mbinfo2.php
<pre>int(72208)
string(10) "ISO-8859-1"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "Méthodes de codage"
int(19)
--
bool(true)
string(5) "UTF-8"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "Méthodes de codage"
int(18)
int(19)
--
bool(true)
string(10) "ISO-8859-1"
string(10) "ISO-8859-1"
string(1) "0"
string(19) "Méthodes de codage"
int(19)
int(18)
</pre>
=end

If I do run the same script through PHP CLI or FastCGI, I 
get the following expected warnings:

PHP Warning:  Wrong parameter count for strlen() in 
/path/to/htdocs/bugs/mbinfo2.php on line 17
PHP Warning:  Wrong parameter count for strlen() in 
/path/to/htdocs/bugs/mbinfo2.php on line 25
 [2006-08-25 13:32 UTC] php at diptyque dot net
I forgot to mention that mbstring.func_overload is enabled  
on a per-vhost basis for some other web sites I'm hosting 
on this platform.
 [2006-08-25 13:39 UTC] tony2001@php.net
Reclassified as Apache-related issue.
 [2006-08-25 15:51 UTC] judas dot iscariote at gmail dot com
PHP5 produces the same effects for you ?
 [2006-08-28 15:56 UTC] php at diptyque dot net
Dunno for PHP 5 -- I have to make some tests before trying 
to switch -- but I wonder if this bug could be related to 
http://bugs.php.net/bug.php?id=37932.
 [2006-09-06 16:13 UTC] php at diptyque dot net
Just downloaded the latest stable release, built it and ran 
the test suite and mb_strlen() test case failed because 
AFAIK this version of PHP (4.4.5-dev) doesn't emit 
catchable errors yet (E_RECOVERABLE_ERROR). Anyway I'm 
going to install it tomorrow morning and will let you know 
ASAP if it does fix the ini settings leak between virtual 
hosts.

===========================================================
=====================
/usr/local/src/php4-STABLE-200609061230/ext/mbstring/tests/
mb_strlen.phpt
===========================================================
=====================

---- EXPECTED OUTPUT
== ASCII ==
40
40
== EUC-JP ==
43
72
== SJIS ==
43
72
== JIS ==
43
90
== UTF-8 ==
43
101
== WRONG PARAMETERS ==
ERR: Notice
5
ERR: Catchable fatal error
ERR: Notice
6
ERR: Warning
---- ACTUAL OUTPUT
== ASCII ==
40
40
== EUC-JP ==
43
72
== SJIS ==
43
72
== JIS ==
43
90
== UTF-8 ==
43
101
== WRONG PARAMETERS ==
ERR: Notice
5
ERR: Notice
6
ERR: Warning
---- FAILED

===========================================================
=====================
019- ERR: Catchable fatal error
019+ ERR: Notice
020- ERR: Notice
020+ 6
021- 6
021+ ERR: Warning
022- ERR: Warning
===========================================================
=====================
 [2006-09-06 16:31 UTC] tony2001@php.net
Fixed, thanks.
What about your issue?
 [2006-09-07 09:29 UTC] php at diptyque dot net
Sorry but it doesn't make it. Mbstring function overloading 
setting is unfortunately persistent once an Apache process 
has served content from a vhost where this ini parameter is 
assigned a value distinct from zero.
 [2006-09-07 15:14 UTC] php at diptyque dot net
Antony, I'm not very familiar with Zend Engine 1.3 innards 
but I had a look at how Xdebug is overriding both 
var_dump() and set_time_limit() functions in 
PHP_RINIT_FUNCTION(xdebug) and how it does restore the 
original function pointers in 
PHP_RSHUTDOWN_FUNCTION(xdebug). Peeking at mbstring 
extension source code, this looks a bit more verbose and it 
doesn't fiddle directly with 
orig->internal_function.handler (!?) to  restore the 
original function. Instead it calls subsequently 
zend_hash_update() and zend_hash_del() using the info it 
gathered inside its mb_overload_def struct... IMHO, 
mbstring ini settings are properly reset (please see 
http://bugs.php.net/bug.php?id=25753) but not the initial 
PHP function table state.
 [2006-09-07 15:25 UTC] tony2001@php.net
Please remove all zend_extensions, including XDebug and try again.
 [2006-09-07 16:39 UTC] php at diptyque dot net
FYI, I do *NOT* have any Zend or Xdebug extension 
installed... I have downloaded Xdebug only to compare its 
overriding technique with the one used in Mbstring 
extension.

=begin
[diptyque] % php -m
[PHP Modules]
bz2
ctype
curl
gd
imap
mbstring
mysql
openssl
overload
pcre
posix
readline
session
sqlite
standard
tokenizer
xml
zlib

[Zend Modules]
=end

BTW, I compared source files for apache SAPI 
(./sapi/apache/mod_php4.c) and mbstring extension 
(./ext/mbstring/mbstring.c) between version 4.4.4 and 
latest stable version and did not find anything different 
(!?)
 [2006-09-07 16:48 UTC] tony2001@php.net
I'm not sure I understand what you're trying to do and to say.
 [2006-09-08 09:02 UTC] php at diptyque dot net
I'm not trying anything. You told me to download and install 
the latest CVS snapshot. That's what I did but the erratic 
function overloading behavior is still there. Considering no 
drastic changes have been made since v4.4.4 either at the 
Apache SAPI level (mod_php4.c) or in Mbstring (mbstring.c) 
source code, this isn't very surprising.

Regarding Xdebug, this particular extension also overrides 
two core functions -- namely var_dump() and set_time_limit
(). Don't you think it would be interesting to know if the 
function overloading that Xdebug performs is sticky or not 
when running under the Apache 1.3 SAPI?

I have the strong feeling that the original PHP function 
table state is not restored properly by Mbstring but I don't 
have the time nor the resources needed to nail down further 
the origin of the leak -- i.e. the overridden functions 
stickiness or whatever you may call it.
 [2006-10-18 21:09 UTC] tony2001@php.net
See bug #38670 and bug #38566.
Please use bug #38760 for further comments.
 [2007-02-13 10:58 UTC] php at diptyque dot net
IMHO, the latest mbstring-related bug fix in PHP 5.2.1 has much more in common with the problem I reported than those bug report numbers you previously pointed to (!?)

see http://bugs.php.net/bug.php?id=39361
; mbstring function overloading - done although not activated
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 16:01:28 2024 UTC