コード例 #1
0
ファイル: mailmime.c プロジェクト: WARA45542/libetpan
static int
mailmime_composite_type_parse(const char * message, size_t length,
			      size_t * indx,
			      struct mailmime_composite_type ** result)
{
  char * extension_token;
  int type;
  struct mailmime_composite_type * ct;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  extension_token = NULL;

  type = MAILMIME_COMPOSITE_TYPE_ERROR; /* XXX - removes a gcc warning */

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "message");
  if (r == MAILIMF_NO_ERROR)
    type = MAILMIME_COMPOSITE_TYPE_MESSAGE;

  if (r == MAILIMF_ERROR_PARSE) {
    r = mailimf_token_case_insensitive_parse(message, length,
					     &cur_token, "multipart");
    if (r == MAILIMF_NO_ERROR)
      type = MAILMIME_COMPOSITE_TYPE_MULTIPART;
  }

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

  ct = mailmime_composite_type_new(type, extension_token);
  if (ct == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_extension;
  }

  * result = ct;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_extension:
  if (extension_token != NULL)
    mailmime_extension_token_free(extension_token);
 err:
  return res;
}
コード例 #2
0
static int
mailmime_size_parm_parse(const char * message, size_t length,
                         size_t * indx, size_t * result)
{
    uint32_t value;
    size_t cur_token;
    int r;

    cur_token = * indx;

    r = mailimf_token_case_insensitive_parse(message, length,
            &cur_token, "size");
    if (r != MAILIMF_NO_ERROR)
        return r;

    r = mailimf_unstrict_char_parse(message, length, &cur_token, '=');
    if (r != MAILIMF_NO_ERROR)
        return r;

    r = mailimf_cfws_parse(message, length, &cur_token);
    if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
        return r;

    r = mailimf_number_parse(message, length, &cur_token, &value);
    if (r != MAILIMF_NO_ERROR)
        return r;

    * indx = cur_token;
    * result = value;

    return MAILIMF_NO_ERROR;
}
コード例 #3
0
static int
mailmime_modification_date_parm_parse(const char * message, size_t length,
                                      size_t * indx, char ** result)
{
    char * value;
    size_t cur_token;
    int r;

    cur_token = * indx;

    r = mailimf_token_case_insensitive_parse(message, length,
            &cur_token, "modification-date");
    if (r != MAILIMF_NO_ERROR)
        return r;

    r = mailimf_unstrict_char_parse(message, length, &cur_token, '=');
    if (r != MAILIMF_NO_ERROR)
        return r;

    r = mailimf_cfws_parse(message, length, &cur_token);
    if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
        return r;

    r = mailmime_quoted_date_time_parse(message, length, &cur_token, &value);
    if (r != MAILIMF_NO_ERROR)
        return r;

    * indx = cur_token;
    * result = value;

    return MAILIMF_NO_ERROR;
}
コード例 #4
0
ファイル: mailmime.c プロジェクト: WARA45542/libetpan
static int mailmime_mechanism_parse(const char * message, size_t length,
				    size_t * indx,
				    struct mailmime_mechanism ** result)
{
  char * token;
  int type;
  struct mailmime_mechanism * mechanism;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;
  
  type = MAILMIME_MECHANISM_ERROR; /* XXX - removes a gcc warning */

