changeset 880:d5168cca2052 HEAD

SEARCHing headers with "" value should always match if the header is found. Changed imap_envelope_parse() so that it's possible to differentiate NIL from "".
author Timo Sirainen <tss@iki.fi>
date Thu, 02 Jan 2003 11:06:33 +0200
parents 488a4c4bcabb
children fe91b60fdb7c
files src/lib-imap/imap-envelope.c src/lib-imap/imap-envelope.h src/lib-storage/index/index-search.c src/lib-storage/index/index-sort.c
diffstat 4 files changed, 75 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-imap/imap-envelope.c	Thu Jan 02 10:29:43 2003 +0200
+++ b/src/lib-imap/imap-envelope.c	Thu Jan 02 11:06:33 2003 +0200
@@ -233,16 +233,19 @@
 	return t_strdup(imap_arg_string(&list->args[2]));
 }
 
-static const char *
-imap_envelope_parse_arg(ImapArg *arg, ImapEnvelopeField field,
-			const char *envelope, ImapEnvelopeResult result)
+static int imap_envelope_parse_arg(ImapArg *arg, ImapEnvelopeField field,
+				   const char *envelope,
+				   ImapEnvelopeResult result_type,
+				   const char **result)
 {
 	const char *value = NULL;
 
-	if (arg->type == IMAP_ARG_NIL)
-		return "";
+	if (arg->type == IMAP_ARG_NIL) {
+		*result = NULL;
+		return TRUE;
+	}
 
-	switch (result) {
+	switch (result_type) {
 	case IMAP_ENVELOPE_RESULT_STRING:
 		if (field >= IMAP_ENVELOPE_FROM && field <= IMAP_ENVELOPE_BCC)
 			value = imap_envelope_parse_address(arg);
@@ -256,21 +259,22 @@
 		break;
 	}
 
-	if (value == NULL) {
+	*result = value;
+	if (value != NULL)
+		return TRUE;
+	else {
 		i_error("Invalid field %u in IMAP envelope: %s",
 			field, envelope);
+		return FALSE;
 	}
-
-	return value;
 }
 
-const char *imap_envelope_parse(const char *envelope, ImapEnvelopeField field,
-				ImapEnvelopeResult result)
+int imap_envelope_parse(const char *envelope, ImapEnvelopeField field,
+			ImapEnvelopeResult result_type, const char **result)
 {
 	IStream *input;
 	ImapParser *parser;
 	ImapArg *args;
-	const char *value;
 	int ret;
 
 	i_assert(field < IMAP_ENVELOPE_FIELDS);
@@ -282,14 +286,15 @@
 	(void)i_stream_read(input);
 	ret = imap_parser_read_args(parser, field+1, 0, &args);
 	if (ret > (int)field) {
-		value = imap_envelope_parse_arg(&args[field], field,
-						envelope, result);
+		ret = imap_envelope_parse_arg(&args[field], field,
+					      envelope, result_type, result);
 	} else {
 		i_error("Error parsing IMAP envelope: %s", envelope);
-		value = NULL;
+		*result = NULL;
+		ret = FALSE;
 	}
 
 	imap_parser_destroy(parser);
 	i_stream_unref(input);
-	return value;
+	return ret;
 }
--- a/src/lib-imap/imap-envelope.h	Thu Jan 02 10:29:43 2003 +0200
+++ b/src/lib-imap/imap-envelope.h	Thu Jan 02 11:06:33 2003 +0200
@@ -35,9 +35,9 @@
 /* Return envelope. */
 const char *imap_envelope_get_part_data(MessagePartEnvelopeData *data);
 
-/* Parse envelope and return specified field unquoted, or NULL if error
-   occured. NILs are returned as "". */
-const char *imap_envelope_parse(const char *envelope, ImapEnvelopeField field,
-				ImapEnvelopeResult result);
+/* Parse envelope and store specified field to result. NIL is stored as NULL.
+   Returns TRUE if successful. */
+int imap_envelope_parse(const char *envelope, ImapEnvelopeField field,
+			ImapEnvelopeResult result_type, const char **result);
 
 #endif
--- a/src/lib-storage/index/index-search.c	Thu Jan 02 10:29:43 2003 +0200
+++ b/src/lib-storage/index/index-search.c	Thu Jan 02 11:06:33 2003 +0200
@@ -278,13 +278,16 @@
 	}
 }
 
