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 "log.h"
22 #include "zbxhttp.h"
23 
24 /******************************************************************************
25  *                                                                            *
26  * Function: zbx_http_url_encode                                              *
27  *                                                                            *
28  * Purpose: replaces unsafe characters with a '%' followed by two hexadecimal *
29  *          digits (the only allowed exception is a space character that can  *
30  *          be replaced with a plus (+) sign or with %20).to url encode       *
31  *                                                                            *
32  * Parameters:  source  - [IN] the value to encode                            *
33  *              result  - [OUT] encoded string                                *
34  *                                                                            *
35  ******************************************************************************/
zbx_http_url_encode(const char * source,char ** result)36 void	zbx_http_url_encode(const char *source, char **result)
37 {
38 	char		*target, *buffer;
39 	const char	*hex = "0123456789ABCDEF";
40 
41 	buffer = (char *)zbx_malloc(NULL, strlen(source) * 3 + 1);
42 	target = buffer;
43 
44 	while ('\0' != *source)
45 	{
46 		if (0 == isalnum(*source) && NULL == strchr("-._~", *source))
47 		{
48 			/* Percent-encoding */
49 			*target++ = '%';
50 			*target++ = hex[(unsigned char)*source >> 4];
51 			*target++ = hex[(unsigned char)*source & 15];
52 		}
53 		else
54 			*target++ = *source;
55 
56 		source++;
57 	}
58 
59 	*target = '\0';
60 	zbx_free(*result);
61 	*result = buffer;
62 }
63 
64 /******************************************************************************
65  *                                                                            *
66  * Function: zbx_http_url_decode                                              *
67  *                                                                            *
68  * Purpose: replaces URL escape sequences ('+' or '%' followed by two         *
69  *          hexadecimal digits) with matching characters.                     *
70  *                                                                            *
71  * Parameters:  source  - [IN] the value to decode                            *
72  *              result  - [OUT] decoded string                                *
73  *                                                                            *
74  * Return value: SUCCEED - the source string was decoded successfully         *
75  *               FAIL    - source string contains malformed percent-encoding  *
76  *                                                                            *
77  ******************************************************************************/
zbx_http_url_decode(const char * source,char ** result)78 int	zbx_http_url_decode(const char *source, char **result)
79 {
80 	const char	*url = source;
81 	char		*target, *buffer = (char *)zbx_malloc(NULL, strlen(source) + 1);
82 
83 	target = buffer;
84 
85 	while ('\0' != *source)
86 	{
87 		if ('%' == *source)
88 		{
89 			/* Percent-decoding */
90 			if (FAIL == is_hex_n_range(source + 1, 2, target, sizeof(char), 0, 0xff))
91 			{
92 				zabbix_log(LOG_LEVEL_WARNING, "cannot perform URL decode of '%s' part of string '%s'",
93 						source, url);
94 				zbx_free(buffer);
95 				break;
96 			}
97 			else
98 				source += 2;
99 		}
100 		else if ('+' == *source)
101 			*target = ' ';
102 		else
103 			*target = *source;
104 
105 		target++;
106 		source++;
107 	}
108 
109 	if (NULL != buffer)
110 	{
111 		*target = '\0';
112 		zbx_free(*result);
113 		*result = buffer;
114 
115 		return SUCCEED;
116 	}
117 
118 	return FAIL;
119 }
120