  token = NULL;
  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "7bit");
  if (r == MAILIMF_NO_ERROR)
    type = MAILMIME_MECHANISM_7BIT;

  if (r == MAILIMF_ERROR_PARSE) {
    r = mailimf_token_case_insensitive_parse(message, length,
					     &cur_token, "8bit");
    if (r == MAILIMF_NO_ERROR)
      type = MAILMIME_MECHANISM_8BIT;
  }

  if (r == MAILIMF_ERROR_PARSE) {
    r = mailimf_token_case_insensitive_parse(message, length,
					     &cur_token, "binary");
    if (r == MAILIMF_NO_ERROR)
      type = MAILMIME_MECHANISM_BINARY;
  }

  if (r == MAILIMF_ERROR_PARSE) {
    r = mailimf_token_case_insensitive_parse(message, length,
					     &cur_token, "quoted-printable");
    if (r == MAILIMF_NO_ERROR)
      type = MAILMIME_MECHANISM_QUOTED_PRINTABLE;
  }

  if (r == MAILIMF_ERROR_PARSE) {
    r = mailimf_token_case_insensitive_parse(message, length,
					     &cur_token, "base64");
    if (r == MAILIMF_NO_ERROR)
      type = MAILMIME_MECHANISM_BASE64;
  }

  if (r == MAILIMF_ERROR_PARSE) {
    r = mailmime_token_parse(message, length, &cur_token, &token);
    if (r == MAILIMF_NO_ERROR)
      type = MAILMIME_MECHANISM_TOKEN;
  }

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

  mechanism = mailmime_mechanism_new(type, token);
  if (mechanism == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free;
  }

  * result = mechanism;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free:
  if (token != NULL)
    mailmime_token_free(token);
 err:
  return res;
}
コード例 #5
0
ファイル: mailmime.c プロジェクト: WARA45542/libetpan
static int
mailmime_discrete_type_parse(const char * message, size_t length,
			     size_t * indx,
			     struct mailmime_discrete_type ** result)
{
  char * extension;
  int type;
  struct mailmime_discrete_type * discrete_type;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  extension = NULL;

  type = MAILMIME_DISCRETE_TYPE_ERROR; /* XXX - removes a gcc warning */

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "text");
  if (r == MAILIMF_NO_ERROR)
    type = MAILMIME_DISCRETE_TYPE_TEXT;

  if (r == MAILIMF_ERROR_PARSE) {
    r = mailimf_token_case_insensitive_parse(message, length,
					     &cur_token, "image");
    if (r == MAILIMF_NO_ERROR)
      type = MAILMIME_DISCRETE_TYPE_IMAGE;
  }

  if (r == MAILIMF_ERROR_PARSE) {
    r = mailimf_token_case_insensitive_parse(message, length,
					     &cur_token, "audio");
    if (r == MAILIMF_NO_ERROR)
      type = MAILMIME_DISCRETE_TYPE_AUDIO;
  }
  
  if (r == MAILIMF_ERROR_PARSE) {
    r = mailimf_token_case_insensitive_parse(message, length,
					     &cur_token, "video");
    if (r == MAILIMF_NO_ERROR)
      type = MAILMIME_DISCRETE_TYPE_VIDEO;
  }

  if (r == MAILIMF_ERROR_PARSE) {
    r = mailimf_token_case_insensitive_parse(message, length,
					     &cur_token, "application");
    if (r == MAILIMF_NO_ERROR)
      type = MAILMIME_DISCRETE_TYPE_APPLICATION;
  }

  if (r == MAILIMF_ERROR_PARSE) {
    r = mailmime_extension_token_parse(message, length,
				       &cur_token, &extension);
    if (r == MAILIMF_NO_ERROR)
      type = MAILMIME_DISCRETE_TYPE_EXTENSION;
  }

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

  discrete_type = mailmime_discrete_type_new(type, extension);
  if (discrete_type == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free;
  }

  * result = discrete_type;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free:
  mailmime_extension_token_free(extension);
 err:
  return res;
}
コード例 #6
0
static int mailmime_encoded_word_parse(const char * message, size_t length,
                                       size_t * indx,
                                       struct mailmime_encoded_word ** result,
                                       int * p_has_fwd)
{
  size_t cur_token;
  char * charset;
  int encoding;
  char * text;
  size_t end_encoding;
  char * decoded;
  size_t decoded_len;
  struct mailmime_encoded_word * ew;
  int r;
  int res;
  int opening_quote;
  int end;
  int has_fwd;

  cur_token = * indx;

  has_fwd = 0;
  r = mailimf_fws_parse(message, length, &cur_token);
  if (r == MAILIMF_NO_ERROR) {
    has_fwd = 1;
  }
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
    res = r;
    goto err;
  }

  opening_quote = FALSE;
  r = mailimf_char_parse(message, length, &cur_token, '\"');
  if (r == MAILIMF_NO_ERROR) {
    opening_quote = TRUE;
  }
  else if (r == MAILIMF_ERROR_PARSE) {
    /* do nothing */
  }
  else {
    res = r;
    goto err;
  }

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

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

  r = mailimf_char_parse(message, length, &cur_token, '?');
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_charset;
  }

  r = mailmime_encoding_parse(message, length, &cur_token, &encoding);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_charset;
  }

  r = mailimf_char_parse(message, length, &cur_token, '?');
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_charset;
  }

  end = FALSE;
  end_encoding = cur_token;
  while (1) {
    if (end_encoding >= length)
      break;

    if (end_encoding + 1 < length) {
      if ((message[end_encoding] == '?') && (message[end_encoding + 1] == '=')) {
        end = TRUE;
      }
    }

    if (end)
      break;

    end_encoding ++;
  }

  decoded_len = 0;
  decoded = NULL;
  switch (encoding) {
  case MAILMIME_ENCODING_B:
    r = mailmime_base64_body_parse(message, end_encoding,
				   &cur_token, &decoded,
				   &decoded_len);

    if (r != MAILIMF_NO_ERROR) {
      res = r;
      goto free_charset;
    }
    break;
  case MAILMIME_ENCODING_Q:
    r = mailmime_quoted_printable_body_parse(message, end_encoding,
					     &cur_token, &decoded,
					     &decoded_len, TRUE);

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

    break;
  }

  text = malloc(decoded_len + 1);
  if (text == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_charset;
  }

  if (decoded_len > 0)
    memcpy(text, decoded, decoded_len);
  text[decoded_len] = '\0';

  mailmime_decoded_part_free(decoded);

  r = mailimf_token_case_insensitive_parse(message, length, &cur_token, "?=");
