Skip to content

Commit

Permalink
lib-mail: message_header_hash_more() now allows input in any slices.
Browse files Browse the repository at this point in the history
There wasn't necessarily any guarantees that the input would be sliced in
such a way that the repeating '?' would be dropped the same way every time.
  • Loading branch information
sirainen authored and GitLab committed Sep 22, 2016
1 parent f4b1d51 commit b75eba4
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 7 deletions.
6 changes: 4 additions & 2 deletions src/doveadm/dsync/dsync-mail.c
Expand Up @@ -30,6 +30,7 @@ int dsync_mail_get_hdr_hash(struct mail *mail, unsigned int version,
{
struct istream *hdr_input, *input;
struct mailbox_header_lookup_ctx *hdr_ctx;
struct message_header_hash_context hash_ctx;
struct md5_context md5_ctx;
unsigned char md5_result[MD5_RESULTLEN];
const unsigned char *data;
Expand All @@ -45,13 +46,14 @@ int dsync_mail_get_hdr_hash(struct mail *mail, unsigned int version,
input = i_stream_create_lf(hdr_input);

md5_init(&md5_ctx);
memset(&hash_ctx, 0, sizeof(hash_ctx));
while (!i_stream_is_eof(input)) {
if (i_stream_read_more(input, &data, &size) == -1)
break;
if (size == 0)
break;
message_header_hash_more(&hash_method_md5, &md5_ctx, version,
data, size);
message_header_hash_more(&hash_ctx, &hash_method_md5, &md5_ctx,
version, data, size);
i_stream_skip(input, size);
}
if (input->stream_errno != 0)
Expand Down
6 changes: 4 additions & 2 deletions src/lib-mail/message-header-hash.c
Expand Up @@ -4,7 +4,8 @@
#include "hash-method.h"
#include "message-header-hash.h"

void message_header_hash_more(const struct hash_method *method, void *context,
void message_header_hash_more(struct message_header_hash_context *ctx,
const struct hash_method *method, void *context,
unsigned int version,
const unsigned char *data, size_t size)
{
Expand Down Expand Up @@ -32,12 +33,13 @@ void message_header_hash_more(const struct hash_method *method, void *context,
if ((data[i] < 0x20 || data[i] >= 0x7f || data[i] == '?') &&
(data[i] != '\t' && data[i] != '\n')) {
/* remove repeated '?' */
if (start < i || i == 0) {
if (start < i || (i == 0 && !ctx->prev_was_questionmark)) {
method->loop(context, data + start, i-start);
method->loop(context, "?", 1);
}
start = i+1;
}
}
ctx->prev_was_questionmark = start == i;
method->loop(context, data + start, i-start);
}
8 changes: 7 additions & 1 deletion src/lib-mail/message-header-hash.h
Expand Up @@ -3,7 +3,13 @@

struct hash_method;

void message_header_hash_more(const struct hash_method *method, void *context,
struct message_header_hash_context {
bool prev_was_questionmark;
};

/* Initialize ctx with zeros. */
void message_header_hash_more(struct message_header_hash_context *ctx,
const struct hash_method *method, void *context,
unsigned int version,
const unsigned char *data, size_t size);

Expand Down
15 changes: 14 additions & 1 deletion src/lib-mail/test-message-header-hash.c
Expand Up @@ -14,12 +14,14 @@ static const unsigned char test_output[] =

static void test_dsync_mail_hash_more(void)
{
struct message_header_hash_context ctx;
struct md5_context md5_ctx;
unsigned char md5_input[MD5_RESULTLEN], md5_output[MD5_RESULTLEN];

test_begin("dsync_mail_hash_more v2");
md5_init(&md5_ctx);
message_header_hash_more(&hash_method_md5, &md5_ctx, 2,
memset(&ctx, 0, sizeof(ctx));
message_header_hash_more(&ctx, &hash_method_md5, &md5_ctx, 2,
test_input, sizeof(test_input)-1);
md5_final(&md5_ctx, md5_input);

Expand All @@ -28,6 +30,17 @@ static void test_dsync_mail_hash_more(void)
md5_final(&md5_ctx, md5_output);

test_assert(memcmp(md5_input, md5_output, MD5_RESULTLEN) == 0);

/* single byte at a time */
md5_init(&md5_ctx);
memset(&ctx, 0, sizeof(ctx));
for (unsigned int i = 0; i < sizeof(test_input)-1; i++) {
message_header_hash_more(&ctx, &hash_method_md5, &md5_ctx, 2,
test_input + i, 1);
}
md5_final(&md5_ctx, md5_input);
test_assert(memcmp(md5_input, md5_output, MD5_RESULTLEN) == 0);

test_end();
}

Expand Down
4 changes: 3 additions & 1 deletion src/plugins/pop3-migration/pop3-migration-plugin.c
Expand Up @@ -178,6 +178,7 @@ int pop3_migration_get_hdr_sha1(uint32_t mail_seq, struct istream *input,
{
const unsigned char *data;
size_t size;
struct message_header_hash_context hash_ctx;
struct sha1_ctxt sha1_ctx;
struct pop3_hdr_context hdr_ctx;

Expand All @@ -190,8 +191,9 @@ int pop3_migration_get_hdr_sha1(uint32_t mail_seq, struct istream *input,
pop3_header_filter_callback, &hdr_ctx);

sha1_init(&sha1_ctx);
memset(&hash_ctx, 0, sizeof(hash_ctx));
while (i_stream_read_more(input, &data, &size) > 0) {
message_header_hash_more(&hash_method_sha1, &sha1_ctx, 2,
message_header_hash_more(&hash_ctx, &hash_method_sha1, &sha1_ctx, 2,
data, size);
i_stream_skip(input, size);
}
Expand Down

0 comments on commit b75eba4

Please sign in to comment.