/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
/* imap_match_init() logic originates from Cyrus, but the code is fully
rewritten. */
#include "lib.h"
#include "array.h"
#include "imap-match.h"
#include <ctype.h>
struct imap_match_pattern {
const char *pattern;
bool inboxcase;
};
struct imap_match_glob {
char sep;
};
struct imap_match_context {
const char *inboxcase_end;
char sep;
bool inboxcase;
};
/* name of "INBOX" - must not have repeated substrings */
struct imap_match_glob *
{
}
{
/* @UNSAFE: compress the pattern */
while (*pattern != '\0') {
/* remove duplicate hierarchy wildcards */
/* "%*" -> "*" */
if (*pattern == '*') {
/* remove duplicate wildcards */
pattern++;
*dest++ = '*';
} else {
*dest++ = '%';
}
} else {
}
}
*dest = '\0';
return ret;
}
{
/* skip over exact matches */
inboxp++; p++;
}
if (*p != '%') {
return *p == '*' || *p == separator ||
}
/* handle 'I%B%X' style checks */
if (*p != '%') {
return FALSE;
if (*++inboxp == '\0') {
/* now check that it doesn't end with
any invalid chars */
if (*++p == '%') p++;
if (*p != '\0' && *p != '*' &&
*p != separator)
return FALSE;
break;
}
}
}
return TRUE;
}
static struct imap_match_glob *
{
unsigned int i, patterns_count;
patterns_count + 1);
/* compress the patterns */
for (i = 0; i < patterns_count; i++) {
}
patterns_count = i;
/* now we know how much memory we need */
/* copy pattern strings to our allocated memory */
for (i = 0, pos = 0; i < patterns_count; i++) {
/* @UNSAFE */
}
return glob;
}
struct imap_match_glob *
{
if (pool->datastack_pool) {
}
T_BEGIN {
} T_END;
return glob;
}
{
return;
}
static struct imap_match_glob *
{
const struct imap_match_pattern *p;
if (p->inboxcase)
}
}
struct imap_match_glob *
{
if (pool->datastack_pool) {
} else {
T_BEGIN {
} T_END;
return new_glob;
}
}
const struct imap_match_glob *glob2)
{
return FALSE;
return FALSE;
return FALSE;
}
}
static enum imap_match_result
const char **pattern_p)
{
unsigned int i;
/* match all non-wildcards */
i = 0;
if (data[i] != '\0')
return IMAP_MATCH_NO;
return IMAP_MATCH_CHILDREN;
return IMAP_MATCH_CHILDREN;
}
return IMAP_MATCH_NO;
}
i++;
}
data += i;
pattern += i;
*pattern != '\0') {
/* data="/" pattern="/%..." */
} else {
}
while (*pattern == '%') {
pattern++;
if (*pattern == '\0') {
/* match, if this is the last hierarchy */
data++;
break;
}
/* skip over this hierarchy */
while (*data != '\0') {
if (ret == IMAP_MATCH_YES)
break;
}
break;
data++;
}
}
if (*pattern != '*') {
return match;
}
if (*data != '\0') {
return match;
}
}
return IMAP_MATCH_YES;
}
static enum imap_match_result
{
/* data begins with INBOX/, use case-insensitive comparison
for it */
}
if (*pattern != '*') {
/* handle the pattern up to the first '*' */
return ret;
}
while (*pattern == '*') {
pattern++;
if (*pattern == '\0')
return IMAP_MATCH_YES;
while (*data != '\0') {
if (ret == IMAP_MATCH_YES)
break;
}
data++;
}
}
}
enum imap_match_result
{
unsigned int i;
if (ret == IMAP_MATCH_YES)
return IMAP_MATCH_YES;
}
return match;
}