#if 0
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_encoded_text;
  }
#endif

  if (opening_quote) {
    r = mailimf_char_parse(message, length, &cur_token, '\"');
#if 0
    if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
      res = r;
      goto free_encoded_text;
    }
#endif
  }

  /* fix charset */
  if (strcasecmp(charset, "utf8") == 0) {
    free(charset);
    charset = strdup("utf-8");
  }
  ew = mailmime_encoded_word_new(charset, text);
  if (ew == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_encoded_text;
  }

  * result = ew;
  * indx = cur_token;
  * p_has_fwd = has_fwd;

  return MAILIMF_NO_ERROR;

 free_encoded_text:
  mailmime_encoded_text_free(text);
 free_charset:
  mailmime_charset_free(charset);
 err:
  return res;
}
コード例 #7
0
int
mailmime_disposition_type_parse(const char * message, size_t length,
                                size_t * indx,
                                struct mailmime_disposition_type ** result)
{
    size_t cur_token;
    int type;
    char * extension;
    struct mailmime_disposition_type * dsp_type;
    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;
    }

    type = MAILMIME_DISPOSITION_TYPE_ERROR; /* XXX - removes a gcc warning */

    extension = NULL;
    r = mailimf_token_case_insensitive_parse(message, length,
            &cur_token, "inline");
    if (r == MAILIMF_NO_ERROR)
        type = MAILMIME_DISPOSITION_TYPE_INLINE;

    if (r == MAILIMF_ERROR_PARSE) {
        r = mailimf_token_case_insensitive_parse(message, length,
                &cur_token, "attachment");
        if (r == MAILIMF_NO_ERROR)
            type = MAILMIME_DISPOSITION_TYPE_ATTACHMENT;
    }

    if (r == MAILIMF_ERROR_PARSE) {
        r = mailmime_extension_token_parse(message, length, &cur_token,
                                           &extension);
        if (r == MAILIMF_NO_ERROR)
            type = MAILMIME_DISPOSITION_TYPE_EXTENSION;
    }

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

    dsp_type = mailmime_disposition_type_new(type, extension);
    if (dsp_type == NULL) {
        res = MAILIMF_ERROR_MEMORY;
        goto free;
    }

    * result = dsp_type;
    * indx = cur_token;

    return MAILIMF_NO_ERROR;

