Skip to content

Commit

Permalink
..F.....S. [ZBX-21898] brings back changes in f011431 that added esca…
Browse files Browse the repository at this point in the history
…ping of backslashes in history function string parameters

This reverts commit c970b82.
  • Loading branch information
Konstantins Prutkovs committed Aug 14, 2023
1 parent bac1e59 commit 891bc28
Show file tree
Hide file tree
Showing 13 changed files with 610 additions and 45 deletions.
1 change: 1 addition & 0 deletions ChangeLog.d/bugfix/ZBX-21898
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
..F.....S. [ZBX-21898] added escaping of backslashes in history function string parameters (epulke, kprutkovs)
2 changes: 1 addition & 1 deletion create/src/schema.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2127,4 +2127,4 @@ TABLE|dbversion|dbversionid|
FIELD |dbversionid |t_id | |NOT NULL |0
FIELD |mandatory |t_integer |'0' |NOT NULL |
FIELD |optional |t_integer |'0' |NOT NULL |
ROW |1 |6050033 |6050033
ROW |1 |6050035 |6050035
3 changes: 3 additions & 0 deletions include/zbxeval.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ typedef int (*zbx_macro_expand_func_t)(void *data, char **str, const zbx_uint64_
char **error);

int zbx_eval_parse_expression(zbx_eval_context_t *ctx, const char *expression, zbx_uint64_t rules, char **error);
int zbx_eval_parse_expression_str_v64_compat(zbx_eval_context_t *ctx, const char *expression,
zbx_uint64_t rules, char **error);
void zbx_eval_init(zbx_eval_context_t *ctx);
void zbx_eval_clear(zbx_eval_context_t *ctx);
int zbx_eval_status(const zbx_eval_context_t *ctx);
Expand Down Expand Up @@ -253,6 +255,7 @@ char *zbx_eval_format_function_error(const char *function, const char *host, con
const char *parameter, const char *error);

void zbx_eval_extract_item_refs(zbx_eval_context_t *ctx, zbx_vector_str_t *refs);
int zbx_eval_compare_tokens_by_loc(const void *d1, const void *d2);

