var-expand-if.c revision a602629cbc5f65341b6cc24ca412a622d1880605
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi/* Copyright (c) 2003-2017 Dovecot authors, see the included COPYING file */
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi/* put all numeric comparisons before this line */
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi/* keep this as last */
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomistatic enum var_expand_if_op var_expand_if_str_to_comp(const char *op)
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi for(enum var_expand_if_op i = 1; i < OP_COUNT; i++) {
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomistatic int var_expand_if_comp(const char *lhs, const char *_op, const char *rhs,
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi enum var_expand_if_op op = var_expand_if_str_to_comp(_op);
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi *error_r = t_strdup_printf("if: Unsupported comparator '%s'", _op);
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi *error_r = t_strdup_printf("if: %s (lhs) is not a number", lhs);
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi *error_r = t_strdup_printf("if: %s (rhs) is not a number", rhs);
ac225e892630ecfdbbd09afe27887edd13d4697bTimo Sirainen /* fall through */
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi if ((ec = regcomp(®, rhs, REG_EXTENDED)) != 0) {
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi *error_r = t_strdup_printf("if: regex failed: %s",
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi /* this should be same as neg.
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi if NOT_REGEXP, neg == TRUE and res should be FALSE
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi if REGEXP, ned == FALSE, and res should be TRUE
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi /* in case the original input had :, we need to fix that
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi by concatenating the key and field together. */
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi const char *input = t_strconcat(key, ":", field, NULL);
9ab2df665ed6bd5043c3334853fcb008aecbf315Aki Tuomi const char *par_end;
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi const char *const *parms;
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi unsigned int depth = 0;
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi /* we need to skip any %{} parameters here, so we can split the string
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi correctly from , without breaking any inner expansions */
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi } else if (escape) {
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi /* if there is a unescaped : at top level it means
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi that the key + arguments end here. it's probably
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi a by-product of the t_strconcat at top of function,
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi which is best handled here. */
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi *error_r = t_strdup_printf("if: requires four or five parameters, got %u",
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi /* expand the parameters */
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi if ((ret = var_expand_with_funcs(param, *parms, ctx->table,
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi /* execute comparison */
b3e71425659780a58cba2f1d84eceef5b4616762Aki Tuomi if (var_expand_if_comp(args[0], args[1], args[2], &result, error_r)<0)