1 #include "uwsgi.h"
2 
uwsgi_str_split_nget(char * str,size_t len,char what,size_t pos,size_t * rlen)3 char *uwsgi_str_split_nget(char *str, size_t len, char what, size_t pos, size_t *rlen) {
4 	size_t i;
5 	size_t current = 0;
6 	char *choosen = str;
7 	size_t choosen_len = 0;
8 	*rlen = 0;
9 	for(i=0;i<len;i++) {
10 		if (!choosen) choosen = str + i;
11 		if (str[i] == what) {
12 			if (current == pos) {
13 				if (choosen_len == 0) return NULL;
14 				*rlen = choosen_len;
15 				return choosen;
16 			}
17 			current++;
18 			choosen = NULL;
19 			choosen_len = 0;
20 		}
21 		else {
22 			choosen_len ++;
23 		}
24 	}
25 
26 	if (current == pos) {
27 		if (choosen_len == 0) return NULL;
28 		*rlen = choosen_len;
29 		return choosen;
30 	}
31 
32 	return NULL;
33 }
34 
uwsgi_str_occurence(char * str,size_t len,char what)35 size_t uwsgi_str_occurence(char *str, size_t len, char what) {
36 	size_t count = 0;
37 	size_t i;
38 	for(i=0;i<len;i++) {
39 		if (str[i] == what) count++;
40 	}
41 	return count;
42 }
43 
44 // check if a string_list contains an item
uwsgi_string_list_has_item(struct uwsgi_string_list * list,char * key,size_t keylen)45 struct uwsgi_string_list *uwsgi_string_list_has_item(struct uwsgi_string_list *list, char *key, size_t keylen) {
46         struct uwsgi_string_list *usl = list;
47         while (usl) {
48                 if (keylen == usl->len) {
49                         if (!memcmp(key, usl->value, keylen)) {
50                                 return usl;
51                         }
52                 }
53                 usl = usl->next;
54         }
55         return NULL;
56 }
57 
58 // lower a string
uwsgi_lower(char * str,size_t size)59 char *uwsgi_lower(char *str, size_t size) {
60         size_t i;
61         for (i = 0; i < size; i++) {
62                 str[i] = tolower((int) str[i]);
63         }
64 
65         return str;
66 }
67 
68 // check if a string is contained in another one
uwsgi_str_contains(char * str,int slen,char what)69 char *uwsgi_str_contains(char *str, int slen, char what) {
70 
71         int i;
72         for (i = 0; i < slen; i++) {
73                 if (str[i] == what) {
74                         return str + i;
75                 }
76         }
77         return NULL;
78 }
79 
uwsgi_contains_n(char * s1,size_t s1_len,char * s2,size_t s2_len)80 int uwsgi_contains_n(char *s1, size_t s1_len, char *s2, size_t s2_len) {
81         size_t i;
82         char *ptr = s2;
83         for (i = 0; i < s1_len; i++) {
84                 if (s1[i] == *ptr) {
85                         ptr++;
86                         if (ptr == s2 + s2_len) {
87                                 return 1;
88                         }
89                 }
90                 else {
91                         ptr = s2;
92                 }
93         }
94         return 0;
95 }
96 
97 // fast compare 2 sized strings
uwsgi_strncmp(char * src,int slen,char * dst,int dlen)98 int uwsgi_strncmp(char *src, int slen, char *dst, int dlen) {
99 
100         if (slen != dlen)
101                 return 1;
102 
103         return memcmp(src, dst, dlen);
104 
105 }
106 
107 // fast compare 2 sized strings (case insensitive)
uwsgi_strnicmp(char * src,int slen,char * dst,int dlen)108 int uwsgi_strnicmp(char *src, int slen, char *dst, int dlen) {
109 
110         if (slen != dlen)
111                 return 1;
112 
113         return strncasecmp(src, dst, dlen);
114 
115 }
116 
117 // fast sized check of initial part of a string
uwsgi_starts_with(char * src,int slen,char * dst,int dlen)118 int uwsgi_starts_with(char *src, int slen, char *dst, int dlen) {
119 
120         if (slen < dlen)
121                 return -1;
122 
123         return memcmp(src, dst, dlen);
124 }
125 
126 
127 // unsized check
uwsgi_startswith(char * src,char * what,int wlen)128 int uwsgi_startswith(char *src, char *what, int wlen) {
129 
130         int i;
131 
132         for (i = 0; i < wlen; i++) {
133                 if (src[i] != what[i])
134                         return -1;
135         }
136 
137         return 0;
138 }
139 
140 // concatenate strings
uwsgi_concatn(int c,...)141 char *uwsgi_concatn(int c, ...) {
142 
143         va_list s;
144         char *item;
145         int j = c;
146         char *buf;
147         size_t len = 1;
148         size_t tlen = 1;
149 
150         va_start(s, c);
151         while (j > 0) {
152                 item = va_arg(s, char *);
153                 if (item == NULL) {
154                         break;
155                 }
156                 len += va_arg(s, int);
157                 j--;
158         }
159         va_end(s);
160 
161 
162         buf = uwsgi_malloc(len);
163         memset(buf, 0, len);
164 
165         j = c;
166 
167         len = 0;
168 
169         va_start(s, c);
170         while (j > 0) {
171                 item = va_arg(s, char *);
172                 if (item == NULL) {
173                         break;
174                 }
175                 tlen = va_arg(s, int);
176                 memcpy(buf + len, item, tlen);
177                 len += tlen;
178                 j--;
179         }
180         va_end(s);
181 
182 
183         return buf;
184 
185 }
186 
uwsgi_concat2(char * one,char * two)187 char *uwsgi_concat2(char *one, char *two) {
188 
189         char *buf;
190         size_t len = strlen(one) + strlen(two) + 1;
191 
192 
193         buf = uwsgi_malloc(len);
194         buf[len - 1] = 0;
195 
196         memcpy(buf, one, strlen(one));
197         memcpy(buf + strlen(one), two, strlen(two));
198 
199         return buf;
200 
201 }
202 
uwsgi_concat4(char * one,char * two,char * three,char * four)203 char *uwsgi_concat4(char *one, char *two, char *three, char *four) {
204 
205         char *buf;
206         size_t len = strlen(one) + strlen(two) + strlen(three) + strlen(four) + 1;
207 
208 
209         buf = uwsgi_malloc(len);
210         buf[len - 1] = 0;
211 
212         memcpy(buf, one, strlen(one));
213         memcpy(buf + strlen(one), two, strlen(two));
214         memcpy(buf + strlen(one) + strlen(two), three, strlen(three));
215         memcpy(buf + strlen(one) + strlen(two) + strlen(three), four, strlen(four));
216 
217         return buf;
218 
219 }
220 
221 
uwsgi_concat3(char * one,char * two,char * three)222 char *uwsgi_concat3(char *one, char *two, char *three) {
223 
224         char *buf;
225         size_t len = strlen(one) + strlen(two) + strlen(three) + 1;
226 
227 
228         buf = uwsgi_malloc(len);
229         buf[len - 1] = 0;
230 
231         memcpy(buf, one, strlen(one));
232         memcpy(buf + strlen(one), two, strlen(two));
233         memcpy(buf + strlen(one) + strlen(two), three, strlen(three));
234 
235         return buf;
236 
237 }
238 
uwsgi_concat2n(char * one,int s1,char * two,int s2)239 char *uwsgi_concat2n(char *one, int s1, char *two, int s2) {
240 
241         char *buf;
242         size_t len = s1 + s2 + 1;
243 
244 
245         buf = uwsgi_malloc(len);
246         buf[len - 1] = 0;
247 
248         memcpy(buf, one, s1);
249         memcpy(buf + s1, two, s2);
250 
251         return buf;
252 
253 }
254 
uwsgi_concat2nn(char * one,int s1,char * two,int s2,int * len)255 char *uwsgi_concat2nn(char *one, int s1, char *two, int s2, int *len) {
256 
257         char *buf;
258         *len = s1 + s2 + 1;
259 
260 
261         buf = uwsgi_malloc(*len);
262         buf[*len - 1] = 0;
263 
264         memcpy(buf, one, s1);
265         memcpy(buf + s1, two, s2);
266 
267         return buf;
268 
269 }
270 
271 
uwsgi_concat3n(char * one,int s1,char * two,int s2,char * three,int s3)272 char *uwsgi_concat3n(char *one, int s1, char *two, int s2, char *three, int s3) {
273 
274         char *buf;
275         size_t len = s1 + s2 + s3 + 1;
276 
277 
278         buf = uwsgi_malloc(len);
279         buf[len - 1] = 0;
280 
281         memcpy(buf, one, s1);
282         memcpy(buf + s1, two, s2);
283         memcpy(buf + s1 + s2, three, s3);
284 
285         return buf;
286 
287 }
288 
uwsgi_concat4n(char * one,int s1,char * two,int s2,char * three,int s3,char * four,int s4)289 char *uwsgi_concat4n(char *one, int s1, char *two, int s2, char *three, int s3, char *four, int s4) {
290 
291         char *buf;
292         size_t len = s1 + s2 + s3 + s4 + 1;
293 
294 
295         buf = uwsgi_malloc(len);
296         buf[len - 1] = 0;
297 
298         memcpy(buf, one, s1);
299         memcpy(buf + s1, two, s2);
300         memcpy(buf + s1 + s2, three, s3);
301         memcpy(buf + s1 + s2 + s3, four, s4);
302 
303         return buf;
304 
305 }
306 
307 // concat unsized strings
uwsgi_concat(int c,...)308 char *uwsgi_concat(int c, ...) {
309 
310         va_list s;
311         char *item;
312         size_t len = 1;
313         int j = c;
314         char *buf;
315 
316         va_start(s, c);
317         while (j > 0) {
318                 item = va_arg(s, char *);
319                 if (item == NULL) {
320                         break;
321                 }
322                 len += (int) strlen(item);
323                 j--;
324         }
325         va_end(s);
326 
327 
328         buf = uwsgi_malloc(len);
329         memset(buf, 0, len);
330 
331         j = c;
332 
333         len = 0;
334 
335         va_start(s, c);
336         while (j > 0) {
337                 item = va_arg(s, char *);
338                 if (item == NULL) {
339                         break;
340                 }
341                 memcpy(buf + len, item, strlen(item));
342                 len += strlen(item);
343                 j--;
344         }
345         va_end(s);
346 
347 
348         return buf;
349 
350 }
351 
uwsgi_strncopy(char * s,int len)352 char *uwsgi_strncopy(char *s, int len) {
353 
354         char *buf;
355 
356         buf = uwsgi_malloc(len + 1);
357         buf[len] = 0;
358 
359         memcpy(buf, s, len);
360 
361         return buf;
362 
363 }
364 
365 // this move a string back of one char and put a 0 at the end (used in uwsgi parsers for buffer reusing)
uwsgi_cheap_string(char * buf,int len)366 char *uwsgi_cheap_string(char *buf, int len) {
367 
368         int i;
369         char *cheap_buf = buf - 1;
370 
371 
372         for (i = 0; i < len; i++) {
373                 *cheap_buf++ = buf[i];
374         }
375 
376 
377         buf[len - 1] = 0;
378 
379         return buf - 1;
380 }
381 
382 /*
383 	status 0: append mode
384 	status 1: single quote found
385 	status 2: double quote found
386 	status 3: backslash found (on 0)
387 	status 4: backslash found (on 1)
388 	status 5: backslash found (on 2)
389 
390 */
uwsgi_split_quoted(char * what,size_t what_len,char * sep,size_t * rlen)391 char ** uwsgi_split_quoted(char *what, size_t what_len, char *sep, size_t *rlen) {
392 	size_t i;
393 	int status = 0;
394 	char *base = uwsgi_concat2n(what, what_len, "", 0);
395 	char *item = NULL;
396 	char *ptr = NULL;
397 	*rlen = 0;
398 	char **ret = (char **) uwsgi_malloc(sizeof(char *) * (what_len+1));
399 
400 	for(i=0;i<what_len;i++) {
401 		if (!item) {
402 			item = uwsgi_malloc((what_len - i)+1);
403 			ptr = item;
404 		}
405 
406 		if (status == 0) {
407 			if (base[i] == '\\') {
408 				status = 3;
409 			}
410 			else if (base[i] == '"') {
411 				status = 2;
412 			}
413 			else if (base[i] == '\'') {
414 				status = 1;
415 			}
416 			else if (strchr(sep, base[i])) {
417 				*ptr++= 0;
418 				ret[(*rlen)] = item; (*rlen)++;
419 				item = NULL;
420 			}
421 			else {
422 				*ptr++= base[i];
423 			}
424 			continue;
425 		}
426 
427 		// backslash
428 		if (status == 3) {
429 			*ptr++= base[i];
430 			status = 0;
431 			continue;
432 		}
433 
434 		// single quote
435 		if (status == 1) {
436 			if (base[i] == '\\') {
437 				status = 4;
438 			}
439 			else if (base[i] == '\'') {
440 				status = 0;
441 			}
442 			else {
443 				*ptr++= base[i];
444 			}
445 			continue;
446 		}
447 
448 		// double quote
449 		if (status == 2) {
450 			if (base[i] == '\\') {
451                                 status = 5;
452                         }
453                         else if (base[i] == '"') {
454                         	status = 0;
455                         }
456                         else {
457                                 *ptr++= base[i];
458                         }
459 			continue;
460 		}
461 
462 		// backslash single quote
463                 if (status == 4) {
464                         *ptr++= base[i];
465                         status = 1;
466 			continue;
467                 }
468 
469 		// backslash double quote
470                 if (status == 5) {
471                         *ptr++= base[i];
472                         status = 2;
473 			continue;
474                 }
475 	}
476 
477 	if (item) {
478 		*ptr++= 0;
479 		ret[(*rlen)] = item; (*rlen)++;
480 	}
481 
482 	free(base);
483 
484 	return ret;
485 }
486