ZF-11279: Zend_Currency creates invalid cache ids for values with fractions

Issue Type: Bug Created: 2011-04-11T23:11:01.000+0000 Last Updated: 2012-02-21T22:54:13.000+0000 Status: Open Fix version(s): Reporter: Rich Peterson (sootsnoot) Assignee: Thomas Weidner (thomas) Tags: - Zend_Currency

Related issues: Attachments:


I'm not skilled enough to provide a php_unit testcase reproducer, but here is the behavior I'm seeing. The application has a Zend_Locale object set with the en_US locale stored in the Zend_Locale registry key. I run the following code:

<pre class="literal">
    $cur = new Zend_Currency(array('value' => 1234), 'aa_DJ');
    echo "$cur\n";

I get reasonable output (I can't swear it's correct since I don't know the currency):

<pre class="literal">

But if give the value a fractional part, say:

<pre class="literal">
    $cur = new Zend_Currency(array('value' => 1234.56), 'aa_DJ');
    echo "$cur\n";

I get (using ZF 1.11.1 sources, but the 1.11.5 sources are identical in this regard):

<pre class="literal">
Zend_Cache_Exception: Invalid id or tag 'Zend_LocaleC_aa_DJ_nametocurrency_1234.56' : must use only [a-zA-Z0-9_] in C:\xampp\htdocs\OSH0\library\Zend\Cache.php on line 209

A more complete traceback is:

<pre class="literal">
Locale/Data.php.Zend_Locale_Data::getContent : lineno 948() Locale/Data.php at line 948 
Currency.php.Zend_Currency->getName : lineno 405() Currency.php at line 405 
Currency.php.Zend_Currency->__construct : lineno 95() Currency.php at line 95   

In XDebug, I can see that this happens because __construct() calls getName() directly at line 110 with a first parameter $options that is array('value' => 1234.56), and within getName() the first parameter is called $currency, which gets passed to self::_checkParams($currency, $locale), which returns $params as follows:

<pre class="literal">
    'locale' => 'aa_DJ',
    'currency' => array(
    'name' => array(
    'country' => 'DJ'

So when getName() at line 405 makes the call

<pre class="literal">
$name = Zend_Locale_Data::getContent($params['locale'], 'nametocurrency', $params['currency'])

The value of $params['currency'] is array(1234.56).

getContent() constructs a cache id by imploding an array value passed in with '_', urlencoding that into a variable named $val, and finally producing the cache id as:

<pre class="literal">
$id = strtr('Zend_LocaleC_' . $locale . '_' . $path . '_' . $val, array('-' => '_', '%' => '_', '+' => '_'));

The implode() and urlencode() on the passed-in value don't change anything, so $val is just "1234.56", and the strtr() doesn't do anything to the '.', which results in the invalid cache id.

But I don't know whether the strtr should be replacing more characters, or whether the problem is that the "1234.56" should not have gotten into $params['currency']. It seems suspicious that $params['names'] got that same value, array(1234.56), but it is the $params['currency'] value that directly causes the problem. If that value is correct, and it's the strtr call that should be changed to replace '.' characters, then would it also need to replace ',' characters to handle default locales where ',' is the radix point?


Posted by Mike Soule (mikestitch) on 2012-02-21T22:54:13.000+0000

Please fix this :(

Have you found an issue?

See the Overview section for more details.


© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.