]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
imap: Added URL parsing of new variables
authorJiri Hruska <jirka@fud.cz>
Sat, 23 Feb 2013 18:35:48 +0000 (19:35 +0100)
committerSteve Holme <steve_holme@hotmail.com>
Sat, 23 Feb 2013 18:40:47 +0000 (18:40 +0000)
Updated the imap_parse_url_path() function to parse uidvalidity, uid and
section parameters based on RFC-5092.

lib/imap.c

index 39230bbcd3b478399cee1f67a058f09c643533a6..3fb4828629a4d9e5eb1f9890f5c0fd107fbb7678 100644 (file)
@@ -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 */