#2615 function overloading breaks with strtolower

Produces PHP errors
open
nobody
None
5
2009-01-31
2009-01-26
Markus Malkusch
No

I have a server with

mbstring.internal_encoding = UTF-8
mbstring.func_overload = 7

Try it! I can't tell what's wrong, but the application is completly broken. Yeah, that's useful information. OK that's what the log says:

PHP Warning: mb_strtolower() [<a href='function.mb-strtolower'>function.mb-strtolower</a>]: Unknown encoding &quot;(null)&quot; in /var/www/malkusch.de/ssl/webmail/functions/imap_mailbox.php on line 111

Your log will probably say something else, because I started to fix the calls...but it's too much. It works when strtolower() has a second parameter:

strtolower($string, 'UTF-8');

Exactly it seems to be a PHP-Bug because, as of my runtime setting, the second parameter should implictly be 'UTF-8'. An imediate ini_get('mbstring.internal_encoding') before strolower() proofs my setting.

I can't reproduce the problem in a small test case. Somewhere you're doing something which triggers an unknown bug in PHP which let's PHP forget the implicit second parameter for strtolower (and strtoupper).

You know your code better and could probably have an idea what could be responsable for this strange behavious.

As func_overload is not configurable through .htaccess (even though the manual says that) I can't disable func_overloading.

Greetings
Markus Malkusch

Discussion

  • BTW: squirrelmail-1.4.17 and php-5.2.8

     
  • OK I found it:
    mb_internal_encoding('pass') in functions/i18n.php:446 breaks the application. For me and my setting it's enough to comment it out.

     
  • You seem to have neglected to read the code comments in the code that you changed. "// mbstring.func_overload<>0 fix. See cvs HEAD comments." Here are the comments that it is referring to:

    /**
    * mbstring.func_overload fix (#929644).
    *
    * php mbstring extension can replace standard string functions with their multibyte
    * equivalents. See http://www.php.net/ref.mbstring#mbstring.overload. This feature
    * was added in php v.4.2.0
    *
    * Some SquirrelMail functions work with 8bit strings in bytes. If interface is forced
    * to use mbstring functions and mbstring internal encoding is set to multibyte charset,
    * interface can't trust regular string functions. Due to mbstring overloading design
    * limits php scripts can't control this setting.
    *
    * This hack should fix some issues related to 8bit strings in passwords. Correct fix is
    * to disable mbstring overloading. Japanese translation uses different internal encoding.
    */

    See also:

    http://sourceforge.net/tracker/index.php?func=detail&aid=929644&group_id=311&atid=423679

     
    • status: open --> closed
     
  • No I didn't read the comments. Anyway you did realize that mb_internal_encoding('pass') forces the overloaded functions not to work and breaks your application?

    > Some SquirrelMail functions work with 8bit strings in bytes.

    I guess it's about the size of those strings. mb_strlen($str, '8bit') gives the correct size for 8bit strings.

    > Correct fix is to disable mbstring overloading.

    No, I want to use mbstring overloading in my applications! It's not possible to disable it in a per directory context,
    so the complete server has to use it.

     
  • mb_internal_encoding('pass'); is intentional. If it breaks, then please show how - without hacking the code first and then giving unrelated error messages.

    You CAN turn it on for your other applications and off for SM. Please see:

    http://www.php.net/manual/mbstring.configuration.php

     
  • > mb_internal_encoding('pass'); is intentional. If it breaks, then please
    > show how

    <?php

    var_dump(ini_get('mbstring.internal_encoding'));
    mb_internal_encoding('pass');
    var_dump(strtolower('test'));

    ?>

    produces this output:

    ,--
    | string 'UTF-8' (length=5)
    |
    | Warning: mb_strtolower() [function.mb-strtolower]: Unknown
    | encoding "(null)" in /export/www/malkusch/test/test.php on line 5
    |
    | boolean false
    `--

    I think you can imagine how your application behaves if all those
    overwritten functions return false.

    > You CAN turn it on for your other applications and off for SM. Please
    > see:
    >
    > http://www.php.net/manual/mbstring.configuration.php

    I know the manual and I already said that mbstring.func_overload is not working
    in a PHP_INI_PERDIR context. At least not for my two servers were I tested it.
    BTW. the manual indicates that:

    ,--<http://www.php.net/manual/en/mbstring.overload.php>
    | Note: It is not recommended to use the function overloading option in the
    | per-directory context, because it's not confirmed yet to be stable enough
    | in a production environment and may lead to undefined behaviour.
    `--

     
  • With the settings in php.ini that you specified and your test code, I cannot reproduce your warning, but that appears to be because I am looking at PHP 5.1.

    However, this turns overloading off locally for SquirrelMail in my tests:

    <Directory /usr/share/squirrelmail>
    php_flag mbstring.func_overload 0
    </Directory>

    The warning you get looks as if it might be a PHP bug that should be reported to them. "pass" is not null. OTOH, "pass" may be treated as invalid and is therefore (?) quietly changed to null, which this Gentoo tracker suggests:

    http://bugs.gentoo.org/show_bug.cgi?id=213528

    The PHP manual states nothing about this, though. It may be possible to get away with changing the encoding back to a single byte character set. You might play around with changing "pass" to "ISO-8859-1" or something else, but who knows what other string functions that could break.

     
    • status: closed --> open