aboutsummaryrefslogtreecommitdiff
path: root/lib/imap.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/imap.c')
-rw-r--r--lib/imap.c99
1 files changed, 93 insertions, 6 deletions
diff --git a/lib/imap.c b/lib/imap.c
index 39230bbcd..3fb482862 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -1659,16 +1659,103 @@ static bool imap_is_bchar(char ch)
*/
static CURLcode imap_parse_url_path(struct connectdata *conn)
{
- /* The imap struct is already inited in imap_connect() */
+ /* The imap struct is already initialised in imap_connect() */
+ CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct IMAP *imap = data->state.proto.imap;
- const char *path = data->state.path;
+ const char *begin = data->state.path;
+ const char *ptr = begin;
+
+ /* See how much of the URL is a valid path and decode it */
+ while(imap_is_bchar(*ptr))
+ ptr++;
+
+ if(ptr != begin) {
+ /* Remove the trailing slash if present */
+ const char *end = ptr;
+ if(end > begin && end[-1] == '/')
+ end--;
+
+ result = Curl_urldecode(data, begin, end - begin, &imap->mailbox, NULL,
+ TRUE);
+ if(result)
+ return result;
+ }
+ else
+ imap->mailbox = NULL;
+
+ /* There can be any number of parameters in the form ";NAME=VALUE" */
+ while(*ptr == ';') {
+ char *name;
+ char *value;
+ size_t valuelen;
+
+ /* Decode the parameter name */
+ begin = ++ptr;
+ while(*ptr && *ptr != '=')
+ ptr++;
+
+ if(!*ptr)
+ return CURLE_URL_MALFORMAT;
+
+ /* Decode the parameter name */
+ result = Curl_urldecode(data, begin, ptr - begin, &name, NULL, TRUE);
+ if(result)
+ return result;
+
+ begin = ++ptr;
+ while(imap_is_bchar(*ptr))
+ ptr++;
+
+ /* Decode the parameter value */
+ result = Curl_urldecode(data, begin, ptr - begin, &value, &valuelen, TRUE);
+ if(result) {
+ Curl_safefree(name);
+ return result;
+ }
+
+ DEBUGF(infof(conn->data, "IMAP URL parameter '%s' = '%s'\n", name, value));
+
+ /* Process known parameters (UIDVALIDITY, UID and SECTION) and create
+ a virtual URL level as they should be followed by a slash, which needs
+ to be stripped. Note: Unknown parameters trigger URL_MALFORMAT error */
+ if(Curl_raw_equal(name, "UIDVALIDITY") && !imap->uidvalidity) {
+ if(valuelen > 0 && value[valuelen - 1] == '/')
+ value[valuelen - 1] = '\0';
+
+ imap->uidvalidity = value;
+ value = NULL;
+ }
+ else if(Curl_raw_equal(name, "UID") && !imap->uid) {
+ if(valuelen > 0 && value[valuelen - 1] == '/')
+ value[valuelen - 1] = '\0';
- if(!*path)
- path = "INBOX";
+ imap->uid = value;
+ value = NULL;
+ }
+ else if(Curl_raw_equal(name, "SECTION") && !imap->section) {
+ if(valuelen > 0 && value[valuelen - 1] == '/')
+ value[valuelen - 1] = '\0';
- /* URL decode the path and use this mailbox */
- return Curl_urldecode(data, path, 0, &imap->mailbox, NULL, TRUE);
+ imap->section = value;
+ value = NULL;
+ }
+ else {
+ Curl_safefree(name);
+ Curl_safefree(value);
+
+ return CURLE_URL_MALFORMAT;
+ }
+
+ Curl_safefree(name);
+ Curl_safefree(value);
+ }
+
+ /* Any extra stuff at the end of the URL is an error */
+ if(*ptr)
+ return CURLE_URL_MALFORMAT;
+
+ return CURLE_OK;
}
/* Call this when the DO phase has completed */