diff options
Diffstat (limited to 'plugins/managesieve')
-rw-r--r-- | plugins/managesieve/Changelog | 3 | ||||
-rw-r--r-- | plugins/managesieve/lib/Net/Sieve.php | 43 |
2 files changed, 39 insertions, 7 deletions
diff --git a/plugins/managesieve/Changelog b/plugins/managesieve/Changelog index ef7573959..20e3bb8c6 100644 --- a/plugins/managesieve/Changelog +++ b/plugins/managesieve/Changelog @@ -1,5 +1,8 @@ - Fix escaping of backslash character in quoted strings (#1487780) - Fix STARTTLS for timsieved < 2.3.10 +- Fix handling of non-safe characters (double-quote, backslash) + or UTF-8 characters (dovecot's implementation bug workaround) + in script names * version 3.0 [2011-02-01] ----------------------------------------------------------- diff --git a/plugins/managesieve/lib/Net/Sieve.php b/plugins/managesieve/lib/Net/Sieve.php index d4cc3eeda..0f6a5f67a 100644 --- a/plugins/managesieve/lib/Net/Sieve.php +++ b/plugins/managesieve/lib/Net/Sieve.php @@ -475,7 +475,9 @@ class Net_Sieve if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { return PEAR::raiseError('Not currently in TRANSACTION state', 1); } - if (PEAR::isError($res = $this->_doCmd(sprintf('HAVESPACE "%s" %d', $scriptname, $size)))) { + + $command = sprintf('HAVESPACE %s %d', $this->_escape($scriptname), $size); + if (PEAR::isError($res = $this->_doCmd($command))) { return $res; } return true; @@ -740,7 +742,9 @@ class Net_Sieve if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { return PEAR::raiseError('Not currently in AUTHORISATION state', 1); } - if (PEAR::isError($res = $this->_doCmd(sprintf('DELETESCRIPT "%s"', $scriptname)))) { + + $command = sprintf('DELETESCRIPT %s', $this->_escape($scriptname)); + if (PEAR::isError($res = $this->_doCmd($command))) { return $res; } return true; @@ -759,7 +763,8 @@ class Net_Sieve return PEAR::raiseError('Not currently in AUTHORISATION state', 1); } - if (PEAR::isError($res = $this->_doCmd(sprintf('GETSCRIPT "%s"', $scriptname)))) { + $command = sprintf('GETSCRIPT %s', $this->_escape($scriptname)); + if (PEAR::isError($res = $this->_doCmd($command))) { return $res; } @@ -779,9 +784,12 @@ class Net_Sieve if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { return PEAR::raiseError('Not currently in AUTHORISATION state', 1); } - if (PEAR::isError($res = $this->_doCmd(sprintf('SETACTIVE "%s"', $scriptname)))) { + + $command = sprintf('SETACTIVE %s', $this->_escape($scriptname)); + if (PEAR::isError($res = $this->_doCmd($command))) { return $res; } + $this->_activeScript = $scriptname; return true; } @@ -808,9 +816,10 @@ class Net_Sieve $res = explode("\r\n", $res); foreach ($res as $value) { if (preg_match('/^"(.*)"( ACTIVE)?$/i', $value, $matches)) { - $scripts[] = $matches[1]; + $script_name = stripslashes($matches[1]); + $scripts[] = $script_name; if (!empty($matches[2])) { - $activescript = $matches[1]; + $activescript = $script_name; } } } @@ -833,8 +842,10 @@ class Net_Sieve } $stringLength = $this->_getLineLength($scriptdata); + $command = sprintf("PUTSCRIPT %s {%d+}\r\n%s", + $this->_escape($scriptname), $stringLength, $scriptdata); - if (PEAR::isError($res = $this->_doCmd(sprintf("PUTSCRIPT \"%s\" {%d+}\r\n%s", $scriptname, $stringLength, $scriptdata)))) { + if (PEAR::isError($res = $this->_doCmd($command))) { return $res; } @@ -1213,6 +1224,24 @@ class Net_Sieve } /** + * Convert string into RFC's quoted-string or literal-c2s form + * + * @param string $string The string to convert. + * + * @return string Result string + */ + function _escape($string) + { + // Some implementations doesn't allow UTF-8 characters in quoted-string + // It's safe to use literal-c2s + if (preg_match('/[^\x01-\x09\x0B-\x0C\x0E-\x7F]/', $string)) { + return sprintf("{%d+}\r\n%s", $this->_getLineLength($string), $string); + } + + return '"' . addcslashes($string, '\\"') . '"'; + } + + /** * Write debug text to the current debug output handler. * * @param string $message Debug message text. |