Issues

ZF-12403: Cannot validate Date if end-user uses custom HTTP_ACCEPT_LANGUAGE

Description

Date validation throw exception if the end-user enter custom values for HTTP_ACCEPT_LANGUAGE which are used internally in Zend_Locale. Those values are 'root', 'auto' and 'browser'.

I believe those internal values should never be accepted from end-user. However I can't wrap my mind around Zend_Locale well enough to provide a patch for that.

Here is a test script to be used via CLI (so we can manually set HTTP_ACCEPT_LANGUAGE):

<?php
require_once('Zend/Version.php');
require_once('Zend/Locale.php');
require_once('Zend/Registry.php');
require_once('Zend/Validate/Date.php');

if (php_sapi_name() != 'cli')
    die('must run as CLI script');

// Extends Zend_Locale, so we can reset its state between tests
class Zend_LocaleReset extends Zend_Locale {
    public static function reset() {
        self::$_auto = null;
        self::$_browser = null;
        self::$_environment = null;
    }
}

function test($accept) 
{
    Zend_LocaleReset::reset();
    $_SERVER['HTTP_ACCEPT_LANGUAGE'] = $accept;

    $locale = new Zend_Locale();
    Zend_Registry::set('Zend_Locale', $locale);
    
    echo $accept . "\t=>\t" . $locale->getLanguage() . ': ';
    try {
        $validator = new Zend_Validate_Date(array('format' => 'Y-m-d'));
        $validator->isValid('2012-08-08');
        echo 'OK';
    } catch (Exception $exc) {
        echo $exc->getMessage();
    }
    echo PHP_EOL;
    
}

echo 'Zend Version: ' . Zend_Version::VERSION . PHP_EOL . PHP_EOL;
test(null);
test('');
test('en');
test('en-US,en;q=0.8,ko;q=0.6');
test('fr');
test('non valid string');
test('root');
test('auto');
test('browser');
test('environment');

It will output the following:

$ php test.php 
Zend Version: 1.11.0dev

    =>  en: OK
    =>  en: OK
en  =>  en: OK
en-US,en;q=0.8,ko;q=0.6 =>  en: OK
fr  =>  fr: OK
non valid string    =>  en: OK
root    =>  root: The locale '' is no known locale
auto    =>  root: The locale '' is no known locale
browser =>  root: The locale '' is no known locale
environment =>  en: OK

Comments

In fact if the value of HTTP_ACCEPT_LANGUAGE is any word of letter up to 8 chars that is not a language or a country, it fails :

 
test('null');
test('top');

will output

 
null    =>      root: The locale '' is no known locale
top     =>      root: The locale '' is no known locale

A solution could be to validate input in static function getBrowser() of Zend_Locale :

something like this ??


if (!isset(self::$_localeData[$region]) && !isset(self::$_territoryData[$region])) {
    continue;
}
foreach ($countrys as $country) {

This issue has been closed on Jira and moved to GitHub for issue tracking. To continue following the resolution of this issues, please visit: https://github.com/zendframework/zf1/issues/10