bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen#include "test-lib.h"
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen#include "str-find.h"
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainenstatic const char *str_find_text = "xababcd";
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainenstatic bool test_str_find_substring(const char *key, int expected_pos)
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen{
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen const unsigned char *text = (const unsigned char *)str_find_text;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen const unsigned int text_len = strlen(str_find_text);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen struct str_find_context *ctx;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen unsigned int i, j, pos, max, offset;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen bool ret;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen ctx = str_find_init(pool_datastack_create(), key);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen /* divide text into every possible block combination and test that
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen it matches */
35283613d4c04ce18836e9fc431582c87b3710a0Timo Sirainen i_assert(text_len > 0);
35283613d4c04ce18836e9fc431582c87b3710a0Timo Sirainen max = 1U << (text_len-1);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen for (i = 0; i < max; i++) {
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen str_find_reset(ctx);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen pos = 0; offset = 0; ret = FALSE;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen for (j = 0; j < text_len; j++) {
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen if ((i & (1 << j)) != 0) {
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen if (str_find_more(ctx, text+pos, j-pos+1)) {
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen ret = TRUE;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen break;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen }
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen offset += j-pos + 1;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen pos = j + 1;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen }
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen }
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen if (pos != text_len && !ret) {
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen if (str_find_more(ctx, text+pos, j-pos))
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen ret = TRUE;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen }
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen if (expected_pos < 0) {
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen if (ret)
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen return FALSE;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen } else {
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen if (!ret)
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen return FALSE;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen pos = str_find_get_match_end_pos(ctx) +
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen offset - strlen(key);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen if ((int)pos != expected_pos)
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen return FALSE;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen }
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen }
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen return TRUE;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen}
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainenstruct str_find_input {
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen const char *str;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen int pos;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen};
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainenvoid test_str_find(void)
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen{
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen static const char *fail_input[] = {
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen "xabc",
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen "xabd",
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen "abd"
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen };
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen unsigned int idx, len;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen const char *key, *p;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen unsigned int i;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen bool success = TRUE;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen for (idx = 0; idx < strlen(str_find_text); idx++) {
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen for (len = strlen(str_find_text)-idx; len > 0; len--) {
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen /* we'll get a search key for all substrings of text */
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen T_BEGIN {
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen key = t_strndup(str_find_text + idx, len);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen p = strstr(str_find_text, key);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen success = test_str_find_substring(key, p - str_find_text);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen } T_END;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen if (!success)
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen break;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen }
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen }
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen for (i = 0; i < N_ELEMENTS(fail_input) && success; i++)
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen success = test_str_find_substring(fail_input[i], -1);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen test_out("str_find()", success);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen}