Пример #1
0
var_t *
exp_eval(exp_t *exp, var_t *mailspec)
{
	if (exp == NULL)
	{
		log_debug("exp_eval: expression is null");
		return NULL;
	}

	switch (exp->ex_type)
	{
	case EX_PARENTHESES:	return exp_eval(exp->ex_data, mailspec);
	case EX_CONSTANT:	return exp->ex_data;
	case EX_LIST:		return exp_eval_list(exp, mailspec);
	case EX_SYMBOL:		return acl_symbol_get(mailspec, exp->ex_data);
	case EX_FUNCTION:	return exp_eval_function(exp, mailspec);
	case EX_OPERATION:	return exp_eval_operation(exp, mailspec);
	case EX_VARIABLE:	return exp_eval_variable(exp, mailspec);
	case EX_MACRO:		return exp_eval_macro(exp, mailspec);
	case EX_TERNARY_COND:	return exp_eval_ternary_condition(exp, mailspec);

	default:
		log_error("exp_eval: bad type");
	}

	return NULL;
}
Пример #2
0
static var_t *
exp_assign(exp_t *left, exp_t *right, var_t *mailspec)
{
	var_t *value;
	char *name;

	if (left->ex_type != EX_VARIABLE)
	{
		log_error("exp_assign: left expression is faulty");
		return NULL;
	}

	name = left->ex_data;

	/*
	 * Evaluate expression
	 */
	value = exp_eval(right, mailspec);
	if (value == NULL)
	{
		log_error("exp_eval_variables: exp_eval failed");
		return NULL;
	}

	if (acl_variable_assign(mailspec, name, value))
	{
		log_error("exp_eval_variable: acl_variable_assign failed");
		return NULL;
	}

	return value;
}
Пример #3
0
int evaluate(char *exp, bool used[], int vals[]) {
    int i = 0, res = 0, opcount = 0, varcount = 0;
    char op;
    while (exp[i]) {
        if (isalpha(exp[i])) {
            varcount++;
            if (varcount == 1) {
                res = vals[exp[i] - DIFF];
                if (opcount == 1) {
                    res = unary_exp_eval(vals[exp[i] - DIFF], op);
                }
            } else if (varcount > 1) {
                res = exp_eval(res, vals[exp[i] - DIFF], op);
            }
            opcount = 0;
            used[exp[i] - DIFF] = true;
        } else if (isoperator(exp[i])) {
            opcount++;
            if (opcount == 1 || (opcount == 3 && exp[i] != exp[i-1])) {
                op = exp[i];
            }
        }
        i++;
    }
    return res;
}
Пример #4
0
static var_t *
exp_eval_ternary_condition(exp_t *exp, var_t *mailspec)
{
	exp_ternary_condition_t *etc = exp->ex_data;
	var_t *v = NULL;
	int result;

	v = exp_eval(etc->etc_condition, mailspec);
	if (v == NULL)
	{
		log_error("exp_eval_ternary_condition: evaluation failed");
		return NULL;
	}

	result = var_true(v);
	exp_free(v);

	if (result)
	{
		return exp_eval(etc->etc_true, mailspec);
	}

	return exp_eval(etc->etc_false, mailspec);
}
Пример #5
0
acl_action_type_t
pipe_action(milter_stage_t stage, char *stagename, var_t *mailspec, void *data,
	int depth)
{
	exp_t *exp = data;
	var_t *v;
	char *dest;
	char *message;
	int size;
	acl_action_type_t a;
	
	v = exp_eval(exp, mailspec);
	if (v == NULL)
	{
		log_error("pipe_exec: exp_eval failed");
		return ACL_ERROR;
	}

	if (v->v_type != VT_STRING)
	{
		log_error("pipe_exec: bad expression in mail.acl");
		return ACL_ERROR;
	}

	dest = v->v_data;
	log_message(LOG_ERR, mailspec, "pipe_exec: %s", dest);

	size = milter_message(mailspec, &message);
	if (size == -1)
	{
		log_error("pipe_exec: milter_message failed");
		return ACL_ERROR;
	}

	if (strncmp(dest, "inet:", 5) == 0 || strncmp(dest, "unix:", 5) == 0)
	{
		a = pipe_socket(dest, message, size);
	}
	else
	{
		a = pipe_exec(dest, message, size);
	}

	free(message);

	return a;
}
Пример #6
0
static var_t *
exp_eval_list(exp_t *exp, var_t *mailspec)
{
	ll_t *exp_list = exp->ex_data;
	ll_entry_t *pos;
	exp_t *exp_item;
	var_t *var_item, *var_list = NULL;

	var_list = vlist_create(NULL, VF_EXP_FREE);
	if (var_list == NULL)
	{
		log_sys_error("exp_eval_list: malloc");
		goto error;
	}

	pos = LL_START(exp_list);
	while ((exp_item = ll_next(exp_list, &pos)))
	{
		var_item = exp_eval(exp_item, mailspec);

		if (vlist_append(var_list, var_item))
		{
			log_sys_error("exp_eval_list: malloc");
			goto error;
		}
	}

	return var_list;


error:

	if (var_list)
	{
		var_delete(var_list);
	}

	return NULL;
}
Пример #7
0
int
exp_is_true(exp_t *exp, var_t *mailspec)
{
	var_t *v;
	int r;

	if (exp == NULL)
	{
		return 1;
	}

	v = exp_eval(exp, mailspec);
	if (v == NULL)
	{
		log_notice("exp_is_true: evaluation failed");
		return -1;
	}

	r = var_true(v);

	exp_free(v);

	return r;
}
Пример #8
0
static var_t *
exp_bool(var_t *mailspec, int op, exp_t *left_exp, exp_t *right_exp)
{
	int known_value, left_known, right_known, result;
	int left_true = 0;
	int right_true = 0;
	var_t *left = NULL;
	var_t *right = NULL;

	if (op != OR && op != AND)
	{
		log_error("exp_bool: bad operation");
		return NULL;
	}

	if (left_exp == NULL || right_exp == NULL)
	{
		log_error("exp_bool: operand is NULL");
		return NULL;
	}

	// Evaluate left operand
	left = exp_eval(left_exp, mailspec);
	if (left == NULL)
	{
		log_error("exp_bool: exp_eval for lefthand operator failed");
		return NULL;
	}

	left_known = left->v_data != NULL;
	if (left_known)
	{
		left_true = var_true(left);
	}
	
	// Short-Circuit Operator (like Perl)
	if (op == OR && left_known && left_true)
	{
		return left;
	}

	exp_free(left);

	// AND operation with left value known and false.
	if (op == AND && left_known && !left_true)
	{
		return &exp_false;
	}

	// Evaluate right operand
	right = exp_eval(right_exp, mailspec);
	if (right == NULL)
	{
		log_error("exp_bool: exp_eval for righthand operator failed");
		return NULL;
	}

	right_known = right->v_data != NULL;
	if (right_known)
	{
		right_true = var_true(right);
	}

	// Short-Circuit Operator (like Perl)
	if (op == OR && !left_true)
	{
		return right;
	}

	exp_free(right);

	// Both sides are unknown
	if (!left_known && !right_known)
	{
		return &exp_empty;
	}

	// One side is unknown
	if (!left_known || !right_known)
	{
		known_value = left_known ? left_true: right_true;

		if (op == AND && !known_value)
		{
			return &exp_false;
		}

		// This case should be handled by the shortcut logic above!
		if (op == OR && known_value)
		{
			log_error("exp_bool: logic error");
			return NULL;
		}

		return &exp_empty;
	}

	// Both sides are known
	if (op == AND)
	{
		result = left_true && right_true;
	}
	else
	{
		result = left_true || right_true;
	}

	if (result)
	{
		return  &exp_true;
	}

	return &exp_false;
}
Пример #9
0
static var_t *
exp_eval_function(exp_t *exp, var_t *mailspec)
{
	exp_function_t *ef = exp->ex_data;
	acl_function_t *af;
	var_t *args = NULL;
	ll_t *single = NULL;
	var_t *v = NULL;

	af = acl_function_lookup(ef->ef_name);
	if (af == NULL)
	{
		log_error("exp_eval_function: unknown function \"%s\"",
		    ef->ef_name);
		goto error;
	}

	/*
	 * Function has arguments
	 */
	if (ef->ef_args)
	{
		args = exp_eval(ef->ef_args, mailspec);
		if (args == NULL)
		{
			log_error("exp_eval_function: exp_eval failed");
			goto error;
		}

		/*
		 * Convert single argument into list.
		 */
		if (args->v_type != VT_LIST)
		{
			single = ll_create();
			if (single == NULL)
			{
				log_error("exp_eval_function: ll_create failed");
				goto error;
			}

			if (LL_INSERT(single, args) == -1)
			{
				log_error("exp_eval_function: LL_INSERT failed");
				goto error;
			}
		}
	}
	else
	{
		/*
		 * Function has no arguments -> empty list
		 */
		single = ll_create();
		if (single == NULL)
		{
			log_error("exp_eval_function: ll_create failed");
			goto error;
		}
	}

	if (af->af_type == AF_SIMPLE)
	{
		v = exp_eval_function_simple(ef->ef_name, af,
		    single ? single : args->v_data);
	}
	else
	{
		v = exp_eval_function_complex(ef->ef_name, af,
		    single ? single : args->v_data);
	}

	if (v == NULL)
	{
		log_error("exp_eval_function: function \"%s\" failed",
		    ef->ef_name);
		goto error;
	}

error:
	if (single)
	{
		ll_delete(single, NULL);
	}

	if (args)
	{
		exp_free(args);
	}

	return v;
}
Пример #10
0
void
exp_test(int n)
{
	// exp_is_true
	TEST_ASSERT(!exp_is_true(exp_test_int_0, NULL));
	TEST_ASSERT(exp_is_true(exp_test_int_1, NULL));
	TEST_ASSERT(exp_is_true(exp_test_int_2, NULL));
	TEST_ASSERT(exp_is_true(exp_test_int_3, NULL));
	TEST_ASSERT(!exp_is_true(exp_test_float_0, NULL));
	TEST_ASSERT(exp_is_true(exp_test_float_1, NULL));
	TEST_ASSERT(exp_is_true(exp_test_float_2, NULL));
	TEST_ASSERT(exp_is_true(exp_test_float_3, NULL));
	TEST_ASSERT(!exp_is_true(exp_test_str_0, NULL));
	TEST_ASSERT(exp_is_true(exp_test_str_1, NULL));
	TEST_ASSERT(exp_is_true(exp_test_str_2, NULL));
	TEST_ASSERT(exp_is_true(exp_test_str_3, NULL));
	TEST_ASSERT(!exp_is_true(exp_test_null, NULL));

	TEST_ASSERT(!exp_is_true(exp_test_addr_0, NULL));
	TEST_ASSERT(!exp_is_true(exp_test_addr_1, NULL));
	TEST_ASSERT(exp_is_true(exp_test_addr_2, NULL));
	TEST_ASSERT(exp_is_true(exp_test_addr_3, NULL));
	TEST_ASSERT(exp_is_true(exp_test_addr_4, NULL));

	// Not
	TEST_ASSERT(exp_eval(exp_operation('!', exp_test_int_0, NULL), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('!', exp_test_int_1, NULL), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('!', exp_test_float_0, NULL), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('!', exp_test_float_1, NULL), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('!', exp_test_str_0, NULL), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('!', exp_test_str_1, NULL), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('!', exp_test_addr_2, NULL), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('!', exp_test_addr_3, NULL), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('!', exp_test_addr_0, NULL), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('!', exp_test_addr_1, NULL), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('!', exp_test_null, NULL), NULL) == EXP_EMPTY);

	// AND
	TEST_ASSERT(exp_eval(exp_operation(AND, exp_test_int_0, exp_test_float_0), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(AND, exp_test_str_1, exp_test_float_0), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(AND, exp_test_str_0, exp_test_int_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(AND, exp_test_int_1, exp_test_float_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(AND, exp_test_null, exp_test_str_0), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(AND, exp_test_int_1, exp_test_null), NULL) == EXP_EMPTY);
	TEST_ASSERT(exp_eval(exp_operation(AND, exp_test_int_1, exp_test_addr_0), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(AND, exp_test_addr_0, exp_test_addr_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(AND, exp_test_addr_2, exp_test_addr_3), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(AND, exp_test_addr_3, exp_test_addr_4), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(AND, exp_test_null, exp_test_null), NULL) == EXP_EMPTY);

	// OR
	TEST_ASSERT(exp_eval(exp_operation(OR, exp_test_int_0, exp_test_float_0), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(OR, exp_test_str_1, exp_test_float_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(OR, exp_test_str_0, exp_test_int_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(OR, exp_test_int_1, exp_test_float_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(OR, exp_test_null, exp_test_str_0), NULL) == EXP_EMPTY);
	TEST_ASSERT(exp_eval(exp_operation(OR, exp_test_int_1, exp_test_null), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(OR, exp_test_addr_0, exp_test_addr_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(OR, exp_test_addr_1, exp_test_str_0), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(OR, exp_test_addr_0, exp_test_addr_4), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(OR, exp_test_null, exp_test_null), NULL) == EXP_EMPTY);

	// < 
	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_int_0, exp_test_int_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_int_1, exp_test_int_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_float_0, exp_test_float_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_float_1, exp_test_float_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_int_1, exp_test_float_3), NULL) == EXP_TRUE);

	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_int_1, exp_test_int_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_int_2, exp_test_int_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_float_1, exp_test_float_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_float_2, exp_test_float_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_float_3, exp_test_int_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_int_1, exp_test_float_2), NULL) == EXP_FALSE);

	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_addr_0, exp_test_addr_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_addr_1, exp_test_addr_4), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_addr_2, exp_test_addr_3), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_addr_0, exp_test_addr_0), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('<', exp_test_addr_1, exp_test_addr_1), NULL) == EXP_FALSE);

	// > 
	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_int_1, exp_test_int_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_int_2, exp_test_int_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_float_1, exp_test_float_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_float_2, exp_test_float_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_float_3, exp_test_int_1), NULL) == EXP_TRUE);

	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_int_1, exp_test_int_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_int_1, exp_test_int_2), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_float_1, exp_test_float_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_float_1, exp_test_float_2), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_int_1, exp_test_float_3), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_int_1, exp_test_float_2), NULL) == EXP_FALSE);

	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_addr_2, exp_test_addr_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_addr_4, exp_test_addr_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_addr_3, exp_test_addr_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_addr_0, exp_test_addr_0), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation('>', exp_test_addr_1, exp_test_addr_1), NULL) == EXP_FALSE);

	// LE
	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_int_0, exp_test_int_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_int_1, exp_test_int_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_float_0, exp_test_float_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_float_1, exp_test_float_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_int_1, exp_test_float_3), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_int_1, exp_test_int_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_float_1, exp_test_float_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_int_1, exp_test_float_2), NULL) == EXP_TRUE);

	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_int_2, exp_test_int_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_float_2, exp_test_float_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_float_3, exp_test_int_1), NULL) == EXP_FALSE);

	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_addr_0, exp_test_addr_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_addr_1, exp_test_addr_4), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_addr_2, exp_test_addr_3), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_addr_0, exp_test_addr_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(LE, exp_test_addr_1, exp_test_addr_1), NULL) == EXP_TRUE);

	// GE
	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_int_1, exp_test_int_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_int_2, exp_test_int_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_float_1, exp_test_float_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_float_2, exp_test_float_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_float_3, exp_test_int_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_int_1, exp_test_int_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_float_1, exp_test_float_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_float_2, exp_test_int_1), NULL) == EXP_TRUE);

	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_int_1, exp_test_int_2), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_float_1, exp_test_float_2), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_int_1, exp_test_float_3), NULL) == EXP_FALSE);

	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_addr_2, exp_test_addr_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_addr_4, exp_test_addr_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_addr_3, exp_test_addr_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_addr_0, exp_test_addr_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(GE, exp_test_addr_1, exp_test_addr_1), NULL) == EXP_TRUE);

	// EQ
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_int_0, exp_test_int_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_int_1, exp_test_int_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_float_0, exp_test_float_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_float_1, exp_test_float_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_str_0, exp_test_str_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_str_3, exp_test_str_3), NULL) == EXP_TRUE);
	
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_int_1, exp_test_str_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_float_3, exp_test_str_2), NULL) == EXP_TRUE);

	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_int_1, exp_test_int_2), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_float_1, exp_test_float_2), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_str_1, exp_test_str_2), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_int_1, exp_test_float_3), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_float_1, exp_test_str_3), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_int_3, exp_test_str_0), NULL) == EXP_FALSE);

	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_addr_2, exp_test_addr_0), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_addr_4, exp_test_addr_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_addr_3, exp_test_addr_2), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_addr_0, exp_test_addr_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_test_addr_1, exp_test_addr_1), NULL) == EXP_TRUE);

	// NE
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_int_0, exp_test_int_0), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_int_1, exp_test_int_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_float_0, exp_test_float_0), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_float_1, exp_test_float_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_str_0, exp_test_str_0), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_str_3, exp_test_str_3), NULL) == EXP_FALSE);
	
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_int_1, exp_test_str_1), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_float_3, exp_test_str_2), NULL) == EXP_FALSE);

	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_int_1, exp_test_int_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_float_1, exp_test_float_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_str_1, exp_test_str_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_int_1, exp_test_float_3), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_float_1, exp_test_str_3), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_int_3, exp_test_str_0), NULL) == EXP_TRUE);

	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_addr_2, exp_test_addr_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_addr_4, exp_test_addr_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_addr_3, exp_test_addr_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_addr_0, exp_test_addr_0), NULL) == EXP_FALSE);
	TEST_ASSERT(exp_eval(exp_operation(NE, exp_test_addr_1, exp_test_addr_1), NULL) == EXP_FALSE);

	// +
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('+', exp_test_int_0, exp_test_int_1), exp_test_int_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('+', exp_test_int_1, exp_test_int_2), exp_test_int_3), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('+', exp_test_float_0, exp_test_float_1), exp_test_float_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('+', exp_test_float_1, exp_test_float_2), exp_test_float_3), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('+', exp_test_str_0, exp_test_str_1), exp_test_str_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('+', exp_test_str_1, exp_test_str_2), exp_test_str_3), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('+', exp_test_int_1, exp_test_float_1), exp_test_float_3), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('+', exp_test_int_1, exp_test_str_2), exp_test_str_3), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('+', exp_test_int_1, exp_test_str_0), exp_test_str_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('+', exp_test_float_3, exp_test_str_0), exp_test_str_2), NULL) == EXP_TRUE);

	// -
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('-', exp_test_int_1, exp_test_int_0), exp_test_int_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('-', exp_test_int_3, exp_test_int_1), exp_test_int_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('-', exp_test_float_1, exp_test_float_0), exp_test_float_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('-', exp_test_float_3, exp_test_float_1), exp_test_float_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('-', exp_test_float_3, exp_test_int_1), exp_test_float_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('-', exp_test_int_1, exp_test_float_1), exp_test_float_1), NULL) == EXP_TRUE);

	// *
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('*', exp_test_int_1, exp_test_int_0), exp_test_int_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('*', exp_test_int_2, exp_test_int_1), exp_test_int_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('*', exp_test_float_1, exp_test_float_0), exp_test_float_0), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('*', exp_test_float_2, exp_test_float_3), exp_test_float_3), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('*', exp_test_float_1, exp_test_int_2), exp_test_float_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('*', exp_test_int_1, exp_test_float_3), exp_test_float_3), NULL) == EXP_TRUE);

	// /
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('/', exp_test_int_2, exp_test_int_1), exp_test_int_2), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('/', exp_test_int_3, exp_test_int_2), exp_test_int_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('/', exp_test_float_3, exp_test_float_2), exp_test_float_3), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('/', exp_test_float_2, exp_test_int_2), exp_test_float_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('/', exp_test_float_3, exp_test_int_3), exp_test_float_1), NULL) == EXP_TRUE);
	TEST_ASSERT(exp_eval(exp_operation(EQ, exp_operation('/', exp_test_int_3, exp_test_float_3), exp_test_int_2), NULL) == EXP_TRUE);

	return;
}
Пример #11
0
var_t *
exp_eval_operation(exp_t *exp, var_t *mailspec)
{
	var_t *left = NULL, *right = NULL, *copy;
	exp_operation_t *eo = exp->ex_data;
	var_t *result = NULL;
	var_type_t type;

	/*
	 * Variable assigment
	 */
	if (eo->eo_operator == '=')
	{
		return exp_assign(eo->eo_operand[0], eo->eo_operand[1],
		    mailspec);
	}

	/*
	 * isset operator
	 */
	if (eo->eo_operator == IS_SET)
	{
		return exp_isset(mailspec, eo->eo_operand[0]);
	}

	/*
	 * Do not load unneccessary symbols in boolean operations
	 */
	if (eo->eo_operator == AND || eo->eo_operator == OR)
	{
		result = exp_bool(mailspec, eo->eo_operator, eo->eo_operand[0],
			eo->eo_operand[1]);
		goto exit;
	}

	/*
 	 * Load left operand
 	 */
	left = exp_eval(eo->eo_operand[0], mailspec);

	/*
	 * ! operator
	 */
	if (eo->eo_operator == '!')
	{
		return exp_not(left);
	}

	/*
	 * Hack: IS_NULL operator
	 */
	if (eo->eo_operator == IS_NULL)
	{
		result = exp_is_null(left);
		goto exit;
	}

	/*
 	 * Evaluate right operand
 	 */
	if (eo->eo_operand[1])
	{
		right = exp_eval(eo->eo_operand[1], mailspec);
	}

	switch(eo->eo_operator)
	{
	// Comparator
	case '<':
	case '>':
	case LE:
	case GE:
	case EQ:
	case NE:
		result = exp_compare(eo->eo_operator, left, right);
		goto exit;

	// Regex
	case '~':
	case NR:
		result = exp_eval_regex(eo->eo_operator, left, right);
		goto exit;

	// In
	case IN:
		result = exp_eval_in(left, right);
		goto exit;



	// Address prefix operator
	case '/':
		if (left == NULL || right == NULL)
		{
			break;
		}
		if (!(left->v_type == VT_ADDR && right->v_type == VT_INT))
		{
			break;
		}

		result = exp_addr_prefix(left, right);
		goto exit;

	default:
		break;
	}

	// Math operators need left and right to be set
	if (left == NULL || right ==  NULL)
	{
		result = EXP_EMPTY;
		goto exit;
	}

	// Make sure we work with the same types
	if (left->v_type != right->v_type)
	{
		/*
		 * The biggest type has precedence (see exp.h)
		 * STRING > FLOAT > INT
		 */
		type = VAR_MAX_TYPE(left, right);

		if (type == left->v_type)
		{
			copy = var_cast_copy(type, right);
		}
		else
		{
			copy = var_cast_copy(type, left);
		}

		if (copy == NULL)
		{
			log_error("exp_eval_operation: var_cast_copy "
			    "failed");
			goto exit;
		}

		if (type == left->v_type)
		{
			exp_free(right);
			right = copy;
			right->v_flags |= VF_EXP_FREE;
		}
		else
		{
			exp_free(left);
			left = copy;
			left->v_flags |= VF_EXP_FREE;
		}
	}

	switch (left->v_type)
	{
	case VT_INT:
		result = exp_math_int(eo->eo_operator, left, right);
		break;

	case VT_FLOAT:
		result = exp_math_float(eo->eo_operator, left, right);
		break;

	case VT_STRING:
		result = exp_math_string(eo->eo_operator, left, right);
		break;

	default:
		log_error("exp_eval_operation: bad type");
		goto exit;
	}

exit:
	if (left)
	{
		exp_free(left);
	}

	if (right)
	{
		exp_free(right);
	}

	return result;
}
Пример #12
0
acl_action_type_t
msgmod(milter_stage_t stage, char *stagename, var_t *mailspec, void *data,
	int depth)
{
	msgmod_t *mm = data;
	void *ctx;
	acl_action_type_t action = ACL_ERROR;
	var_t **args = NULL;
	int argc;
	int size;
	var_t *v, *copy;
	int i;
	exp_t *exp;
	ll_t *ll;
	ll_entry_t *pos;

	/*
	 * Get milter ctx pointer
	 */
	ctx = vtable_get(mailspec, "milter_ctx");
	if (ctx == NULL)
	{
		log_error("msgmod: ctx not set");
		goto error;
	}

	/*
	 * Evaluate arguments
	 */
	argc = mm->mm_args->ll_size;
	size = (argc + 1) * sizeof (var_t *);

	args = (var_t **) malloc(size);
	if (args == NULL)
	{
		log_sys_error("msgmod: malloc");
		goto error;
	}

	memset(args, 0, size);

	ll = mm->mm_args;
	pos = LL_START(ll);

	for (i = 0; i < argc; ++i)
	{
		exp = ll_next(ll, &pos);
		if (exp == NULL)
		{
			log_die(EX_SOFTWARE, "msgmod: empty argument");
		}

		v = exp_eval(exp, mailspec);
		if (v == NULL)
		{
			log_error("msgmod: exp_eval failed");
			goto error;
		}

		// Cast all aruments to VT_STRING
		if (v->v_type != VT_STRING)
		{
			copy = var_cast_copy(VT_STRING, v);
			if (copy == NULL)
			{
				log_error("msgmod: var_cast_copy failed");
				goto error;
			}

			exp_free(v);

			/*
			 * args are freed using exp_free. Set VF_EXP_FREE to
			 * free copy.
			 */
			copy->v_flags |= VF_EXP_FREE;
			
			v = copy;
		}
		
		args[i] = v;
	}

	if (mm->mm_callback(ctx, argc, args))
	{
		log_error("msgmod: mm_callback failed");
		goto error;
	}

	action = ACL_NONE;

error:

	/*
	 * Free args
	 */
	for (i = 0; args[i]; ++i)
	{
		exp_free(args[i]);
	}

	if (args)
	{
		free(args);
	}

	return action;
}