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 }