1 /*
2  * pv_headers
3  *
4  * Copyright (C)
5  * 2020 Victor Seva <vseva@sipwise.com>
6  * 2018 Kirill Solomko <ksolomko@sipwise.com>
7  *
8  * This file is part of Kamailio, a free SIP server.
9  *
10  * Kamailio is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * Kamailio is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23  *
24  */
25 
26 #include "pvh_str.h"
27 
pvh_str_new(str * s,int size)28 int pvh_str_new(str *s, int size)
29 {
30 	s->s = (char *)pkg_malloc(size);
31 	if(s->s == NULL) {
32 		PKG_MEM_ERROR;
33 		return -1;
34 	}
35 	memset(s->s, 0, size);
36 	s->len = 0;
37 
38 	return 1;
39 }
40 
pvh_str_free(str * s)41 int pvh_str_free(str *s)
42 {
43 	if(s->s)
44 		pkg_free(s->s);
45 	s->s = NULL;
46 	return 1;
47 }
48 
pvh_str_copy(str * dst,str * src,unsigned int max_size)49 int pvh_str_copy(str *dst, str *src, unsigned int max_size)
50 {
51 	unsigned int src_len = src->len + 1 >= max_size ? max_size - 1 : src->len;
52 
53 	if(src == NULL || dst == NULL || src->len <= 0)
54 		return -1;
55 
56 	memset(dst->s, 0, dst->len);
57 	memcpy(dst->s, src->s, src_len);
58 	dst->s[src_len] = '\0';
59 	dst->len = src_len;
60 
61 	return 1;
62 }
63 
pvh_extract_display_uri(char * suri,str * display,str * duri)64 int pvh_extract_display_uri(char *suri, str *display, str *duri)
65 {
66 	char *ptr_a = NULL;
67 	char *ptr_b = NULL;
68 	int display_len = 0;
69 	int uri_len = 0;
70 
71 	if(suri == NULL || strlen(suri) == 0)
72 		return -1;
73 
74 	ptr_a = strchr(suri, '<');
75 	ptr_b = strchr(suri, '>');
76 
77 	if(ptr_a == NULL && ptr_b == NULL) {
78 		ptr_a = suri;
79 		uri_len = strlen(suri);
80 	} else if(ptr_a == NULL || ptr_b == NULL) {
81 		return -1;
82 	} else {
83 		display_len = ptr_a - suri;
84 		ptr_a++;
85 		uri_len = ptr_b - ptr_a;
86 	}
87 
88 	if(uri_len <= 0)
89 		return -1;
90 
91 	if(display_len > 0) {
92 		memcpy(display->s, suri, display_len);
93 		display->len = strlen(display->s);
94 		display->s[display->len] = '\0';
95 	} else {
96 		display->len = 0;
97 	}
98 
99 	memcpy(duri->s, ptr_a, uri_len);
100 	duri->len = strlen(duri->s);
101 	duri->s[duri->len] = '\0';
102 
103 	return 1;
104 }
105 
pvh_detect_split_char(char * val)106 char *pvh_detect_split_char(char *val)
107 {
108 	char *quote_a = NULL, *quote_b = NULL;
109 	char *split = NULL;
110 
111 	if(val == NULL)
112 		return NULL;
113 
114 	split = strchr(val, ',');
115 	if(split == NULL) {
116 		LM_DBG("no split marker detected\n");
117 		return NULL;
118 	}
119 
120 	quote_a = strchr(val, '"');
121 	if(quote_a == NULL || split < quote_a) {
122 		LM_DBG("split marker detected[%ld], not between quotes\n", split - val);
123 		return split;
124 	}
125 
126 	quote_b = strchr(val + (split - quote_a + 1), '"');
127 	if(quote_b == NULL) {
128 		LM_DBG("split marker detected[%ld], quote occurrence unbalanced[%ld]\n",
129 				split - val, quote_b - val);
130 		return split;
131 	}
132 	return pvh_detect_split_char(val + (quote_b - val + 1));
133 }
134 
pvh_split_values(str * s,char d[][header_value_size],int * d_size,int keep_spaces,char * marker)135 int pvh_split_values(str *s, char d[][header_value_size], int *d_size,
136 		int keep_spaces, char *marker)
137 {
138 	char *p = NULL;
139 	int idx = 0, c_idx = 0;
140 
141 	*d_size = -1;
142 
143 	if(s == NULL || s->len == 0 || d == NULL) {
144 		*d_size = 0;
145 		return 1;
146 	}
147 	if(!marker)
148 		marker = pvh_detect_split_char(s->s);
149 	while(idx < s->len) {
150 		p = s->s + idx++;
151 		if(keep_spaces == 0 && strncmp(p, " ", 1) == 0)
152 			continue;
153 		if(p == marker) {
154 			if(marker && idx < s->len) {
155 				LM_DBG("search next split marker[%d]\n", idx);
156 				marker = pvh_detect_split_char(p + 1);
157 			}
158 			if(c_idx == 0)
159 				continue;
160 			if(c_idx + 1 < header_value_size)
161 				c_idx++;
162 			d[*d_size][c_idx] = '\0';
163 			c_idx = 0;
164 			continue;
165 		}
166 		if(c_idx == 0)
167 			(*d_size)++;
168 		strncpy(&d[*d_size][c_idx++], p, 1);
169 	}
170 
171 	if(c_idx > 0) {
172 		if(c_idx >= header_value_size)
173 			c_idx--;
174 		d[*d_size][c_idx] = '\0';
175 	}
176 
177 	(*d_size)++;
178 
179 	return 1;
180 }