imap: fix custom listing
No binary (build failed)
—
(log yok)
| @@ -1175,6 +1175,43 @@ static CURLcode imap_state_login_resp(struct Curl_easy *data, | |
| return result; | |
| } | |
| + | /* Detect IMAP listings vs. downloading a single email */ |
| + | static bool is_custom_fetch_listing_match(const char *params) |
| + | { |
| + | /* match " 1:* (FLAGS ..." or " 1,2,3 (FLAGS ..." */ |
| + | if(*params++ != ' ') |
| + | return FALSE; |
| + | |
| + | while(ISDIGIT(*params)) { |
| + | params++; |
| + | if(*params == 0) |
| + | return FALSE; |
| + | } |
| + | if(*params == ':') |
| + | return true; |
| + | if(*params == ',') |
| + | return true; |
| + | return FALSE; |
| + | } |
| + | |
| + | static bool is_custom_fetch_listing(struct IMAP *imap) |
| + | { |
| + | /* filter out "UID FETCH 1:* (FLAGS ..." queries to list emails */ |
| + | if(!imap->custom) |
| + | return FALSE; |
| + | else if(curl_strequal(imap->custom, "FETCH") && imap->custom_params) { |
| + | const char *p = imap->custom_params; |
| + | return is_custom_fetch_listing_match(p); |
| + | } |
| + | else if(curl_strequal(imap->custom, "UID") && imap->custom_params) { |
| + | if(curl_strnequal(imap->custom_params, " FETCH ", 7)) { |
| + | const char *p = imap->custom_params + 6; |
| + | return is_custom_fetch_listing_match(p); |
| + | } |
| + | } |
| + | return FALSE; |
| + | } |
| + | |
| /* For LIST and SEARCH responses */ | |
| static CURLcode imap_state_listsearch_resp(struct Curl_easy *data, | |
| struct imap_conn *imapc, | |
| @@ -1184,10 +1221,14 @@ static CURLcode imap_state_listsearch_resp(struct Curl_easy *data, | |
| CURLcode result = CURLE_OK; | |
| char *line = curlx_dyn_ptr(&imapc->pp.recvbuf); | |
| size_t len = imapc->pp.nfinal; | |
| + | struct IMAP *imap = Curl_meta_get(data, CURL_META_IMAP_EASY); |
| (void)instate; | |
| - | if(imapcode == '*') { |
| + | if(imapcode == '*' && is_custom_fetch_listing(imap)) { |
| + | /* custom FETCH or UID FETCH for listing is not handled here */ |
| + | } |
| + | else if(imapcode == '*') { |
| /* Check if this response contains a literal (e.g. FETCH responses with | |
| body data). Literal syntax is {size}\r\n */ | |
| const char *cr = memchr(line, '\r', len); | |
| @@ -231,7 +231,7 @@ test1680 test1681 test1682 test1683 \ | |
| test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 \ | |
| test1708 test1709 test1710 test1711 \ | |
| \ | |
| - | test1800 test1801 test1802 \ |
| + | test1800 test1801 test1802 test1847 test1848 \ |
| \ | |
| test1900 test1901 test1902 test1903 test1904 test1905 test1906 test1907 \ | |
| test1908 test1909 test1910 test1911 test1912 test1913 test1914 test1915 \ | |
| @@ -0,0 +1,58 @@ | |
| + | <?xml version="1.0" encoding="US-ASCII"?> |
| + | <testcase> |
| + | <info> |
| + | <keywords> |
| + | IMAP |
| + | Clear Text |
| + | FETCH |
| + | CUSTOMREQUEST |
| + | </keywords> |
| + | </info> |
| + | |
| + | # Server-side |
| + | <reply> |
| + | <data crlf="yes"> |
| + | From: me@somewhere |
| + | To: fake@nowhere |
| + | |
| + | body |
| + | |
| + | -- |
| + | yours sincerely |
| + | </data> |
| + | <datacheck crlf="yes"> |
| + | * FETCH FETCH (1 BODY[] {71} |
| + | From: me@somewhere |
| + | To: fake@nowhere |
| + | |
| + | body |
| + | |
| + | -- |
| + | yours sincerely |
| + | </datacheck> |
| + | </reply> |
| + | |
| + | # Client-side |
| + | <client> |
| + | <server> |
| + | imap |
| + | </server> |
| + | <name> |
| + | IMAP FETCH message with custom request |
| + | </name> |
| + | <command> |
| + | 'imap://%HOSTIP:%IMAPPORT/%TESTNUMBER' --request 'UID FETCH 1 BODY[]' -u '"user:sec"ret{' |
| + | </command> |
| + | </client> |
| + | |
| + | # Verify data after the test has been "shot" |
| + | <verify> |
| + | <protocol crlf="yes"> |
| + | A001 CAPABILITY |
| + | A002 LOGIN "\"user" "sec\"ret{" |
| + | A003 SELECT %TESTNUMBER |
| + | A004 UID FETCH 1 BODY[] |
| + | A005 LOGOUT |
| + | </protocol> |
| + | </verify> |
| + | </testcase> |
| @@ -0,0 +1,51 @@ | |
| + | <?xml version="1.0" encoding="US-ASCII"?> |
| + | <testcase> |
| + | <info> |
| + | <keywords> |
| + | IMAP |
| + | Clear Text |
| + | FETCH |
| + | CUSTOMREQUEST |
| + | </keywords> |
| + | </info> |
| + | |
| + | # Server-side |
| + | <reply> |
| + | <data crlf="yes"> |
| + | From: me@somewhere |
| + | To: fake@nowhere |
| + | |
| + | body |
| + | |
| + | -- |
| + | yours sincerely |
| + | </data> |
| + | # listing goes to debug output, so data output is empty |
| + | <datacheck crlf="yes"> |
| + | </datacheck> |
| + | </reply> |
| + | |
| + | # Client-side |
| + | <client> |
| + | <server> |
| + | imap |
| + | </server> |
| + | <name> |
| + | IMAP FETCH message with custom request to get list of email. |
| + | </name> |
| + | <command> |
| + | 'imap://%HOSTIP:%IMAPPORT/%TESTNUMBER' --request 'UID FETCH 1:* (FLAGS INTERNALDATE RFC822.SIZE BODY.PEEK[HEADER.FIELDS (Message-Id DATE FROM SUBJECT TO SENDER REPLY-TO CC BCC)])' -u '"user:sec"ret{' |
| + | </command> |
| + | </client> |
| + | |
| + | # Verify data after the test has been "shot" |
| + | <verify> |
| + | <protocol crlf="yes"> |
| + | A001 CAPABILITY |
| + | A002 LOGIN "\"user" "sec\"ret{" |
| + | A003 SELECT %TESTNUMBER |
| + | A004 UID FETCH 1:* (FLAGS INTERNALDATE RFC822.SIZE BODY.PEEK[HEADER.FIELDS (Message-Id DATE FROM SUBJECT TO SENDER REPLY-TO CC BCC)]) |
| + | A005 LOGOUT |
| + | </protocol> |
| + | </verify> |
| + | </testcase> |