free:
    if (extension != NULL)
        free(extension);
err:
    return res;
}
コード例 #8
0
int mailmime_encoded_word_parse(const char * message, size_t length,
                                size_t * indx,
                                struct mailmime_encoded_word ** result,
                                int * p_has_fwd, int * p_missing_closing_quote)
{
  /*
  Parse the following, when a unicode character encoding is split.
  =?UTF-8?B?4Lij4Liw4LmA4Lia4Li04LiU4LiE4Lin4Liy4Lih4Lih4Lix4LiZ4Liq4LmM?=
  =?UTF-8?B?4LmA4LiV4LmH4Lih4Lie4Li04LiB4Lix4LiUIFRSQU5TRk9STUVSUyA0IOC4?=
  =?UTF-8?B?oeC4seC4meC4quC5jOC4hOC4o+C4muC4l+C4uOC4geC4o+C4sOC4muC4miDg?=
  =?UTF-8?B?uJfguLXguYjguYDguJTguLXguKLguKfguYPguJnguYDguKHguLfguK3guIfg?=
  =?UTF-8?B?uYTguJfguKI=?=
  Expected result:
  ระเบิดความมันส์เต็มพิกัด TRANSFORMERS 4 มันส์ครบทุกระบบ ที่เดียวในเมืองไทย
  libetpan result:
  ระเบิดความมันส์เต็มพิกัด TRANSFORMERS 4 ?ันส์ครบทุกระบบ ??ี่เดียวในเมือง??ทย
   
  See https://github.com/dinhviethoa/libetpan/pull/211
  */
  size_t cur_token;
  char * charset;
  int encoding;
  char * body;
  size_t old_body_len;
  char * text;
  size_t end_encoding;
  size_t lookfwd_cur_token;
  char * lookfwd_charset;
  int lookfwd_encoding;
  size_t copy_len;
  size_t decoded_token;
  char * decoded;
  size_t decoded_len;
  struct mailmime_encoded_word * ew;
  int r;
  int res;
  int opening_quote;
  int end;
  int has_fwd;
  int missing_closing_quote;

  cur_token = * indx;

  text = NULL;
  lookfwd_charset = NULL;
  missing_closing_quote = 0;
  has_fwd = 0;
  r = mailimf_fws_parse(message, length, &cur_token);
  if (r == MAILIMF_NO_ERROR) {
    has_fwd = 1;
  }
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
    res = r;
    goto err;
  }

  opening_quote = FALSE;
  r = mailimf_char_parse(message, length, &cur_token, '\"');
  if (r == MAILIMF_NO_ERROR) {
    opening_quote = TRUE;
  }
  else if (r == MAILIMF_ERROR_PARSE) {
    /* do nothing */
  }
  else {
    res = r;
    goto err;
  }

  /* Parse first charset and encoding. */
  r = mailimf_token_case_insensitive_parse(message, length, &cur_token, "=?");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

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

  r = mailimf_char_parse(message, length, &cur_token, '?');
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_charset;
  }

  r = mailmime_encoding_parse(message, length, &cur_token, &encoding);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_charset;
  }

  r = mailimf_char_parse(message, length, &cur_token, '?');
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_charset;
  }

  lookfwd_cur_token = cur_token;
  body = NULL;
  old_body_len = 0;
  while (1) {
    int has_base64_padding;

    end = FALSE;
    has_base64_padding = FALSE;
    end_encoding = cur_token;
    while (1) {
      if (end_encoding >= length)
        break;

      if (end_encoding + 1 < length) {
        if ((message[end_encoding] == '?') && (message[end_encoding + 1] == '=')) {
          end = TRUE;
        }
      }

      if (end)
        break;

      end_encoding ++;
    }

    copy_len = end_encoding - lookfwd_cur_token;
    if (copy_len > 0) {
      if (encoding == MAILMIME_ENCODING_B) {
        if (end_encoding >= 1) {
          if (message[end_encoding - 1] == '=') {
            has_base64_padding = TRUE;
          }
        }
      }

      body = realloc(body, old_body_len + copy_len + 1);
      if (body == NULL) {
        res = MAILIMF_ERROR_MEMORY;
        goto free_body;
      }

      memcpy(body + old_body_len, &message[cur_token], copy_len);
      body[old_body_len + copy_len] = '\0';

      old_body_len += copy_len;
    }
    cur_token = end_encoding;

    r = mailimf_token_case_insensitive_parse(message, length, &cur_token, "?=");
    if (r != MAILIMF_NO_ERROR) {
      break;
    }

    if (has_base64_padding) {
      break;
    }

    lookfwd_cur_token = cur_token;

    r = mailimf_fws_parse(message, length, &lookfwd_cur_token);
    if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
      break;
    }

    /* Parse following charset and encoding to check if they're matching. */
    r = mailimf_token_case_insensitive_parse(message, length, &lookfwd_cur_token, "=?");
    if (r != MAILIMF_NO_ERROR) {
      break;
    }

    r = mailmime_charset_parse(message, length, &lookfwd_cur_token, &lookfwd_charset);
    if (r != MAILIMF_NO_ERROR) {
      break;
    }

    r = mailimf_char_parse(message, length, &lookfwd_cur_token, '?');
    if (r != MAILIMF_NO_ERROR) {
      break;
    }

    r = mailmime_encoding_parse(message, length, &lookfwd_cur_token, &lookfwd_encoding);
    if (r != MAILIMF_NO_ERROR) {
      break;
    }

    r = mailimf_char_parse(message, length, &lookfwd_cur_token, '?');
    if (r != MAILIMF_NO_ERROR) {
      break;
    }

    if ((strcasecmp(charset, lookfwd_charset) == 0) && (encoding == lookfwd_encoding)) {
      cur_token = lookfwd_cur_token;
    } else {
      /* the next charset is not matched with the current one,
        therefore exit the loop to decode the body appended so far */
      break;
    }

    mailmime_charset_free(lookfwd_charset);
    lookfwd_charset = NULL;
  }

  if (lookfwd_charset != NULL) {
    mailmime_charset_free(lookfwd_charset);
    lookfwd_charset = NULL;
  }

  if (body == NULL) {
    body = strdup("");
    if (body == NULL) {
      res = MAILIMF_ERROR_MEMORY;
      goto free_body;
    }
  }

  decoded_token = 0;
  decoded_len = 0;
  decoded = NULL;
  switch (encoding) {
    case MAILMIME_ENCODING_B:
      r = mailmime_base64_body_parse(body, strlen(body),
                                     &decoded_token, &decoded,
                                     &decoded_len);

      if (r != MAILIMF_NO_ERROR) {
        res = r;
        goto free_body;
      }
      break;
    case MAILMIME_ENCODING_Q:
      r = mailmime_quoted_printable_body_parse(body, strlen(body),
                                               &decoded_token, &decoded,
                                               &decoded_len, TRUE);

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

      break;
  }

  text = malloc(decoded_len + 1);
  if (text == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_decoded;
  }

  if (decoded_len > 0)
    memcpy(text, decoded, decoded_len);
  text[decoded_len] = '\0';

  if (opening_quote) {
    r = mailimf_char_parse(message, length, &cur_token, '\"');
    if (r == MAILIMF_ERROR_PARSE) {
      missing_closing_quote = 1;
    }
  }

  /* fix charset */
  if (strcasecmp(charset, "utf8") == 0) {
    free(charset);
    charset = strdup("utf-8");
  }
  ew = mailmime_encoded_word_new(charset, text);
  if (ew == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_decoded;
  }

  * result = ew;
  * indx = cur_token;
  * p_has_fwd = has_fwd;
  * p_missing_closing_quote = missing_closing_quote;

  mailmime_decoded_part_free(decoded);
  free(body);

  return MAILIMF_NO_ERROR;

free_decoded:
  mailmime_decoded_part_free(decoded);
free_body:
  free(body);
  mailmime_encoded_text_free(text);
free_charset:
  mailmime_charset_free(charset);
err:
  return res;
}