Aleksander Machniak
2013-08-24 4db26a430b0a2fb9b5c725aef373c6b79e27f100
Fix handling of non-default date formats (#1489294)
- remove ambiguous m/d/Y format from default config

Conflicts:

CHANGELOG
config/main.inc.php.dist
program/lib/Roundcube/rcube_utils.php
tests/Framework/Utils.php
4 files modified
80 ■■■■ changed files
CHANGELOG 1 ●●●● patch | view | raw | blame | history
config/main.inc.php.dist 3 ●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_utils.php 37 ●●●● patch | view | raw | blame | history
tests/Framework/Utils.php 39 ●●●●● patch | view | raw | blame | history
CHANGELOG
@@ -2,6 +2,7 @@
===========================
- Fix Junk folder icon alignment when it's nested in inbox folder (#1489292)
- Fix handling of non-default date formats (#1489294)
- Fix unquoted path in PREG expression on Windows (#1489290)
RELEASE 0.9.3
config/main.inc.php.dist
@@ -436,7 +436,8 @@
$rcmail_config['date_format'] = 'Y-m-d';
// give this choice of date formats to the user to select from
$rcmail_config['date_formats'] = array('Y-m-d', 'd-m-Y', 'Y/m/d', 'm/d/Y', 'd/m/Y', 'd.m.Y', 'j.n.Y');
// Note: do not use ambiguous formats like m/d/Y
$config['date_formats'] = array('Y-m-d', 'Y/m/d', 'Y.m.d', 'd-m-Y', 'd/m/Y', 'd.m.Y', 'j.n.Y');
// use this format for time display (date or strftime format)
$rcmail_config['time_format'] = 'H:i';
program/lib/Roundcube/rcube_utils.php
@@ -717,16 +717,37 @@
     */
    public static function strtotime($date)
    {
        $date = trim($date);
        // check for MS Outlook vCard date format YYYYMMDD
        if (preg_match('/^([12][90]\d\d)([01]\d)(\d\d)$/', trim($date), $matches)) {
            return mktime(0,0,0, intval($matches[2]), intval($matches[3]), intval($matches[1]));
        }
        else if (is_numeric($date)) {
            return $date;
        if (preg_match('/^([12][90]\d\d)([01]\d)([0123]\d)$/', $date, $m)) {
            return mktime(0,0,0, intval($m[2]), intval($m[3]), intval($m[1]));
        }
        // support non-standard "GMTXXXX" literal
        $date = preg_replace('/GMT\s*([+-][0-9]+)/', '\\1', $date);
        // common little-endian formats, e.g. dd/mm/yyyy (not all are supported by strtotime)
        if (preg_match('/^(\d{1,2})[.\/-](\d{1,2})[.\/-](\d{4})$/', $date, $m)
            && $m[1] > 0 && $m[1] <= 31 && $m[2] > 0 && $m[2] <= 12 && $m[3] >= 1970
        ) {
            return mktime(0,0,0, intval($m[2]), intval($m[1]), intval($m[3]));
        }
        // unix timestamp
        if (is_numeric($date)) {
            return (int) $date;
        }
        // Clean malformed data
        $date = preg_replace(
            array(
                '/GMT\s*([+-][0-9]+)/',                   // support non-standard "GMTXXXX" literal
                '/[^a-z0-9\x20\x09:+-]/i',                // remove any invalid characters
                '/\s*(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*/i', // remove weekday names
            ),
            array(
                '\\1',
                '',
                '',
            ), $date);
        // if date parsing fails, we have a date in non-rfc format.
        // remove token from the end and try again
@@ -739,7 +760,7 @@
            $date = implode(' ', $d);
        }
        return $ts;
        return (int) $ts;
    }
tests/Framework/Utils.php
@@ -229,4 +229,43 @@
        }
    }
    /**
     * rcube:utils::strtotime()
     */
    function test_strtotime()
    {
        $test = array(
            '1' => 1,
            '' => 0,
            '2013-04-22' => 1366581600,
            '2013/04/22' => 1366581600,
            '2013.04.22' => 1366581600,
            '22-04-2013' => 1366581600,
            '22/04/2013' => 1366581600,
            '22.04.2013' => 1366581600,
            '22.4.2013'  => 1366581600,
            '20130422'   => 1366581600,
        );
        foreach ($test as $datetime => $ts) {
            $result = rcube_utils::strtotime($datetime);
            $this->assertSame($ts, $result, "Error parsing date: $datetime");
        }
    }
    /**
     * rcube:utils::normalize _string()
     */
    function test_normalize_string()
    {
        $test = array(
            '' => '',
            'abc def' => 'abc def',
        );
        foreach ($test as $input => $output) {
            $result = rcube_utils::normalize_string($input);
            $this->assertSame($output, $result);
        }
    }
}