typedef struct
{
Expand Down
2 changes: 2 additions & 0 deletions include/zbxexpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ int zbx_function_find(const char *expr, size_t *func_pos, size_t *par_l, size_t
void zbx_function_param_parse(const char *expr, size_t *param_pos, size_t *length, size_t *sep_pos);
char *zbx_function_param_unquote_dyn(const char *param, size_t len, int *quoted);
int zbx_function_param_quote(char **param, int forced);
char *zbx_function_param_unescape_dyn(const char *param, size_t len, int *quoted);
int zbx_function_param_escape(char **param, int forced);
char *zbx_function_get_param_dyn(const char *params, int Nparam);

typedef enum
Expand Down
6 changes: 3 additions & 3 deletions src/libs/zbxcacheconfig/dbconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -14898,15 +14898,15 @@ char *zbx_dc_expand_user_macros_in_func_params(const char *params, zbx_uint64_t
for (ptr = params; ptr < params + params_len; ptr += sep_pos + 1)
{
size_t param_pos, param_len;
int quoted;
int escaped;
char *param;

zbx_function_param_parse(ptr, &param_pos, &param_len, &sep_pos);

param = zbx_function_param_unquote_dyn(ptr + param_pos, param_len, &quoted);
param = zbx_function_param_unescape_dyn(ptr + param_pos, param_len, &escaped);
(void)zbx_dc_expand_user_macros(um_handle, &param, &hostid, 1, NULL);

if (SUCCEED == zbx_function_param_quote(&param, quoted))
if (SUCCEED == zbx_function_param_escape(&param, escaped))
zbx_strcpy_alloc(&buf, &buf_alloc, &buf_offset, param);
else
zbx_strncpy_alloc(&buf, &buf_alloc, &buf_offset, ptr + param_pos, param_len);
Expand Down
197 changes: 197 additions & 0 deletions src/libs/zbxdbupgrade/dbupgrade_6050.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include "dbupgrade.h"

#include "zbxdbschema.h"
#include "zbxexpr.h"
#include "zbxeval.h"
#include "zbxalgo.h"
#include "zbxdbhigh.h"

/*
Expand Down Expand Up @@ -382,6 +385,198 @@ static int DBpatch_6050033(void)
return SUCCEED;
}

static char *fix_hist_param_escaping(const char *param, size_t left, size_t right)
{
size_t escaped_len = 0;
/* resulting string cannot be more than 2 times longer than original string */
char *escaped = zbx_malloc(NULL, 2 * (right - left + 1) * sizeof(char) + 1);

for (size_t i = left; i <= right; i++)
{
escaped[escaped_len++] = param[i];
if (i < right && '\\' == param[i] && '"' != param[i + 1])
escaped[escaped_len++] = '\\';
}
escaped[escaped_len++] = '\0';

return escaped;
}

static int DBpatch_6050034(void)
{
zbx_db_result_t result;
zbx_db_row_t row;
int ret = SUCCEED;
char *sql = NULL;
size_t sql_alloc = 0, sql_offset = 0;

zbx_db_begin_multiple_update(&sql, &sql_alloc, &sql_offset);

/* functions table contains history functions used in trigger expressions */
result = zbx_db_select("select functionid,parameter from functions where length(parameter) > 1");

while (SUCCEED == ret && NULL != (row = zbx_db_fetch(result)))
{
const char *ptr;
char *buf, *tmp, *param = NULL;
size_t param_pos, param_len, sep_pos, buf_alloc, buf_offset = 0;

buf_alloc = strlen(row[1]);
buf = zbx_malloc(NULL, buf_alloc);

for (ptr = row[1]; ptr < row[1] + strlen(row[1]); ptr += sep_pos + 1)
{
zbx_function_param_parse(ptr, &param_pos, &param_len, &sep_pos);

if (param_pos < sep_pos)
{
param = fix_hist_param_escaping(ptr, param_pos, sep_pos - 1);
zbx_strcpy_alloc(&buf, &buf_alloc, &buf_offset, param);
}

if (',' == ptr[sep_pos])
zbx_chrcpy_alloc(&buf, &buf_alloc, &buf_offset, ',');
zbx_free(param);
}

tmp = zbx_db_dyn_escape_string(buf);
zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
"update functions set parameter='%s' where functionid=%s;\n", tmp, row[0]);
zbx_free(tmp);
zbx_free(buf);

if (SUCCEED == ret)
ret = zbx_db_execute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
}

zbx_db_free_result(result);
zbx_db_end_multiple_update(&sql, &sql_alloc, &sql_offset);

if (SUCCEED == ret && 16 < sql_offset)
{
if (ZBX_DB_OK > zbx_db_execute("%s", sql))
ret = FAIL;
}

zbx_free(sql);

return ret;
}

typedef struct {
zbx_uint32_t op_num;
char is_hist;
} expr_fun_call;

ZBX_VECTOR_DECL(fun_stack, expr_fun_call)
ZBX_VECTOR_IMPL(fun_stack, expr_fun_call)

static int DBpatch_6050035(void)
{
int ret = SUCCEED;
zbx_eval_context_t ctx;
int token_num;
const zbx_eval_token_t *token;
zbx_vector_fun_stack_t fun_stack;
zbx_vector_ptr_t hist_param_tokens;
zbx_db_result_t result;
zbx_db_row_t row;
char *tmp, *substitute = NULL, *sql = NULL, *error = NULL;
size_t sql_alloc = 0, sql_offset = 0;

zbx_vector_fun_stack_create(&fun_stack);
zbx_vector_ptr_create(&hist_param_tokens);

zbx_db_begin_multiple_update(&sql, &sql_alloc, &sql_offset);

if (NULL == (result = zbx_db_select("select itemid,params from items where type = 15")))
goto clean;

while (NULL != (row = zbx_db_fetch(result)))
{
ret = zbx_eval_parse_expression_str_v64_compat(&ctx, row[1], ZBX_EVAL_PARSE_CALC_EXPRESSION, &error);
if (FAIL == ret)
{
zabbix_log(LOG_LEVEL_CRIT, "Failed to parse calculated item expression \"%s\" for"
" item with id %s, error: %s", row[1], row[0], error);
goto clean;
}
zbx_free(error);

zbx_vector_fun_stack_clear(&fun_stack);
zbx_vector_ptr_clear(&hist_param_tokens);
substitute = zbx_strdup(NULL, ctx.expression);

/* finding string parameters of history functions */
for (token_num = ctx.stack.values_num - 1; token_num >= 0; token_num--)
{
token = &ctx.stack.values[token_num];

if (0 < fun_stack.values_num) {
expr_fun_call *cur_call = &(fun_stack.values[fun_stack.values_num - 1]);

if (ZBX_EVAL_TOKEN_VAR_STR == token->type && cur_call->is_hist)
zbx_vector_ptr_append(&hist_param_tokens, (void *)token);

if (0 == --(cur_call->op_num))
fun_stack.values_num--;
}

if (0 < token->opt)
{
expr_fun_call call = {token->opt, ZBX_EVAL_TOKEN_HIST_FUNCTION == token->type};

zbx_vector_fun_stack_append(&fun_stack, call);
}
}

/* Substitution logic relies on replacing further-most tokens first */
zbx_vector_ptr_sort(&hist_param_tokens, zbx_eval_compare_tokens_by_loc);

/* adding necessary escaping to the the string parameters of history functions */
for (token_num = 0; token_num < hist_param_tokens.values_num; token_num++)
{
size_t right_pos;

token = hist_param_tokens.values[token_num];
right_pos = token->loc.r;
tmp = fix_hist_param_escaping(substitute, token->loc.l, right_pos);
zbx_replace_string(&substitute, token->loc.l, &right_pos, tmp);

zbx_free(tmp);
}

tmp = zbx_db_dyn_escape_string(substitute);
zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update items set params='%s' where itemid=%s;\n",
tmp, row[0]);
zbx_free(tmp);
zbx_free(substitute);
zbx_eval_clear(&ctx);

if (SUCCEED == ret)
ret = zbx_db_execute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
}

zbx_db_free_result(result);
zbx_db_end_multiple_update(&sql, &sql_alloc, &sql_offset);

if (SUCCEED == ret && 16 < sql_offset)
{
if (ZBX_DB_OK > zbx_db_execute("%s", sql))
ret = FAIL;
}

clean:
zbx_free(error);
zbx_free(substitute);

zbx_vector_fun_stack_destroy(&fun_stack);
zbx_vector_ptr_destroy(&hist_param_tokens);
zbx_free(sql);

return ret;
}

#endif

DBPATCH_START(6050)
Expand Down Expand Up @@ -422,5 +617,7 @@ DBPATCH_ADD(6050030, 0, 1)
DBPATCH_ADD(6050031, 0, 1)
DBPATCH_ADD(6050032, 0, 1)
DBPATCH_ADD(6050033, 0, 1)
DBPATCH_ADD(6050034, 0, 1)
DBPATCH_ADD(6050035, 0, 1)

DBPATCH_END()
6 changes: 3 additions & 3 deletions src/libs/zbxeval/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ void zbx_eval_deserialize(zbx_eval_context_t *ctx, const char *expression, zbx_u
}
}

