Zend Framework

Zend_Date broken when using mbstring with overloading

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 1.10.0, 1.10.1, 1.10.2, 1.10.3, 1.10.4, 1.10.5, 1.10.6
  • Fix Version/s: 1.11.0
  • Component/s: Zend_Date
  • Labels:
    None

Description

When outputting Zend_Date::DATE_LONG in locales with UTF-8 in the format string (such as 'zh') the output is returning half the string with only half the last character.

This is only when mbstring.func_overload is enabled for strlen and the internal encoding is set to UTF-8.

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

Test case:

$date = new Zend_Date('2008-12-10');
echo $date->get(Zend_Date::DATE_LONG, 'zh');

Output:
2008年10�

Expected:
2008年10月12日

This issue appears to still be happening in SVN trunk.

Faulty function:
Zend_Date::_toToken()
_toToken loops over the format string using strlen() to determine the length of the string, and uses $part[$i] to access the individual bytes.
The issue comes about when strlen is overloaded by turning on mbstring.func_overload. This causes strlen to return the number of UTF-8 characters in the string, not the number of bytes.

Rejected solution:
use mb_strlen($part, '8bit') in place of strlen($part) to make sure it returns the number of bytes in the string regardless of the current internal encoding.
NOTE: This solution was rejected because use of mb_ functions is not acceptable in the Zend_Date.

New proposed solution:
use isset($part[$i]) in place of strlen($part) in the for loop.
This is the same check that is used further down that same function to make sure it does not read off the end of the string when reading of the current position.

  1. Zend.patch
    14/Jul/10 12:35 AM
    0.5 kB
    Michael Cooper
  2. Zend.patch
    13/Jul/10 9:54 PM
    0.5 kB
    Michael Cooper

Activity

Hide
Michael Cooper added a comment -

Attached proposed patch

Show
Michael Cooper added a comment - Attached proposed patch
Hide
Michael Cooper added a comment -

Added relevant php.ini configuration settings.

Show
Michael Cooper added a comment - Added relevant php.ini configuration settings.
Hide
Thomas Weidner added a comment -

Patch not accepted.
Usage of mb* is not allowed within these components.

Show
Thomas Weidner added a comment - Patch not accepted. Usage of mb* is not allowed within these components.
Hide
Michael Cooper added a comment -

Attached alternative solution patch.

Alternative solution:
Use isset($part[$i]) instead to detect the end of the string.

isset() is also used further down in the function to detect the end of the string.

Show
Michael Cooper added a comment - Attached alternative solution patch. Alternative solution: Use isset($part[$i]) instead to detect the end of the string. isset() is also used further down in the function to detect the end of the string.
Hide
Thomas Weidner added a comment -

Verification:
I just added a unittest.

The problem does not occur when mbstring is used without overloading and it does also not occur when mbstring isn't available at all.

In all cases this method works as expected.

Only when mbstring is used with overloading then things do not work anymore because utf8 is no longer handled as utf8.

Show
Thomas Weidner added a comment - Verification: I just added a unittest. The problem does not occur when mbstring is used without overloading and it does also not occur when mbstring isn't available at all. In all cases this method works as expected. Only when mbstring is used with overloading then things do not work anymore because utf8 is no longer handled as utf8.
Hide
Thomas Weidner added a comment -

Changed issue header

Show
Thomas Weidner added a comment - Changed issue header
Hide
Michael Cooper added a comment -

Updated description with new proposed solution.

Show
Michael Cooper added a comment - Updated description with new proposed solution.
Hide
Thomas Weidner added a comment - - edited

Fixed with r22713
Thank you for your time and report

Show
Thomas Weidner added a comment - - edited Fixed with r22713 Thank you for your time and report

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: