Exemple #1
0
enum message_cte message_decoder_parse_cte(struct message_header_line *hdr)
{
	struct rfc822_parser_context parser;
	enum message_cte message_cte;
	string_t *value;

	value = t_str_new(64);
	rfc822_parser_init(&parser, hdr->full_value, hdr->full_value_len, NULL);

	rfc822_skip_lwsp(&parser);
	(void)rfc822_parse_mime_token(&parser, value);

	message_cte = MESSAGE_CTE_UNKNOWN;
	switch (str_len(value)) {
	case 4:
		if (i_memcasecmp(str_data(value), "7bit", 4) == 0 ||
		    i_memcasecmp(str_data(value), "8bit", 4) == 0)
			message_cte = MESSAGE_CTE_78BIT;
		break;
	case 6:
		if (i_memcasecmp(str_data(value), "base64", 6) == 0)
			message_cte = MESSAGE_CTE_BASE64;
		else if (i_memcasecmp(str_data(value), "binary", 6) == 0)
			message_cte = MESSAGE_CTE_BINARY;
		break;
	case 16:
		if (i_memcasecmp(str_data(value), "quoted-printable", 16) == 0)
			message_cte = MESSAGE_CTE_QP;
		break;
	}
	return message_cte;
}
Exemple #2
0
void http_client_request_remove_header(struct http_client_request *req,
				       const char *key)
{
	const unsigned char *data, *p;
	size_t size, line_len, line_start_pos;
	unsigned int key_len = strlen(key);

	i_assert(req->state == HTTP_REQUEST_STATE_NEW ||
		 /* allow calling for retries */
		 req->state == HTTP_REQUEST_STATE_GOT_RESPONSE ||
		 req->state == HTTP_REQUEST_STATE_ABORTED);

	data = str_data(req->headers);
	size = str_len(req->headers);
	while ((p = memchr(data, '\n', size)) != NULL) {
		line_len = (p+1) - data;
		if (size > key_len && i_memcasecmp(data, key, key_len) == 0 &&
		    data[key_len] == ':' && data[key_len+1] == ' ') {
			/* key was found from header, replace its value */
			line_start_pos = str_len(req->headers) - size;
			str_delete(req->headers, line_start_pos, line_len);
			break;
		}
		size -= line_len;
		data += line_len;
	}
}
Exemple #3
0
static int mbox_parse_month(const unsigned char *msg, struct tm *tm)
{
	int i;

	for (i = 0; i < 12; i++) {
		if (i_memcasecmp(months[i], msg, 3) == 0) {
			tm->tm_mon = i;
			break;
		}
	}

	if (i == 12 && memcmp(msg, "???", 3) == 0) {
		/* just a hack to parse one special mbox I have :) */
		i = 0;
	}

	if (i == 12 || msg[3] != ' ')
		return -1;
	return 0;
}
Exemple #4
0
static bool
message_date_parser_tokens(struct message_date_parser_context *ctx,
			   time_t *timestamp_r, int *timezone_offset_r)
{
	struct tm tm;
	const unsigned char *value;
	size_t i, len;
	int ret;

	/* [weekday_name "," ] dd month_name [yy]yy hh:mi[:ss] timezone */
	memset(&tm, 0, sizeof(tm));

        rfc822_skip_lwsp(&ctx->parser);

	/* skip the optional weekday */
	if (next_token(ctx, &value, &len) <= 0)
		return FALSE;
	if (len == 3) {
		if (*ctx->parser.data != ',')
			return FALSE;
		ctx->parser.data++;
		rfc822_skip_lwsp(&ctx->parser);

		if (next_token(ctx, &value, &len) <= 0)
			return FALSE;
	}

	/* dd */
	if (len < 1 || len > 2 || !i_isdigit(value[0]))
		return FALSE;

	tm.tm_mday = value[0]-'0';
	if (len == 2) {
		if (!i_isdigit(value[1]))
			return FALSE;
		tm.tm_mday = (tm.tm_mday * 10) + (value[1]-'0');
	}

	/* month name */
	if (next_token(ctx, &value, &len) <= 0 || len < 3)
		return FALSE;

	for (i = 0; i < 12; i++) {
		if (i_memcasecmp(month_names[i], value, 3) == 0) {
			tm.tm_mon = i;
			break;
		}
	}
	if (i == 12)
		return FALSE;

	/* [yy]yy */
	if (next_token(ctx, &value, &len) <= 0 || (len != 2 && len != 4))
		return FALSE;

	for (i = 0; i < len; i++) {
		if (!i_isdigit(value[i]))
			return FALSE;
		tm.tm_year = tm.tm_year * 10 + (value[i]-'0');
	}

	if (len == 2) {
		/* two digit year, assume 1970+ */
		if (tm.tm_year < 70)
			tm.tm_year += 100;
	} else {
		if (tm.tm_year < 1900)
			return FALSE;
		tm.tm_year -= 1900;
	}

	/* hh, allow also single digit */
	if (next_token(ctx, &value, &len) <= 0 ||
	    len < 1 || len > 2 || !i_isdigit(value[0]))
		return FALSE;
	tm.tm_hour = value[0]-'0';
	if (len == 2) {
		if (!i_isdigit(value[1]))
			return FALSE;
		tm.tm_hour = tm.tm_hour * 10 + (value[1]-'0');
	}

	/* :mm (may be the last token) */
	if (!IS_TIME_SEP(*ctx->parser.data))
		return FALSE;
	ctx->parser.data++;
	rfc822_skip_lwsp(&ctx->parser);

	if (next_token(ctx, &value, &len) < 0 || len != 2 ||
	    !i_isdigit(value[0]) || !i_isdigit(value[1]))
		return FALSE;
	tm.tm_min = (value[0]-'0') * 10 + (value[1]-'0');

	/* [:ss] */
	if (ctx->parser.data != ctx->parser.end &&
	    IS_TIME_SEP(*ctx->parser.data)) {
		ctx->parser.data++;
		rfc822_skip_lwsp(&ctx->parser);

		if (next_token(ctx, &value, &len) <= 0 || len != 2 ||
		    !i_isdigit(value[0]) || !i_isdigit(value[1]))
			return FALSE;
		tm.tm_sec = (value[0]-'0') * 10 + (value[1]-'0');
	}

	if ((ret = next_token(ctx, &value, &len)) < 0)
		return FALSE;
	if (ret == 0) {
		/* missing timezone */
		*timezone_offset_r = 0;
	} else {
		/* timezone */
		*timezone_offset_r = parse_timezone(value, len);
	}

	tm.tm_isdst = -1;
	*timestamp_r = utc_mktime(&tm);
	if (*timestamp_r == (time_t)-1)
		return FALSE;

	*timestamp_r -= *timezone_offset_r * 60;

	return TRUE;
}
Exemple #5
0
static void imap_parser_save_arg(struct imap_parser *parser,
				 const unsigned char *data, size_t size)
{
	struct imap_arg *arg;
	char *str;

	arg = imap_arg_create(parser);

	switch (parser->cur_type) {
	case ARG_PARSE_ATOM:
	case ARG_PARSE_TEXT:
		if (size == 3 && i_memcasecmp(data, "NIL", 3) == 0) {
			/* NIL argument. it might be an actual NIL, but if
			   we're reading astring, it's an atom and we can't
			   lose its case. */
			arg->type = IMAP_ARG_NIL;
		} else {
			/* simply save the string */
			arg->type = IMAP_ARG_ATOM;
		}
		arg->_data.str = imap_parser_strdup(parser, data, size);
		arg->str_len = size;
		break;
	case ARG_PARSE_STRING:
		/* data is quoted and may contain escapes. */
		i_assert(size > 0);

		arg->type = IMAP_ARG_STRING;
		str = p_strndup(parser->pool, data+1, size-1);

		/* remove the escapes */
		if (parser->str_first_escape >= 0 &&
		    (parser->flags & IMAP_PARSE_FLAG_NO_UNESCAPE) == 0) {
			/* -1 because we skipped the '"' prefix */
			(void)str_unescape(str + parser->str_first_escape-1);
		}
		arg->_data.str = str;
		arg->str_len = strlen(str);
		break;
	case ARG_PARSE_LITERAL_DATA:
		if ((parser->flags & IMAP_PARSE_FLAG_LITERAL_SIZE) != 0) {
			/* save literal size */
			arg->type = parser->literal_nonsync ?
				IMAP_ARG_LITERAL_SIZE_NONSYNC :
				IMAP_ARG_LITERAL_SIZE;
			arg->_data.literal_size = parser->literal_size;
			arg->literal8 = parser->literal8;
			break;
		}
		/* fall through */
	case ARG_PARSE_LITERAL_DATA_FORCED:
		if ((parser->flags & IMAP_PARSE_FLAG_LITERAL_TYPE) != 0)
			arg->type = IMAP_ARG_LITERAL;
		else
			arg->type = IMAP_ARG_STRING;
		arg->_data.str = imap_parser_strdup(parser, data, size);
		arg->literal8 = parser->literal8;
		arg->str_len = size;
		break;
	default:
                i_unreached();
	}

	parser->cur_type = ARG_PARSE_NONE;
}