static int compare_tokens_by_loc(const void *d1, const void *d2)
int zbx_eval_compare_tokens_by_loc(const void *d1, const void *d2)
{
const zbx_eval_token_t *t1 = *(const zbx_eval_token_t * const *)d1;
const zbx_eval_token_t *t2 = *(const zbx_eval_token_t * const *)d2;
Expand Down Expand Up @@ -370,7 +370,7 @@ void zbx_eval_compose_expression(const zbx_eval_context_t *ctx, char **expressio
zbx_vector_ptr_append(&tokens, &ctx->stack.values[i]);
}

zbx_vector_ptr_sort(&tokens, compare_tokens_by_loc);
zbx_vector_ptr_sort(&tokens, zbx_eval_compare_tokens_by_loc);

for (i = 0; i < tokens.values_num; i++)
{
Expand Down Expand Up @@ -786,7 +786,7 @@ void zbx_eval_get_functionids_ordered(zbx_eval_context_t *ctx, zbx_vector_uint64
zbx_vector_ptr_append(&tokens, &ctx->stack.values[i]);
}

zbx_vector_ptr_sort(&tokens, compare_tokens_by_loc);
zbx_vector_ptr_sort(&tokens, zbx_eval_compare_tokens_by_loc);

for (i = 0; i < tokens.values_num; i++)
{
Expand Down
Loading

0 comments on commit 891bc28

Please sign in to comment.