Commit message: Fixed crash #274
CVE: CVE-2017-8825
CWE: CWE-476
Vulnerability description: A null dereference vulnerability has been found in the MIME handling component of LibEtPan before 1.8, as used in MailCore and MailCore 2. A crash can occur in low-level/imf/mailimf.c during a failed parse of a Cc header containing multiple e-mail addresses.

Project: libetpan
File: mailimf.c

static inline int is_ctext(char ch)
{
  unsigned char uch = (unsigned char) ch;

  if (is_no_ws_ctl(ch))
    return TRUE;

  if (uch < 33)
    return FALSE;

  if ((uch == 40) || (uch == 41))
    return FALSE;
  
  if (uch == 92)
    return FALSE;

  if (uch == 127)
    return FALSE;

  return TRUE;
}

Project: libetpan
File: mailimf.c

mailimf_from_parse(const char * message, size_t length,
		   size_t * indx, struct mailimf_from ** result)
{
  struct mailimf_mailbox_list * mb_list;
  struct mailimf_from * from;
  size_t cur_token;
  int r;
  int res;

  cur_token =  * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "From");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_mailbox_list_parse(message, length, &cur_token, &mb_list);

  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_mb_list;
  }

  from = mailimf_from_new(mb_list);
  if (from == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_mb_list;
  }

  * result = from;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_mb_list:
  mailimf_mailbox_list_free(mb_list);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_hour_parse(const char * message, size_t length,
			      size_t * indx, int * result)
{
  uint32_t hour;
  int r;

  r = mailimf_number_parse(message, length, indx, &hour);
  if (r != MAILIMF_NO_ERROR)
    return r;

  * result = hour;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_minute_parse(const char * message, size_t length,
				size_t * indx, int * result)
{
  uint32_t minute;
  int r;

  r = mailimf_number_parse(message, length, indx, &minute);
  if (r != MAILIMF_NO_ERROR)
    return r;

  * result = minute;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

int mailimf_quoted_string_parse(const char * message, size_t length,
				size_t * indx, char ** result)
{
  size_t cur_token;
  MMAPString * gstr;
  char ch;
  char * str;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_cfws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
    res = r;
    goto err;
  }

  r = mailimf_dquote_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  gstr = mmap_string_new("");
  if (gstr == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto err;
  }

#if 0
  if (mmap_string_append_c(gstr, '\"') == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_gstr;
  }
#endif

  while (1) {
    r = mailimf_fws_parse(message, length, &cur_token);
    if (r == MAILIMF_NO_ERROR) {
      if (mmap_string_append_c(gstr, ' ') == NULL) {
	res = MAILIMF_ERROR_MEMORY;
	goto free_gstr;
      }
    }
    else if (r != MAILIMF_ERROR_PARSE) {
      res = r;
      goto free_gstr;
    }

    r = mailimf_qcontent_parse(message, length, &cur_token, &ch);
    if (r == MAILIMF_NO_ERROR) {
      if (mmap_string_append_c(gstr, ch) == NULL) {
	res = MAILIMF_ERROR_MEMORY;
	goto free_gstr;
      }
    }
    else if (r == MAILIMF_ERROR_PARSE)
      break;
    else {
      res = r;
      goto free_gstr;
    }
  }

  r = mailimf_dquote_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_gstr;
  }

#if 0
  if (mmap_string_append_c(gstr, '\"') == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_gstr;
  }
#endif

  str = strdup(gstr->str);
  if (str == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_gstr;
  }
  mmap_string_free(gstr);

  * indx = cur_token;
  * result = str;

  return MAILIMF_NO_ERROR;

 free_gstr:
  mmap_string_free(gstr);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_sender_parse(const char * message, size_t length,
		     size_t * indx, struct mailimf_sender ** result)
{
  struct mailimf_mailbox * mb;
  struct mailimf_sender * sender;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Sender");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_mailbox_parse(message, length, &cur_token, &mb);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_mb;
  }

  sender = mailimf_sender_new(mb);
  if (sender == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_mb;
  }

  * result = sender;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_mb:
  mailimf_mailbox_free(mb);
 err:
  return res;
}