-static int search_sent(MailSearchArgType type, const char *value,
+static int search_sent(MailSearchArgType type, const char *search_value,
 		       const char *sent_value)
 {
 	time_t search_time, sent_time;
 	int timezone_offset;
 
-	if (!imap_parse_date(value, &search_time))
+	if (sent_value == NULL)
+		return 0;
+
+	if (!imap_parse_date(search_value, &search_time))
 		return 0;
 
 	/* NOTE: RFC2060 doesn't specify if timezones should affect
@@ -380,22 +383,29 @@
 	/* get field from hopefully cached envelope */
 	envelope = index->lookup_field(index, ctx->rec, DATA_FIELD_ENVELOPE);
 	if (envelope != NULL) {
-		field = imap_envelope_parse(envelope, env_field,
-					    IMAP_ENVELOPE_RESULT_STRING);
+		ret = imap_envelope_parse(envelope, env_field,
+					  IMAP_ENVELOPE_RESULT_STRING,
+					  &field) ? 1 : -1;
 	} else {
 		index->cache_fields_later(index, DATA_FIELD_ENVELOPE);
 		field = NULL;
+		ret = -1;
 	}
 
-	if (field == NULL)
-		ret = -1;
-	else {
+	if (ret != -1) {
 		switch (arg->type) {
 		case SEARCH_SENTBEFORE:
 		case SEARCH_SENTON:
 		case SEARCH_SENTSINCE:
 			ret = search_sent(arg->type, arg->value.str, field);
 		default:
+			if (arg->value.str[0] == '\0') {
+				/* we're just testing existence of the field.
+				   assume it matches with non-NIL values. */
+				ret = field != NULL ? 1 : 0;
+				break;
+			}
+
 			hdr_search_ctx = search_header_context(ctx, arg);
 			if (hdr_search_ctx == NULL) {
 				ret = 0;
@@ -488,18 +498,23 @@
 		return;
 	}
 
-	t_push();
+	if (arg->value.str[0] == '\0') {
+		/* we're just testing existence of the field. always matches. */
+		ret = 1;
+	} else {
+		t_push();
 
-	/* then check if the value matches */
-	hdr_search_ctx = search_header_context(ctx->index_context, arg);
-	if (hdr_search_ctx == NULL)
-		ret = 0;
-	else {
-		len = ctx->value_len;
-		ret = message_header_search(ctx->value, len,
-					    hdr_search_ctx) ? 1 : 0;
+		/* then check if the value matches */
+		hdr_search_ctx = search_header_context(ctx->index_context, arg);
+		if (hdr_search_ctx == NULL)
+			ret = 0;
+		else {
+			len = ctx->value_len;
+			ret = message_header_search(ctx->value, len,
+						    hdr_search_ctx) ? 1 : 0;
+		}
+		t_pop();
 	}
-	t_pop();
 
         ARG_SET_RESULT(arg, ret);
 }
--- a/src/lib-storage/index/index-sort.c	Thu Jan 02 10:29:43 2003 +0200
+++ b/src/lib-storage/index/index-sort.c	Thu Jan 02 11:06:33 2003 +0200
@@ -52,7 +52,7 @@
 {
 	IndexSortContext *ctx = context;
 	ImapEnvelopeField env_field;
-	const char *envelope;
+	const char *envelope, *str;
 
 	switch (type) {
 	case MAIL_SORT_CC:
@@ -72,16 +72,21 @@
 	/* get field from hopefully cached envelope */
 	envelope = imap_msgcache_get(search_open_cache(ctx, id),
 				     IMAP_CACHE_ENVELOPE);
-	return envelope == NULL ? NULL :
-		imap_envelope_parse(envelope, env_field,
-				    IMAP_ENVELOPE_RESULT_FIRST_MAILBOX);
+	if (envelope == NULL)
+		return NULL;
+
+	if (!imap_envelope_parse(envelope, env_field,
+				 IMAP_ENVELOPE_RESULT_FIRST_MAILBOX, &str))
+		return NULL;
+
+	return str;
 }
 
 static const char *_input_str(MailSortType type, unsigned int id, void *context)
 {
 	IndexSortContext *ctx = context;
 	ImapEnvelopeField env_field;
-	const char *envelope;
+	const char *envelope, *str;
 
 	switch (type) {
 	case MAIL_SORT_DATE:
@@ -98,9 +103,14 @@
 	/* get field from hopefully cached envelope */
 	envelope = imap_msgcache_get(search_open_cache(ctx, id),
 				     IMAP_CACHE_ENVELOPE);
-	return envelope == NULL ? NULL :
-		imap_envelope_parse(envelope, env_field,
-				    IMAP_ENVELOPE_RESULT_STRING);
+	if (envelope == NULL)
+		return NULL;
+
+	if (!imap_envelope_parse(envelope, env_field,
+				 IMAP_ENVELOPE_RESULT_STRING, &str))
+		return NULL;
+
+	return str;
 }
 
 static time_t _input_time(MailSortType type, unsigned int id, void *context)