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