imap: fix custom listing

Add test 1847 and 1848.

Fixes #20356
Closes #20360
This commit is contained in:
Christian Schmitz 2026-01-19 17:01:16 +01:00 committed by Daniel Stenberg
parent cf4164fa8d
commit e788d9d2c7
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
4 changed files with 152 additions and 2 deletions

View file

@ -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);