1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 **/
19 
20 #include "common.h"
21 #include "zbxregexp.h"
22 #include "macrofunc.h"
23 
24 /******************************************************************************
25  *                                                                            *
26  * Function: macrofunc_regsub                                                 *
27  *                                                                            *
28  * Purpose: calculates regular expression substitution                        *
29  *                                                                            *
30  * Parameters: func - [IN] the function data                                  *
31  *             out  - [IN/OUT] the input/output value                         *
32  *                                                                            *
33  * Return value: SUCCEED - the function was calculated successfully.          *
34  *               FAIL    - the function calculation failed.                   *
35  *                                                                            *
36  ******************************************************************************/
macrofunc_regsub(char ** params,size_t nparam,char ** out)37 static int	macrofunc_regsub(char **params, size_t nparam, char **out)
38 {
39 	char	*value = NULL;
40 
41 	if (2 != nparam)
42 		return FAIL;
43 
44 	if (FAIL == zbx_regexp_sub(*out, params[0], params[1], &value))
45 		return FAIL;
46 
47 	if (NULL == value)
48 		value = zbx_strdup(NULL, "");
49 
50 	zbx_free(*out);
51 	*out = value;
52 
53 	return SUCCEED;
54 }
55 
56 /******************************************************************************
57  *                                                                            *
58  * Function: macrofunc_iregsub                                                *
59  *                                                                            *
60  * Purpose: calculates case insensitive regular expression substitution       *
61  *                                                                            *
62  * Parameters: func - [IN] the function data                                  *
63  *             out  - [IN/OUT] the input/output value                         *
64  *                                                                            *
65  * Return value: SUCCEED - the function was calculated successfully.          *
66  *               FAIL    - the function calculation failed.                   *
67  *                                                                            *
68  ******************************************************************************/
macrofunc_iregsub(char ** params,size_t nparam,char ** out)69 static int	macrofunc_iregsub(char **params, size_t nparam, char **out)
70 {
71 	char	*value = NULL;
72 
73 	if (2 != nparam)
74 		return FAIL;
75 
76 	if (FAIL == zbx_iregexp_sub(*out, params[0], params[1], &value))
77 		return FAIL;
78 
79 	if (NULL == value)
80 		value = zbx_strdup(NULL, "");
81 
82 	zbx_free(*out);
83 	*out = value;
84 
85 	return SUCCEED;
86 }
87 
88 /******************************************************************************
89  *                                                                            *
90  * Function: zbx_calculate_macro_function                                     *
91  *                                                                            *
92  * Purpose: calculates macro function value                                   *
93  *                                                                            *
94  * Parameters: expression - [IN] expression containing macro function         *
95  *             func_macro - [IN] information about macro function token       *
96  *             out        - [IN/OUT] the input/output value                   *
97  *                                                                            *
98  * Return value: SUCCEED - the function was calculated successfully.          *
99  *               FAIL    - the function calculation failed.                   *
100  *                                                                            *
101  ******************************************************************************/
zbx_calculate_macro_function(const char * expression,const zbx_token_func_macro_t * func_macro,char ** out)102 int	zbx_calculate_macro_function(const char *expression, const zbx_token_func_macro_t *func_macro, char **out)
103 {
104 	char			**params, *buf = NULL;
105 	const char		*ptr;
106 	size_t			nparam = 0, param_alloc = 8, buf_alloc = 0, buf_offset = 0, len, sep_pos;
107 	int			(*macrofunc)(char **params, size_t nparam, char **out), ret;
108 
109 	ptr = expression + func_macro->func.l;
110 	len = func_macro->func_param.l - func_macro->func.l;
111 
112 	if (ZBX_CONST_STRLEN("regsub") == len && 0 == strncmp(ptr, "regsub", len))
113 		macrofunc = macrofunc_regsub;
114 	else if (ZBX_CONST_STRLEN("iregsub") == len && 0 == strncmp(ptr, "iregsub", len))
115 		macrofunc = macrofunc_iregsub;
116 	else
117 		return FAIL;
118 
119 	zbx_strncpy_alloc(&buf, &buf_alloc, &buf_offset, expression + func_macro->func_param.l + 1,
120 			func_macro->func_param.r - func_macro->func_param.l - 1);
121 	params = (char **)zbx_malloc(NULL, sizeof(char *) * param_alloc);
122 
123 	for (ptr = buf; ptr < buf + buf_offset; ptr += sep_pos + 1)
124 	{
125 		size_t	param_pos, param_len;
126 		int	quoted;
127 
128 		if (nparam == param_alloc)
129 		{
130 			param_alloc *= 2;
131 			params = (char **)zbx_realloc(params, sizeof(char *) * param_alloc);
132 		}
133 
134 		zbx_function_param_parse(ptr, &param_pos, &param_len, &sep_pos);
135 		params[nparam++] = zbx_function_param_unquote_dyn(ptr + param_pos, param_len, &quoted);
136 	}
137 
138 	ret = macrofunc(params, nparam, out);
139 
140 	while (0 < nparam--)
141 		zbx_free(params[nparam]);
142 
143 	zbx_free(params);
144 	zbx_free(buf);
145 
146 	return ret;
147 }
148 
149