summaryrefslogtreecommitdiff
path: root/xs_url.h
diff options
context:
space:
mode:
authorGravatar shtrophic2025-02-15 14:37:36 +0100
committerGravatar shtrophic2025-02-15 14:37:36 +0100
commit7611a6bee4bcbad2f1710aafa99aba730e5cf995 (patch)
tree33ab7bee30379e16f6869b2efda5494be8aeb858 /xs_url.h
parentenforce tls when supported && add tests (diff)
parentVersion 2.72 RELEASED. (diff)
downloadsnac2-7611a6bee4bcbad2f1710aafa99aba730e5cf995.tar.gz
snac2-7611a6bee4bcbad2f1710aafa99aba730e5cf995.tar.xz
snac2-7611a6bee4bcbad2f1710aafa99aba730e5cf995.zip
Merge tag '2.72' into curl-smtp
Version 2.72 RELEASED.
Diffstat (limited to 'xs_url.h')
-rw-r--r--xs_url.h117
1 files changed, 80 insertions, 37 deletions
diff --git a/xs_url.h b/xs_url.h
index 3c24736..37d2391 100644
--- a/xs_url.h
+++ b/xs_url.h
@@ -11,18 +11,57 @@ xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *hea
11 11
12#ifdef XS_IMPLEMENTATION 12#ifdef XS_IMPLEMENTATION
13 13
14char *xs_url_dec_in(char *str, int qs)
15{
16 char *w = str;
17 char *r;
18
19 for (r = str; *r != '\0'; r++) {
20 switch (*r) {
21 case '%': {
22 unsigned hex;
23 if (!r[1] || !r[2])
24 return NULL;
25 if (sscanf(r + 1, "%2x", &hex) != 1)
26 return NULL;
27 *w++ = hex;
28 r += 2;
29 break;
30 }
31
32 case '+':
33 if (qs) {
34 *w++ = ' ';
35 break;
36 }
37 /* fall-through */
38 default:
39 *w++ = *r;
40 }
41 }
42
43 *w++ = '\0';
44 return str;
45}
46
14xs_str *xs_url_dec(const char *str) 47xs_str *xs_url_dec(const char *str)
15/* decodes an URL */ 48/* decodes an URL */
16{ 49{
17 xs_str *s = xs_str_new(NULL); 50 xs_str *s = xs_str_new(NULL);
18 51
19 while (*str) { 52 while (*str) {
53 if (!xs_is_string(str))
54 break;
55
20 if (*str == '%') { 56 if (*str == '%') {
21 unsigned int i; 57 unsigned int i;
22 58
23 if (sscanf(str + 1, "%02x", &i) == 1) { 59 if (sscanf(str + 1, "%02x", &i) == 1) {
24 unsigned char uc = i; 60 unsigned char uc = i;
25 61
62 if (!xs_is_string((char *)&uc))
63 break;
64
26 s = xs_append_m(s, (char *)&uc, 1); 65 s = xs_append_m(s, (char *)&uc, 1);
27 str += 2; 66 str += 2;
28 } 67 }
@@ -69,43 +108,45 @@ xs_dict *xs_url_vars(const char *str)
69 108
70 vars = xs_dict_new(); 109 vars = xs_dict_new();
71 110
72 if (str != NULL) { 111 if (xs_is_string(str)) {
73 /* split by arguments */ 112 xs *dup = xs_dup(str);
74 xs *args = xs_split(str, "&"); 113 char *k;
75 114 char *saveptr;
76 const xs_val *v; 115 for (k = strtok_r(dup, "&", &saveptr);
77 116 k;
78 xs_list_foreach(args, v) { 117 k = strtok_r(NULL, "&", &saveptr)) {
79 xs *dv = xs_url_dec(v); 118 char *v = strchr(k, '=');
80 xs *kv = xs_split_n(dv, "=", 1); 119 if (!v)
81 120 continue;
82 if (xs_list_len(kv) == 2) { 121 *v++ = '\0';
83 const char *key = xs_list_get(kv, 0); 122 k = xs_url_dec_in(k, 1);
84 const char *pv = xs_dict_get(vars, key); 123 v = xs_url_dec_in(v, 1);
85 124 if (!xs_is_string(k) || !xs_is_string(v))
86 if (!xs_is_null(pv)) { 125 continue;
87 /* there is a previous value: convert to a list and append */ 126
88 xs *vlist = NULL; 127 const char *pv = xs_dict_get(vars, k);
89 if (xs_type(pv) == XSTYPE_LIST) 128 if (!xs_is_null(pv)) {
90 vlist = xs_dup(pv); 129 /* there is a previous value: convert to a list and append */
91 else { 130 xs *vlist = NULL;
92 vlist = xs_list_new(); 131 if (xs_type(pv) == XSTYPE_LIST)
93 vlist = xs_list_append(vlist, pv); 132 vlist = xs_dup(pv);
94 }
95
96 vlist = xs_list_append(vlist, xs_list_get(kv, 1));
97 vars = xs_dict_set(vars, key, vlist);
98 }
99 else { 133 else {
100 /* ends with []? force to always be a list */ 134 vlist = xs_list_new();
101 if (xs_endswith(key, "[]")) { 135 vlist = xs_list_append(vlist, pv);
102 xs *vlist = xs_list_new(); 136 }
103 vlist = xs_list_append(vlist, xs_list_get(kv, 1)); 137
104 vars = xs_dict_append(vars, key, vlist); 138 vlist = xs_list_append(vlist, v);
105 } 139 vars = xs_dict_set(vars, k, vlist);
106 else 140 }
107 vars = xs_dict_append(vars, key, xs_list_get(kv, 1)); 141 else {
142 /* ends with []? force to always be a list */
143 if (xs_endswith(k, "[]")) {
144 xs *vlist = xs_list_new();
145 vlist = xs_list_append(vlist, v);
146 vars = xs_dict_append(vars, k, vlist);
108 } 147 }
148 else
149 vars = xs_dict_append(vars, k, v);
109 } 150 }
110 } 151 }
111 } 152 }
@@ -233,7 +274,8 @@ xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *hea
233 l1 = xs_list_append(l1, vpo); 274 l1 = xs_list_append(l1, vpo);
234 l1 = xs_list_append(l1, vps); 275 l1 = xs_list_append(l1, vps);
235 276
236 p_vars = xs_dict_append(p_vars, vn, l1); 277 if (xs_is_string(vn))
278 p_vars = xs_dict_append(p_vars, vn, l1);
237 } 279 }
238 else { 280 else {
239 /* regular variable; just copy */ 281 /* regular variable; just copy */
@@ -241,7 +283,8 @@ xs_dict *xs_multipart_form_data(const char *payload, int p_size, const char *hea
241 memcpy(vc, payload + po, ps); 283 memcpy(vc, payload + po, ps);
242 vc[ps] = '\0'; 284 vc[ps] = '\0';
243 285
244 p_vars = xs_dict_append(p_vars, vn, vc); 286 if (xs_is_string(vn) && xs_is_string(vc))
287 p_vars = xs_dict_append(p_vars, vn, vc);
245 } 288 }
246 289
247 /* move on */ 290 /* move on */