Aleksander Machniak
2012-09-12 a04a74fec4b5e13e8464f1f3c9071fa0b56a13eb
Improvements in building criteria string for IMAP SEARCH
4 files modified
53 ■■■■■ changed files
program/include/rcube_imap.php 8 ●●●● patch | view | raw | blame | history
program/include/rcube_shared.inc 15 ●●●●● patch | view | raw | blame | history
program/steps/mail/search.inc 2 ●●● patch | view | raw | blame | history
tests/Framework/Shared.php 28 ●●●●● patch | view | raw | blame | history
program/include/rcube_imap.php
@@ -1434,6 +1434,12 @@
            $criteria = 'UNDELETED '.$criteria;
        }
        // unset CHARSET if criteria string is ASCII, this way
        // SEARCH won't be re-sent after "unsupported charset" response
        if ($charset && $charset != 'US-ASCII' && is_ascii($criteria)) {
            $charset = 'US-ASCII';
        }
        if ($this->threading) {
            $threads = $this->conn->thread($folder, $this->threading, $criteria, true, $charset);
@@ -1465,7 +1471,7 @@
        }
        $messages = $this->conn->search($folder,
            ($charset ? "CHARSET $charset " : '') . $criteria, true);
            ($charset && $charset != 'US-ASCII' ? "CHARSET $charset " : '') . $criteria, true);
        // Error, try with US-ASCII (some servers may support only US-ASCII)
        if ($messages->is_error() && $charset && $charset != 'US-ASCII') {
program/include/rcube_shared.inc
@@ -255,6 +255,21 @@
/**
 * Check if a string contains only ascii characters
 *
 * @param string $str           String to check
 * @param bool   $control_chars Includes control characters
 *
 * @return bool
 */
function is_ascii($str, $control_chars = true)
{
    $regexp = $control_chars ? '/[^\x00-\x7F]/' : '/[^\x20-\x7E]/';
    return preg_match($regexp, $str) ? false : true;
}
/**
 * Remove single and double quotes from a given string
 *
 * @param string Input value
program/steps/mail/search.inc
@@ -100,7 +100,7 @@
if (!empty($subject)) {
  $search_str .= str_repeat(' OR', count($subject)-1);
  foreach ($subject as $sub)
    $search_str .= sprintf(" %s {%d}\r\n%s", $sub, strlen($search), $search);
    $search_str .= ' ' . $sub . ' ' . rcube_imap_generic::escape($search);
}
$search_str  = trim($search_str);
tests/Framework/Shared.php
@@ -201,4 +201,32 @@
    }
    /**
     * rcube_shared.inc: is_ascii()
     */
    function test_is_ascii()
    {
        $result = is_ascii("0123456789");
        $this->assertTrue($result, "Valid ASCII (numbers)");
        $result = is_ascii("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
        $this->assertTrue($result, "Valid ASCII (letters)");
        $result = is_ascii(" !\"#\$%&'()*+,-./:;<=>?@[\\^_`{|}~");
        $this->assertTrue($result, "Valid ASCII (special characters)");
        $result = is_ascii("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
            ."\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F");
        $this->assertTrue($result, "Valid ASCII (control characters)");
        $result = is_ascii("\n", false);
        $this->assertFalse($result, "Valid ASCII (control characters)");
        $result = is_ascii("ż");
        $this->assertFalse($result, "Invalid ASCII (UTF-8 character)");
        $result = is_ascii("ż", false);
        $this->assertFalse($result, "Invalid ASCII (UTF-8 character [2])");
    }
}