summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Peter Banyard <girgias@php.net>2021-02-26 03:03:38 +0000
committerGeorge Peter Banyard <girgias@php.net>2021-02-27 13:12:22 +0000
commit1ee6aad248117312fdc9ff7edc3ddd7bd5203d79 (patch)
tree8d32f108c3f30586582ba5e13432ea1363b96da7
parent8813f2e0c31a98828cac4570673ccd8ce79b00af (diff)
downloadphp-git-1ee6aad248117312fdc9ff7edc3ddd7bd5203d79.tar.gz
Fix Bug #80800 imap_open() fails when the flags parameter includes CL_EXPUNGE
This also affected imap_reopen(). Add a supplementary test that the CL_EXPUNGE flag does have the intended effect. Closes GH-6732
-rw-r--r--NEWS4
-rw-r--r--ext/imap/php_imap.c12
-rw-r--r--ext/imap/tests/bug80800.phpt21
-rw-r--r--ext/imap/tests/imap_open_with_cl_expunge.phpt43
-rw-r--r--ext/imap/tests/imap_reopen_with_cl_expunge.phpt48
-rw-r--r--ext/imap/tests/setup/imap_include.inc11
6 files changed, 135 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 18bd50a986..aefef64c28 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,10 @@ PHP NEWS
- Core:
. Fixed bug #75776 (Flushing streams with compression filter is broken). (cmb)
+- IMAP:
+ . Fixed bug #80800 (imap_open() fails when the flags parameter includes
+ CL_EXPUNGE). (girgias)
+
- Intl:
. Fixed bug #80763 (msgfmt_format() does not accept DateTime references).
(cmb)
diff --git a/ext/imap/php_imap.c b/ext/imap/php_imap.c
index bf04897c92..9ff1ae0618 100644
--- a/ext/imap/php_imap.c
+++ b/ext/imap/php_imap.c
@@ -735,7 +735,11 @@ PHP_FUNCTION(imap_open)
RETURN_THROWS();
}
- if (flags && ((flags & ~(OP_READONLY | OP_ANONYMOUS | OP_HALFOPEN | CL_EXPUNGE | OP_DEBUG | OP_SHORTCACHE
+ /* Check for PHP_EXPUNGE and not CL_EXPUNGE as the user land facing CL_EXPUNGE constant is defined
+ * to something different to prevent clashes between CL_EXPUNGE and an OP_* constant allowing setting
+ * the CL_EXPUNGE flag which will expunge when the mailbox is closed (be that manually, or via the
+ * IMAPConnection object being destroyed naturally at the end of the PHP script */
+ if (flags && ((flags & ~(OP_READONLY | OP_ANONYMOUS | OP_HALFOPEN | PHP_EXPUNGE | OP_DEBUG | OP_SHORTCACHE
| OP_SILENT | OP_PROTOTYPE | OP_SECURE)) != 0)) {
zend_argument_value_error(4, "must be a bitmask of the OP_* constants, and CL_EXPUNGE");
RETURN_THROWS();
@@ -858,7 +862,11 @@ PHP_FUNCTION(imap_reopen)
}
/* TODO Verify these are the only options available as they are pulled from the php.net documentation */
- if (options && ((options & ~(OP_READONLY | OP_ANONYMOUS | OP_HALFOPEN | OP_EXPUNGE | CL_EXPUNGE)) != 0)) {
+ /* Check for PHP_EXPUNGE and not CL_EXPUNGE as the user land facing CL_EXPUNGE constant is defined
+ * to something different to prevent clashes between CL_EXPUNGE and an OP_* constant allowing setting
+ * the CL_EXPUNGE flag which will expunge when the mailbox is closed (be that manually, or via the
+ * IMAPConnection object being destroyed naturally at the end of the PHP script */
+ if (options && ((options & ~(OP_READONLY | OP_ANONYMOUS | OP_HALFOPEN | OP_EXPUNGE | PHP_EXPUNGE)) != 0)) {
zend_argument_value_error(3, "must be a bitmask of OP_READONLY, OP_ANONYMOUS, OP_HALFOPEN, "
"OP_EXPUNGE, and CL_EXPUNGE");
RETURN_THROWS();
diff --git a/ext/imap/tests/bug80800.phpt b/ext/imap/tests/bug80800.phpt
new file mode 100644
index 0000000000..d75c1fde80
--- /dev/null
+++ b/ext/imap/tests/bug80800.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #80800: imap_open() fails when the flags parameter includes CL_EXPUNGE
+--SKIPIF--
+<?php
+require_once(__DIR__.'/setup/skipif.inc');
+?>
+--FILE--
+<?php
+
+require_once __DIR__.'/setup/imap_include.inc';
+
+$mail_box = imap_open(IMAP_DEFAULT_MAILBOX, IMAP_MAILBOX_USERNAME, IMAP_MAILBOX_PASSWORD, flags: CL_EXPUNGE);
+var_dump(imap_reopen($mail_box, IMAP_DEFAULT_MAILBOX, flags: CL_EXPUNGE));
+imap_close($mail_box);
+
+echo 'Connected without any issues', "\n";
+
+?>
+--EXPECT--
+bool(true)
+Connected without any issues
diff --git a/ext/imap/tests/imap_open_with_cl_expunge.phpt b/ext/imap/tests/imap_open_with_cl_expunge.phpt
new file mode 100644
index 0000000000..5d1721f861
--- /dev/null
+++ b/ext/imap/tests/imap_open_with_cl_expunge.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Test imap_open() using the CL_EXPUNGE flag
+--SKIPIF--
+<?php
+require_once(__DIR__.'/setup/skipif.inc');
+?>
+--FILE--
+<?php
+
+// include file for required variables in imap_open()
+require_once(__DIR__.'/setup/imap_include.inc');
+
+// set up temp mailbox with 3 messages
+$stream_id = setup_test_mailbox('imapopenwithclexpunge', 3, $mailbox, flags: CL_EXPUNGE);
+
+// mark messages in inbox for deletion
+for ($i = 1; $i < 4; $i++) {
+ imap_delete($stream_id, $i);
+}
+
+echo "\n-- Call to imap_close() --\n";
+var_dump( imap_close($stream_id) );
+
+// check that CL_EXPUNGE in previous imap_open() call worked
+$stream_id = imap_open($mailbox, IMAP_MAILBOX_USERNAME, IMAP_MAILBOX_PASSWORD);
+echo "There are now " . imap_num_msg($stream_id) . " msgs in mailbox '$mailbox'\n";
+
+// Close connection
+var_dump( imap_close($stream_id) );
+?>
+--CLEAN--
+<?php
+$mailbox_suffix = 'imapopenwithclexpunge';
+require_once(__DIR__.'/setup/clean.inc');
+?>
+--EXPECTF--
+Create a temporary mailbox and add 3 msgs
+New mailbox created
+
+-- Call to imap_close() --
+bool(true)
+There are now 0 msgs in mailbox '%sINBOX.phpttestimapopenwithclexpunge'
+bool(true)
diff --git a/ext/imap/tests/imap_reopen_with_cl_expunge.phpt b/ext/imap/tests/imap_reopen_with_cl_expunge.phpt
new file mode 100644
index 0000000000..78d1eddaca
--- /dev/null
+++ b/ext/imap/tests/imap_reopen_with_cl_expunge.phpt
@@ -0,0 +1,48 @@
+--TEST--
+Test imap_reopen() using the CL_EXPUNGE flag
+--SKIPIF--
+<?php
+require_once(__DIR__.'/setup/skipif.inc');
+?>
+--FILE--
+<?php
+
+// include file for required variables in imap_open()
+require_once(__DIR__.'/setup/imap_include.inc');
+
+$mailbox_suffix = 'imapreopenwithclexpunge';
+
+// set up temp mailbox with 3 messages
+$stream_id = setup_test_mailbox($mailbox_suffix , 3, $mailbox);
+
+var_dump(imap_reopen($stream_id, IMAP_DEFAULT_MAILBOX . '.' . IMAP_MAILBOX_PHPT_PREFIX . $mailbox_suffix, flags: CL_EXPUNGE));
+
+// mark messages in inbox for deletion
+for ($i = 1; $i < 4; $i++) {
+ imap_delete($stream_id, $i);
+}
+
+echo "\n-- Call to imap_close() --\n";
+var_dump( imap_close($stream_id) );
+
+// check that CL_EXPUNGE in previous imap_reopen() call worked
+$stream_id = imap_open($mailbox, IMAP_MAILBOX_USERNAME, IMAP_MAILBOX_PASSWORD);
+echo "There are now " . imap_num_msg($stream_id) . " msgs in mailbox '$mailbox'\n";
+
+// Close connection
+var_dump( imap_close($stream_id) );
+?>
+--CLEAN--
+<?php
+$mailbox_suffix = 'imapreopenwithclexpunge';
+require_once(__DIR__.'/setup/clean.inc');
+?>
+--EXPECTF--
+Create a temporary mailbox and add 3 msgs
+New mailbox created
+bool(true)
+
+-- Call to imap_close() --
+bool(true)
+There are now 0 msgs in mailbox '%sINBOX.phpttestimapreopenwithclexpunge'
+bool(true)
diff --git a/ext/imap/tests/setup/imap_include.inc b/ext/imap/tests/setup/imap_include.inc
index 223278f077..0c07f9ae2d 100644
--- a/ext/imap/tests/setup/imap_include.inc
+++ b/ext/imap/tests/setup/imap_include.inc
@@ -63,12 +63,19 @@ function displayOverviewFields($resp, array $fields = MANDATORY_OVERVIEW_FIELDS)
* @param int message_count number of test msgs to be written to new mailbox
* @param null $new_mailbox
* @param bool $simpleMessages
+ * @param int $flags OP_* (or CL_EXPUNGE) flags to pass to imap_open() sub-call
* @return resource IMAP stream to new mailbox
* @throws Exception
*/
-function setup_test_mailbox(string $mailbox_suffix, int $message_count, &$new_mailbox = null, bool $simpleMessages = true){
+function setup_test_mailbox(
+ string $mailbox_suffix,
+ int $message_count,
+ &$new_mailbox = null,
+ bool $simpleMessages = true,
+ int $flags = 0,
+){
// open a stream to default mailbox
- $imap_stream = imap_open(IMAP_DEFAULT_MAILBOX, IMAP_MAILBOX_USERNAME, IMAP_MAILBOX_PASSWORD);
+ $imap_stream = imap_open(IMAP_DEFAULT_MAILBOX, IMAP_MAILBOX_USERNAME, IMAP_MAILBOX_PASSWORD, flags: $flags);
if ($imap_stream === false) {
throw new Exception("Cannot connect to IMAP server " . IMAP_SERVER . ": " . imap_last_error());