php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #71228 imap_search auto-corrects Date string in criteria using undocumented algorithm
Submitted: 2015-12-28 04:30 UTC Modified: 2020-10-14 14:16 UTC
Votes:4
Avg. Score:3.5 ± 0.9
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: crazytonyi at gmail dot com Assigned:
Status: Verified Package: IMAP related
PHP Version: 5.5.30 OS:
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2015-12-28 04:30 UTC] crazytonyi at gmail dot com
Description:
------------
---
From manual page: http://www.php.net/function.imap-search
---

If you set $criteria argument for imap_search function using string such as:

'SINCE "Mon, 28 Dec 2015 02:55:04 +0000" UNDELETED'

it will reformat the string to something like:

'UNDELETED SINCE 28-Dec-2015'

This is mostly a good thing, except:

1. Nowhere in imap_search documentation does it reflect this auto-correction behavior,

2. Nowhere in imap_search documentation does it indicate the algorithm or mechanism that is applied to the datetime sub-string to derive a "pure datetime" value for correct formatting,

3. Throughout the documentation User Notes thread, there are several references to confusion regarding the "correct date formatting", including those that encourage the formatting used in the documentation examples ( such as "8 August 2008" ) versus those that encourage following the RFC-3501 spec ( which would be "08-Aug-2008" for that same example). So the fact that PHP is automatically handling date strings to format to RFC-3501 formatting is not well-known or being leveraged in a reliable, intentional manner.

4. Since there is no indication of what algorithm is used for parsing input date strings, it is not clear whether the following:

'SINCE "12-01-2015" UNDELETED'

would be handled as:

a. Invalid (un-parseable) date string
b. 12-Jan-2015
c. 01-Dec-2015

5. Also, PHP uses current timezone set (either via INI directive or date_default_timezone_set, etc) for formatting to RTC-3501, so that change to local system timezone means different resulting IMAP search criteria.

Test script:
---------------
date_default_timezone_set('UTC');

$conn   = imap_open('{localhost:143}INBOX', 'user@example.org', 'password', OP_READONLY);

$since = date('r');

$criteria = "SINCE \"{$since}\" UNDELETED";

echo $criteria . PHP_EOL;

$search   = imap_search($conn, $criteria, SE_UID);

print_r($search);

Expected result:
----------------
1. IMAP search criteria are sent with actual value of $criteria argument, like:

    UID SEARCH SINCE "Mon, 28 Dec 2015 02:55:04 +0000" UNDELETED

OR

2. IMAP search criteria gets reformatted as it does currently, but with consistent results (independent of timezone) so that:

date_default_timezone_set('UTC');

$since = date('r');

$criteria = "SINCE \"{$since}\" UNDELETED";

VS

date_default_timezone_set('America/Los Angeles');

$since = date('r');

$criteria = "SINCE \"{$since}\" UNDELETED";

both result in same search criteria sent to IMAP server, like:

'UNDELETED SINCE 28-Dec-2015'

instead of the criteria, when timezone is set to UTC, being:

'UNDELETED SINCE 28-Dec-2015'

versus when timezone is set to "America/Los Angeles", with result being:

'UNDELETED SINCE 27-Dec-2015'

-----

Note that some of this is actually more of a weakness of the IMAP specification (which indicates that SINCE should not include time or timezone but doesn't indicate what pure date should be relative to), as well as a probable issue with IMAP server misbehaving and using its own local timezone when it shouldn't be. However, the fact that PHP does this auto-correction AND the fact that there is potential for problems due to date-related searches, it should be more clear in PHP documentation what to expect based on value passed in to imap_search function compared to SEARCH command that is actually sent to PHP server.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-10-14 14:16 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2020-10-14 14:16 UTC] cmb@php.net
Firstly, the IMAP extension does not reformat the date, but rather
the underlying libc-client does this.  Also, this library does not
accept IMAP4 search criteria (specified by RFC 3501), but rather
IMAP2 search criteria (specified by RFC 1176).  The latter RFC
does not even mention any details regarding the dates accepted for
BEFORE, ON and SINCE.  Furthermore, the libc-client documentation
doesn't mention any details, so the best docs are likely from the
doc comment of mail_parse_date() (libc-client 2000f):

/* Mail parse date into elt fields
 * Accepts: elt to write into
 *	    date string to parse
 * Returns: T if parse successful, else NIL 
 * This routine parses dates as follows:
 * . leading three alphas followed by comma and space are ignored
 * . date accepted in format: mm/dd/yy, mm/dd/yyyy, dd-mmm-yy, dd-mmm-yyyy,
 *    dd mmm yy, dd mmm yyyy, yyyy-mm-dd, yyyymmdd
 * . two and three digit years interpreted according to RFC 2822 rules
 * . mandatory end of string if yyyy-mm-dd or yyyymmdd; otherwise optional
 *    space followed by time:
 * . time accepted in format hh:mm:ss or hh:mm
 * . end of string accepted
 * . timezone accepted: hyphen followed by symbolic timezone, or space
 *    followed by signed numeric timezone or symbolic timezone
 * Examples of normal input:
 * . IMAP date-only (SEARCH):
 *    dd-mmm-yyyy
 * . IMAP date-time (INTERNALDATE):
 *    dd-mmm-yyyy hh:mm:ss +zzzz
 * . RFC-822:
 *    www, dd mmm yy hh:mm:ss zzz
 * . RFC-2822:
 *    www, dd mmm yyyy hh:mm:ss +zzzz
 */

Note that for search criteria, the time is ignored.

> PHP uses current timezone set […] for formatting to RTC-3501,
> […]

No.  It's rather that the result of date('r') depends on the
default timezone.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Thu Oct 29 00:01:23 2020 UTC