Exemplo n.º 1
0
static bool search_header(struct message_search_context *ctx,
			  const struct message_header_line *hdr)
{
	static const unsigned char crlf[2] = { '\r', '\n' };

	return str_find_more(ctx->str_find_ctx,
			     (const unsigned char *)hdr->name, hdr->name_len) ||
		str_find_more(ctx->str_find_ctx,
			      hdr->middle, hdr->middle_len) ||
		str_find_more(ctx->str_find_ctx, hdr->full_value,
			      hdr->full_value_len) ||
		(!hdr->no_newline &&
		 str_find_more(ctx->str_find_ctx, crlf, 2));
}
Exemplo n.º 2
0
static bool test_str_find_substring(const char *key, int expected_pos)
{
	const unsigned char *text = (const unsigned char *)str_find_text;
	const unsigned int text_len = strlen(str_find_text);
	struct str_find_context *ctx;
	unsigned int i, j, pos, max, offset;
	bool ret;

	ctx = str_find_init(pool_datastack_create(), key);
	/* divide text into every possible block combination and test that
	   it matches */
	i_assert(text_len > 0);
	max = 1U << (text_len-1);
	for (i = 0; i < max; i++) {
		str_find_reset(ctx);
		pos = 0; offset = 0; ret = FALSE;
		for (j = 0; j < text_len; j++) {
			if ((i & (1 << j)) != 0) {
				if (str_find_more(ctx, text+pos, j-pos+1)) {
					ret = TRUE;
					break;
				}
				offset += j-pos + 1;
				pos = j + 1;
			}
		}
		if (pos != text_len && !ret) {
			if (str_find_more(ctx, text+pos, j-pos))
				ret = TRUE;
		}
		if (expected_pos < 0) {
			if (ret)
				return FALSE;
		} else {
			if (!ret)
				return FALSE;

			pos = str_find_get_match_end_pos(ctx) +
				offset - strlen(key);
			if ((int)pos != expected_pos)
				return FALSE;
		}
	}
	return TRUE;
}
Exemplo n.º 3
0
static bool message_search_more_decoded2(struct message_search_context *ctx,
					 struct message_block *block)
{
	if (block->hdr != NULL) {
		if (search_header(ctx, block->hdr))
			return TRUE;
	} else {
		if (str_find_more(ctx->str_find_ctx, block->data, block->size))
			return TRUE;
	}
	return FALSE;
}
Exemplo n.º 4
0
static int
dbox_file_find_next_magic(struct dbox_file *file, uoff_t *offset_r, bool *pre_r)
{
	struct istream *input = file->input;
	struct str_find_context *pre_ctx, *post_ctx;
	uoff_t orig_offset, pre_offset, post_offset;
	const unsigned char *data;
	size_t size;
	int ret;

	*pre_r = FALSE;

	pre_ctx = str_find_init(default_pool, "\n"DBOX_MAGIC_PRE);
	post_ctx = str_find_init(default_pool, DBOX_MAGIC_POST);

	/* \n isn't part of the DBOX_MAGIC_PRE, but it always preceds it.
	   assume that at this point we've already just read the \n. when
	   scanning for it later we'll need to find the \n though. */
	str_find_more(pre_ctx, (const unsigned char *)"\n", 1);

	orig_offset = input->v_offset;
	while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) {
		pre_offset = (uoff_t)-1;
		if (str_find_more(pre_ctx, data, size)) {
			pre_offset = input->v_offset +
				str_find_get_match_end_pos(pre_ctx) -
				(strlen(DBOX_MAGIC_PRE) + 1);
			*pre_r = TRUE;
		}
		if (str_find_more(post_ctx, data, size)) {
			post_offset = input->v_offset +
				str_find_get_match_end_pos(post_ctx) -
				strlen(DBOX_MAGIC_POST);
			if (pre_offset == (uoff_t)-1 ||
			    post_offset < pre_offset) {
				pre_offset = post_offset;
				*pre_r = FALSE;
			}
		}

		if (pre_offset != (uoff_t)-1) {
			if (*pre_r) {
				/* LF isn't part of the magic */
				pre_offset++;
			}
			*offset_r = pre_offset;
			break;
		}
		i_stream_skip(input, size);
	}
	if (ret <= 0) {
		i_assert(ret == -1);
		if (input->stream_errno != 0)
			dbox_file_set_syscall_error(file, "read()");
		else {
			ret = 0;
			*offset_r = input->v_offset;
		} 
	}
	i_stream_seek(input, orig_offset);
	str_find_deinit(&pre_ctx);
	str_find_deinit(&post_ctx);
	return ret;
}