Commit e7566410 authored by Jiri Hruska's avatar Jiri Hruska Committed by Steve Holme
Browse files

imap: Added URL parsing of new variables

Updated the imap_parse_url_path() function to parse uidvalidity, uid and
section parameters based on RFC-5092.
parent 2f638a8f
Loading
Loading
Loading
Loading
+93 −6
Original line number Diff line number Diff line
@@ -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;

  if(!*path)
    path = "INBOX";
  /* There can be any number of parameters in the form ";NAME=VALUE" */
  while(*ptr == ';') {
    char *name;
    char *value;
    size_t valuelen;

  /* URL decode the path and use this mailbox */
  return Curl_urldecode(data, path, 0, &imap->mailbox, NULL, TRUE);
    /* 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';

      imap->uid = value;
      value = NULL;
    }
    else if(Curl_raw_equal(name, "SECTION") && !imap->section) {
      if(valuelen > 0 && value[valuelen - 1] == '/')
        value[valuelen - 1] = '\0';

      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 */