diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | include/zbxserver.h | 5 | ||||
-rw-r--r-- | src/libs/zbxcommon/str.c | 138 | ||||
-rw-r--r-- | src/libs/zbxeval/parse.c | 32 | ||||
-rw-r--r-- | src/libs/zbxserver/expression.c | 92 | ||||
-rwxr-xr-x | tests/libs/zbxeval/Makefile.am | 16 | ||||
-rw-r--r-- | tests/libs/zbxeval/zbx_eval_execute.yaml | 8 | ||||
-rwxr-xr-x | tests/libs/zbxeval/zbx_eval_get_constant.c (renamed from tests/libs/zbxserver/get_trigger_expression_constant.c) | 13 | ||||
-rwxr-xr-x | tests/libs/zbxeval/zbx_eval_get_constant.yaml (renamed from tests/libs/zbxserver/get_trigger_expression_constant.yaml) | 30 | ||||
-rw-r--r-- | tests/libs/zbxeval/zbx_eval_parse_expression.yaml | 28 | ||||
-rwxr-xr-x | tests/libs/zbxserver/Makefile.am | 13 |
11 files changed, 71 insertions, 306 deletions
diff --git a/.gitignore b/.gitignore index 3e6be4f67c3..65fd3df996f 100644 --- a/.gitignore +++ b/.gitignore @@ -166,6 +166,7 @@ tests/libs/zbxdbhigh/DBselect_uint64 tests/libs/zbxeval/zbx_eval_compose_expression tests/libs/zbxeval/zbx_eval_execute tests/libs/zbxeval/zbx_eval_execute_ext +tests/libs/zbxeval/zbx_eval_get_constant tests/libs/zbxeval/zbx_eval_parse_expression tests/libs/zbxeval/zbx_eval_serialize tests/libs/zbxhistory/zbx_history_get_values @@ -180,7 +181,6 @@ tests/libs/zbxprometheus/zbx_prometheus_pattern tests/libs/zbxprometheus/zbx_prometheus_to_json tests/libs/zbxregexp/wildcard_match tests/libs/zbxserver/evaluate_function -tests/libs/zbxserver/get_trigger_expression_constant tests/libs/zbxserver/macro_fmttime tests/libs/zbxserver/substitute_lld_macros tests/libs/zbxsysinfo/check_key_access_rules diff --git a/include/zbxserver.h b/include/zbxserver.h index 01106df4d78..4cd35535b11 100644 --- a/include/zbxserver.h +++ b/include/zbxserver.h @@ -58,8 +58,6 @@ #define STR_CONTAINS_MACROS(str) (NULL != strchr(str, '{')) -int get_N_functionid(const char *expression, int N_functionid, zbx_uint64_t *functionid, const char **end); - int evaluate_function(char **value, DC_ITEM *item, const char *function, const char *parameter, const zbx_timespec_t *ts, char **error); int evaluate_function2(zbx_variant_t *value, DC_ITEM *item, const char *function, const char *parameter, @@ -84,9 +82,6 @@ void zbx_format_value(char *value, size_t max_len, zbx_uint64_t valuemapid, void zbx_determine_items_in_expressions(zbx_vector_ptr_t *trigger_order, const zbx_uint64_t *itemids, int item_num); -void get_trigger_expression_constant(const char *expression, const zbx_token_reference_t *reference, - char **constant); - /* lld macro context */ #define ZBX_MACRO_ANY (ZBX_TOKEN_LLD_MACRO | ZBX_TOKEN_LLD_FUNC_MACRO | ZBX_TOKEN_USER_MACRO) #define ZBX_MACRO_NUMERIC (ZBX_MACRO_ANY | ZBX_TOKEN_NUMERIC) diff --git a/src/libs/zbxcommon/str.c b/src/libs/zbxcommon/str.c index c49203bb470..e177f06c33b 100644 --- a/src/libs/zbxcommon/str.c +++ b/src/libs/zbxcommon/str.c @@ -4691,144 +4691,6 @@ int zbx_suffixed_number_parse(const char *number, int *len) /****************************************************************************** * * - * Function: zbx_expression_next_constant * - * * - * Purpose: gets next constant (numeric/string value or unresolved user * - * macro) from trigger expression. * - * * - * Parameters: src - [IN] the expression * - * pos - [IN] the starting position * - * loc - [IN] the substring location * - * * - * Return value: SUCCEED - the next constant was located. * - * FAIL - otherwise. * - * * - ******************************************************************************/ -int zbx_expression_next_constant(const char *str, size_t pos, zbx_strloc_t *loc) -{ - const char *s; - zbx_token_t token; - int offset = 0, len; - - for (s = str + pos; '\0' != *s; s++) - { - switch (*s) - { - case '"': - loc->l = s - str; - - for (++s;'\0' != *s; s++) - { - if ('"' == *s) - { - loc->r = s - str; - return SUCCEED; - } - if ('\\' == *s) - { - if ('\\' != s[1] && '"' != s[1]) - return FAIL; - s++; - } - } - return FAIL; - case '{': - if (SUCCEED == zbx_token_find(str, s - str, &token, ZBX_TOKEN_SEARCH_BASIC)) - { - if (ZBX_TOKEN_USER_MACRO == token.type) - { - *loc = token.loc; - return SUCCEED; - } - /* Skip all other tokens. Currently it can be only {TRIGGER.VALUE} macro. */ - s = str + token.loc.r; - } - continue; - case '-': - offset = 1; - continue; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '.': - if (SUCCEED != zbx_suffixed_number_parse(s, &len)) - return FAIL; - - loc->l = s - str - offset; - loc->r = s - str + len - 1; - return SUCCEED; - default: - offset = 0; - } - } - return FAIL; -} - -/****************************************************************************** - * * - * Function: zbx_expression_extract_constant * - * * - * Purpose: extracts constant from trigger expression unquoting/escaping if * - * necessary * - * * - * Parameters: src - [IN] the source string * - * loc - [IN] the substring location * - * * - * Return value: The constant. * - * * - ******************************************************************************/ -char *zbx_expression_extract_constant(const char *src, const zbx_strloc_t *loc) -{ - char *str, *pout; - const char *pin; - size_t len; - - len = loc->r - loc->l + 1; - str = zbx_malloc(NULL, len + 1); - - if ('"' == src[loc->l]) - { - for (pout = str, pin = src + loc->l + 1; pin <= src + loc->r - 1; pin++) - { - if ('\\' == *pin) - { - pin++; - switch (*pin) - { - case '\\': - *pout++ = '\\'; - break; - case '"': - *pout++ = '"'; - break; - default: - THIS_SHOULD_NEVER_HAPPEN; - *pout++ = '?'; - } - } - else - *pout++ = *pin; - } - *pout++ ='\0'; - } - else - { - memcpy(str, src + loc->l, len); - str[len] = '\0'; - } - - return str; -} - -/****************************************************************************** - * * * Function: num_param * * * * Purpose: find number of parameters in parameter list * diff --git a/src/libs/zbxeval/parse.c b/src/libs/zbxeval/parse.c index f18f9044dd0..ae4793b4e6f 100644 --- a/src/libs/zbxeval/parse.c +++ b/src/libs/zbxeval/parse.c @@ -120,7 +120,6 @@ static int eval_parse_macro(zbx_eval_context_t *ctx, size_t pos, zbx_eval_token_ SUCCEED == zbx_token_parse_macro(ctx->expression, ctx->expression + pos, &tok)) { token->type = ZBX_EVAL_TOKEN_VAR_MACRO; - eval_update_const_variable(ctx, token); } else if (0 != (ctx->rules & ZBX_EVAL_PARSE_USERMACRO) && '$' == ctx->expression[pos + 1] && SUCCEED == zbx_token_parse_user_macro(ctx->expression, ctx->expression + pos, &tok)) @@ -298,7 +297,6 @@ static int eval_parse_string_token(zbx_eval_context_t *ctx, size_t pos, zbx_eval * Parameters: ctx - [IN] the evaluation context * * pos - [IN] the starting position * * token - [OUT] the parsed token * - * error - [OUT] the error message in the case of failure * * * * Return value: SUCCEED - token was parsed successfully * * FAIL - otherwise * @@ -306,14 +304,19 @@ static int eval_parse_string_token(zbx_eval_context_t *ctx, size_t pos, zbx_eval * Comments: Time suffixes s,m,h,d,w are supported. * * * ******************************************************************************/ -static int eval_parse_number_token(zbx_eval_context_t *ctx, size_t pos, zbx_eval_token_t *token, char **error) +static int eval_parse_number_token(zbx_eval_context_t *ctx, size_t pos, zbx_eval_token_t *token) { - int len; + int len, offset = 0; char *end; double tmp; - if (FAIL == zbx_suffixed_number_parse(ctx->expression + pos, &len)) - goto error; + if ('-' == ctx->expression[pos]) + offset++; + + if (FAIL == zbx_suffixed_number_parse(ctx->expression + pos + offset, &len)) + return FAIL; + + len += offset; switch (ctx->expression[pos + len - 1]) { @@ -331,16 +334,13 @@ static int eval_parse_number_token(zbx_eval_context_t *ctx, size_t pos, zbx_eval tmp = strtod(ctx->expression + pos, &end) * suffix2factor(ctx->expression[pos + len - 1]); if (HUGE_VAL == tmp || -HUGE_VAL == tmp || EDOM == errno) - goto error; + return FAIL; token->loc.l = pos; token->loc.r = pos + len - 1; eval_update_const_variable(ctx, token); return SUCCEED; -error: - *error = zbx_dsprintf(*error, "invalid numeric value at \"%s\"", ctx->expression + pos); - return FAIL; } /****************************************************************************** @@ -555,7 +555,10 @@ static int eval_parse_token(zbx_eval_context_t *ctx, size_t pos, zbx_eval_token_ return SUCCEED; case '-': if (0 == (ctx->last_token_type & ZBX_EVAL_CLASS_OPERAND)) - eval_parse_character_token(pos, ZBX_EVAL_TOKEN_OP_MINUS, token); + { + if (SUCCEED != eval_parse_number_token(ctx, pos, token)) + eval_parse_character_token(pos, ZBX_EVAL_TOKEN_OP_MINUS, token); + } else eval_parse_character_token(pos, ZBX_EVAL_TOKEN_OP_SUB, token); return SUCCEED; @@ -620,7 +623,12 @@ static int eval_parse_token(zbx_eval_context_t *ctx, size_t pos, zbx_eval_token_ } ZBX_FALLTHROUGH; case '.': - return eval_parse_number_token(ctx, pos, token, error); + if (FAIL == eval_parse_number_token(ctx, pos, token)) + { + *error = zbx_dsprintf(*error, "invalid numeric value at \"%s\"", ctx->expression + pos); + return FAIL; + } + return SUCCEED; case ',': if (0 != (ctx->rules & ZBX_EVAL_PARSE_FUNCTION)) { diff --git a/src/libs/zbxserver/expression.c b/src/libs/zbxserver/expression.c index 396f60f6f2c..e5d444bac49 100644 --- a/src/libs/zbxserver/expression.c +++ b/src/libs/zbxserver/expression.c @@ -81,98 +81,6 @@ static int substitute_key_macros_impl(char **data, zbx_uint64_t *hostid, DC_ITEM const struct zbx_json_parse *jp_row, const zbx_vector_ptr_t *lld_macro_paths, int macro_type, char *error, size_t maxerrlen); -/****************************************************************************** - * * - * Function: get_N_functionid * - * * - * Parameters: expression - [IN] null terminated trigger expression * - * '{11}=1 & {2346734}>5' * - * N_functionid - [IN] number of function in trigger expression * - * functionid - [OUT] ID of an N-th function in expression * - * end - [OUT] a pointer to text following the extracted * - * function id (can be NULL) * - * * - ******************************************************************************/ -int get_N_functionid(const char *expression, int N_functionid, zbx_uint64_t *functionid, const char **end) -{ - enum state_t {NORMAL, ID} state = NORMAL; - int num = 0, ret = FAIL; - const char *c, *p_functionid = NULL; - - for (c = expression; '\0' != *c; c++) - { - if ('{' == *c) - { - /* skip user macros */ - if ('$' == c[1]) - { - int macro_r, context_l, context_r; - - if (SUCCEED == zbx_user_macro_parse(c, ¯o_r, &context_l, &context_r, NULL)) - c += macro_r; - else - c++; - - continue; - } - - state = ID; - p_functionid = c + 1; - } - else if ('}' == *c && ID == state && NULL != p_functionid) - { - if (SUCCEED == is_uint64_n(p_functionid, c - p_functionid, functionid)) - { - if (++num == N_functionid) - { - if (NULL != end) - *end = c + 1; - - ret = SUCCEED; - break; - } - } - - state = NORMAL; - } - } - - return ret; -} - -/****************************************************************************** - * * - * Function: get_trigger_expression_constant * - * * - * Purpose: get constant from a trigger expression corresponding a given * - * reference from trigger name * - * * - * Parameters: expression - [IN] trigger expression, source of constants * - * reference - [IN] reference from a trigger name ($1, $2, ...) * - * constant - [OUT] the extracted constant or empty string, * - * must be freed by caller * - * * - ******************************************************************************/ -void get_trigger_expression_constant(const char *expression, const zbx_token_reference_t *reference, - char **constant) -{ - size_t pos; - zbx_strloc_t loc; - int index; - - for (pos = 0, index = 1; SUCCEED == zbx_expression_next_constant(expression, pos, &loc); - pos = loc.r + 1, index++) - { - if (index < reference->index) - continue; - - *constant = zbx_expression_extract_constant(expression, &loc); - return; - } - - *constant = zbx_strdup(*constant, ""); -} - static void DCexpand_trigger_expression(char **expression) { char *tmp = NULL; diff --git a/tests/libs/zbxeval/Makefile.am b/tests/libs/zbxeval/Makefile.am index 3369948da23..d4a487bba52 100755 --- a/tests/libs/zbxeval/Makefile.am +++ b/tests/libs/zbxeval/Makefile.am @@ -4,7 +4,8 @@ SERVER_tests = \ zbx_eval_serialize \ zbx_eval_compose_expression \ zbx_eval_execute \ - zbx_eval_execute_ext + zbx_eval_execute_ext \ + zbx_eval_get_constant endif noinst_PROGRAMS = $(SERVER_tests) @@ -153,5 +154,18 @@ zbx_eval_execute_ext_LDFLAGS = @SERVER_LDFLAGS@ zbx_eval_execute_ext_CFLAGS = $(COMMON_COMPILER_FLAGS) + +zbx_eval_get_constant_SOURCES = \ + zbx_eval_get_constant.c \ + mock_eval.c mock_eval.h + +zbx_eval_get_constant_LDADD = \ + $(COMMON_LIB_FILES) + +zbx_eval_get_constant_LDADD += @SERVER_LIBS@ + +zbx_eval_get_constant_LDFLAGS = @SERVER_LDFLAGS@ + +zbx_eval_get_constant_CFLAGS = $(COMMON_COMPILER_FLAGS) endif diff --git a/tests/libs/zbxeval/zbx_eval_execute.yaml b/tests/libs/zbxeval/zbx_eval_execute.yaml index bb9d6b0f5fd..88f9f4b6453 100644 --- a/tests/libs/zbxeval/zbx_eval_execute.yaml +++ b/tests/libs/zbxeval/zbx_eval_execute.yaml @@ -95,6 +95,14 @@ out: result: SUCCEED value: '-1' --- +test case: Expression '--1' +in: + rules: [] + expression: '--1' +out: + result: SUCCEED + value: '1' +--- test case: Expression '- "2"' in: rules: [] diff --git a/tests/libs/zbxserver/get_trigger_expression_constant.c b/tests/libs/zbxeval/zbx_eval_get_constant.c index 60b4efbc923..f7e9a3f576a 100755 --- a/tests/libs/zbxserver/get_trigger_expression_constant.c +++ b/tests/libs/zbxeval/zbx_eval_get_constant.c @@ -30,8 +30,8 @@ void zbx_mock_test_entry(void **state) zbx_mock_handle_t param_handle; zbx_uint64_t index = 0; const char *expected_result = NULL, *expression = NULL; - char *actual_result = NULL; - zbx_token_reference_t token; + char *actual_result = NULL, *errmsg = NULL; + zbx_eval_context_t ctx; ZBX_UNUSED(state); @@ -54,10 +54,15 @@ void zbx_mock_test_entry(void **state) zbx_mock_error_string(error)); } - token.index = index; - get_trigger_expression_constant(expression, &token, &actual_result); + if (SUCCEED != zbx_eval_parse_expression(&ctx, expression, ZBX_EVAL_TRIGGER_EXPRESSION, &errmsg)) + fail_msg("Cannot parse expression: %s", errmsg); + + zbx_eval_get_constant(&ctx, index, &actual_result); + if (NULL == actual_result) + actual_result = zbx_strdup(NULL, ""); zbx_mock_assert_str_eq("Invalid result", expected_result, actual_result); zbx_free(actual_result); + zbx_eval_clear(&ctx); } diff --git a/tests/libs/zbxserver/get_trigger_expression_constant.yaml b/tests/libs/zbxeval/zbx_eval_get_constant.yaml index bb0e052964c..fac9d242909 100755 --- a/tests/libs/zbxserver/get_trigger_expression_constant.yaml +++ b/tests/libs/zbxeval/zbx_eval_get_constant.yaml @@ -1,11 +1,4 @@ --- -test case: 'extract token 0' -in: - expression: '("ccc")="ccca"' - index: 0 -out: - return: 'ccc' ---- test case: 'extract token 1' in: expression: '("ccc")="ccca"' @@ -71,7 +64,7 @@ out: --- test case: 'escape function' in: - expression: '{0286} (0)<>("-2"/1 - {2370897})' + expression: '{0286} + (0)<>("-2"/1 - {2370897})' index: 1 out: return: '0' @@ -125,13 +118,6 @@ in: out: return: '{$MACRO:"x:\"1\""}' --- -test case: 'broken user macro with context' -in: - expression: '{19928}<>{$MACRO:"x:\"1} and 1' - index: 1 -out: - return: '' ---- test case: 'fraction' in: expression: '{19928}<>.5' @@ -146,13 +132,6 @@ in: out: return: '-.5' --- -test case: 'invalid number .5.5.5' -in: - expression: '{19928}<>.5.5.5' - index: 1 -out: - return: '' ---- test case: 'constant after macro' in: expression: '{TRIGGER.VALUE}=1 and {19928}<>10' @@ -174,13 +153,6 @@ in: out: return: '1e-5' --- -test case: 'constant 1e-5.0' -in: - expression: '{19928}=1e-5.0' - index: 1 -out: - return: '' ---- test case: 'string constant -10e-10' in: expression: '{TRIGGER.VALUE}=1 and {19928}<>"-10e-10"' diff --git a/tests/libs/zbxeval/zbx_eval_parse_expression.yaml b/tests/libs/zbxeval/zbx_eval_parse_expression.yaml index f374bdb9ea8..8f432686ca7 100644 --- a/tests/libs/zbxeval/zbx_eval_parse_expression.yaml +++ b/tests/libs/zbxeval/zbx_eval_parse_expression.yaml @@ -316,8 +316,7 @@ in: expression: '-1' out: stack: - - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '1', opt: 0} - - {type: ZBX_EVAL_TOKEN_OP_MINUS, token: '-', opt: 0} + - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '-1', opt: 0} result: SUCCEED --- test case: Succeed '-(1)' @@ -346,8 +345,7 @@ in: expression: '--1' out: stack: - - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '1', opt: 0} - - {type: ZBX_EVAL_TOKEN_OP_MINUS, token: '-', opt: 0} + - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '-1', opt: 0} - {type: ZBX_EVAL_TOKEN_OP_MINUS, token: '-', opt: 0} result: SUCCEED --- @@ -368,8 +366,7 @@ in: expression: '-(-1)' out: stack: - - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '1', opt: 0} - - {type: ZBX_EVAL_TOKEN_OP_MINUS, token: '-', opt: 0} + - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '-1', opt: 0} - {type: ZBX_EVAL_TOKEN_OP_MINUS, token: '-', opt: 0} result: SUCCEED --- # arithmetic operations @@ -515,8 +512,7 @@ in: out: stack: - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '2', opt: 0} - - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '1', opt: 0} - - {type: ZBX_EVAL_TOKEN_OP_MINUS, token: '-', opt: 0} + - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '-1', opt: 0} - {type: ZBX_EVAL_TOKEN_OP_SUB, token: '-', opt: 0} result: SUCCEED --- @@ -852,8 +848,7 @@ in: out: stack: - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '1', opt: 0} - - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '2', opt: 0} - - {type: ZBX_EVAL_TOKEN_OP_MINUS, token: '-', opt: 0} + - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '-2', opt: 0} - {type: ZBX_EVAL_TOKEN_OP_EQ, token: '=', opt: 0} result: SUCCEED --- # logical not @@ -957,7 +952,7 @@ out: - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '3', opt: 2} - {type: ZBX_EVAL_TOKEN_OP_MUL, token: '*', opt: 0} - {type: ZBX_EVAL_TOKEN_OP_ADD, token: '+', opt: 0} - - {type: ZBX_EVAL_TOKEN_VAR_MACRO, token: '{MACRO}', opt: 3} + - {type: ZBX_EVAL_TOKEN_VAR_MACRO, token: '{MACRO}', opt: 0} - {type: ZBX_EVAL_TOKEN_OP_SUB, token: '-', opt: 0} result: SUCCEED --- # logical and/or @@ -1379,4 +1374,15 @@ out: - {type: ZBX_EVAL_TOKEN_OP_ADD, token: '+', opt: 0} - {type: ZBX_EVAL_TOKEN_FUNCTION, token: 'min', opt: 2} result: SUCCEED +--- +test case: Succeed '1=-1' +in: + rules: [] + expression: '1=-1' +out: + stack: + - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '1', opt: 0} + - {type: ZBX_EVAL_TOKEN_VAR_NUM, token: '-1', opt: 0} + - {type: ZBX_EVAL_TOKEN_OP_EQ, token: '=', opt: 0} + result: SUCCEED ... diff --git a/tests/libs/zbxserver/Makefile.am b/tests/libs/zbxserver/Makefile.am index 2f0697d83e2..b4c9a175ce1 100755 --- a/tests/libs/zbxserver/Makefile.am +++ b/tests/libs/zbxserver/Makefile.am @@ -1,6 +1,5 @@ if SERVER SERVER_tests = \ - get_trigger_expression_constant \ evaluate_function \ substitute_lld_macros \ macro_fmttime @@ -84,18 +83,6 @@ COMMON_LIB_FILES = \ COMMON_COMPILER_FLAGS = -I@top_srcdir@/tests -get_trigger_expression_constant_SOURCES = \ - get_trigger_expression_constant.c - -get_trigger_expression_constant_LDADD = \ - $(COMMON_LIB_FILES) - -get_trigger_expression_constant_LDADD += @SERVER_LIBS@ - -get_trigger_expression_constant_LDFLAGS = @SERVER_LDFLAGS@ - -get_trigger_expression_constant_CFLAGS = $(COMMON_COMPILER_FLAGS) - substitute_lld_macros_SOURCES = \ substitute_lld_macros.c |