str-find.c revision f609bd50846f898583ef481d8aac927b10aa8395
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2008 Dovecot authors, see the included COPYING file */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch/* @UNSAFE: whole file */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch unsigned char *key;
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Bosch unsigned int key_len;
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Bosch unsigned int *matches;
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Boschstatic void init_badtab(struct str_find_context *ctx)
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Bosch for (i = 0; i <= UCHAR_MAX; i++)
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Bosch for (i = 0; i < len_1; i++)
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Boschstatic void init_suffixes(struct str_find_context *ctx, unsigned int *suffixes)
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Bosch int f = 0, g, i;
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Bosch if (i > g && (int)suffixes[i + len_1 - f] < i - g)
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Bosch while (g >= 0 && ctx->key[g] == ctx->key[g + len_1 - f])
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Boschstatic void init_goodtab(struct str_find_context *ctx)
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Bosch unsigned int j, *suffixes;
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Bosch suffixes = t_buffer_get(sizeof(*suffixes) * ctx->key_len);
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Bosch if (i < 0 || suffixes[i] == (unsigned int)i + 1) {
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Bosch for (; j < len_1 - i; j++) {
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Bosch ctx->goodtab[len_1 - suffixes[i]] = len_1 - i;
62ed3307fb8a4a038a32a5181c503f1b645bf946Stephan Boschstruct str_find_context *str_find_init(pool_t pool, const char *key)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch ctx = p_malloc(pool, sizeof(struct str_find_context) +
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch ctx->matches = p_new(pool, unsigned int, key_len);
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschvoid str_find_deinit(struct str_find_context **_ctx)
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschbool str_find_more(struct str_find_context *ctx,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch unsigned int i, j, a, b;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* we can fully determine this match now */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch for (; a < key_len; a++) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch for (b = 0; b < size; b++) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* Boyer-Moore searching */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch bad_value = ctx->badtab[data[i + j]] + i + 1 - key_len;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch for (; j < size; j++) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch for (i = j; i < size; i++) {