]> granicus.if.org Git - apache/blob - server/apreq_param.c
Add compiled and loaded PCRE version numbers
[apache] / server / apreq_param.c
1 /*
2 **  Licensed to the Apache Software Foundation (ASF) under one or more
3 ** contributor license agreements.  See the NOTICE file distributed with
4 ** this work for additional information regarding copyright ownership.
5 ** The ASF licenses this file to You under the Apache License, Version 2.0
6 ** (the "License"); you may not use this file except in compliance with
7 ** the License.  You may obtain a copy of the License at
8 **
9 **      http://www.apache.org/licenses/LICENSE-2.0
10 **
11 **  Unless required by applicable law or agreed to in writing, software
12 **  distributed under the License is distributed on an "AS IS" BASIS,
13 **  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 **  See the License for the specific language governing permissions and
15 **  limitations under the License.
16 */
17
18 #include "apreq_param.h"
19 #include "apreq_error.h"
20 #include "apreq_util.h"
21 #include "apr_strings.h"
22 #include "apr_lib.h"
23
24 #define MAX_LEN         (1024 * 1024)
25 #define MAX_BRIGADE_LEN (1024 * 256)
26 #define MAX_READ_AHEAD  (1024 * 64)
27
28
29 APREQ_DECLARE(apreq_param_t *) apreq_param_make(apr_pool_t *p,
30                                                 const char *name,
31                                                 const apr_size_t nlen,
32                                                 const char *val,
33                                                 const apr_size_t vlen)
34 {
35     apreq_param_t *param;
36     apreq_value_t *v;
37
38     param = apr_palloc(p, nlen + vlen + 1 + sizeof *param);
39
40     if (param == NULL)
41         return NULL;
42
43     param->info = NULL;
44     param->upload = NULL;
45     param->flags = 0;
46
47     *(const apreq_value_t **)&v = &param->v;
48
49     if (vlen && val != NULL)
50         memcpy(v->data, val, vlen);
51     v->data[vlen] = 0;
52     v->dlen = vlen;
53
54     v->name = v->data + vlen + 1;
55     if (nlen && name != NULL)
56         memcpy(v->name, name, nlen);
57     v->name[nlen] = 0;
58     v->nlen = nlen;
59
60     return param;
61 }
62
63 APREQ_DECLARE(apr_status_t) apreq_param_decode(apreq_param_t **param,
64                                                apr_pool_t *pool,
65                                                const char *word,
66                                                apr_size_t nlen,
67                                                apr_size_t vlen)
68 {
69     apr_status_t status;
70     apreq_value_t *v;
71     apreq_param_t *p;
72     apreq_charset_t charset;
73
74     if (nlen == 0) {
75         *param = NULL;
76         return APR_EBADARG;
77     }
78
79     p = apr_palloc(pool, nlen + vlen + 1 + sizeof *p);
80     p->info = NULL;
81     p->upload = NULL;
82     p->flags = 0;
83     *(const apreq_value_t **)&v = &p->v;
84
85     if (vlen > 0) {
86         status = apreq_decode(v->data, &v->dlen, word + nlen + 1, vlen);
87         if (status != APR_SUCCESS) {
88             *param = NULL;
89             return status;
90         }
91         charset = apreq_charset_divine(v->data, v->dlen);
92     }
93     else {
94         v->data[0] = 0;
95         v->dlen = 0;
96         charset = APREQ_CHARSET_ASCII;
97     }
98     v->name = v->data + vlen + 1;
99
100     status = apreq_decode(v->name, &v->nlen, word, nlen);
101     if (status != APR_SUCCESS) {
102         *param = NULL;
103         return status;
104     }
105
106     switch (apreq_charset_divine(v->name, v->nlen)) {
107     case APREQ_CHARSET_UTF8:
108         if (charset == APREQ_CHARSET_ASCII)
109             charset = APREQ_CHARSET_UTF8;
110     case APREQ_CHARSET_ASCII:
111         break;
112
113     case APREQ_CHARSET_LATIN1:
114         if (charset != APREQ_CHARSET_CP1252)
115             charset = APREQ_CHARSET_LATIN1;
116         break;
117     case APREQ_CHARSET_CP1252:
118         charset = APREQ_CHARSET_CP1252;
119     }
120
121     apreq_param_charset_set(p, charset);
122     *param = p;
123
124     return APR_SUCCESS;
125 }
126
127
128 APREQ_DECLARE(char *) apreq_param_encode(apr_pool_t *pool,
129                                          const apreq_param_t *param)
130 {
131     apr_size_t dlen;
132     char *data;
133     data = apr_palloc(pool, 3 * (param->v.nlen + param->v.dlen) + 2);
134     dlen = apreq_encode(data, param->v.name, param->v.nlen);
135     data[dlen++] = '=';
136     dlen += apreq_encode(data + dlen, param->v.data, param->v.dlen);
137
138     return data;
139 }
140
141 APREQ_DECLARE(apr_status_t) apreq_parse_query_string(apr_pool_t *pool,
142                                                      apr_table_t *t,
143                                                      const char *qs)
144 {
145     const char *start = qs;
146     apr_size_t nlen = 0;
147
148     for (;;++qs) {
149         switch (*qs) {
150
151         case '=':
152             if (nlen == 0) {
153                 nlen = qs - start;
154             }
155             break;
156
157         case '&':
158         case ';':
159         case 0:
160             if (qs > start) {
161                 apr_size_t vlen = 0;
162                 apreq_param_t *param;
163                 apr_status_t s;
164                 if (nlen == 0)
165                     nlen = qs - start;
166                 else
167                     vlen = qs - start - nlen - 1;
168
169                 s = apreq_param_decode(&param, pool, start, nlen, vlen);
170                 if (s != APR_SUCCESS)
171                     return s;
172
173                 apreq_param_tainted_on(param);
174                 apreq_value_table_add(&param->v, t);
175             }
176
177             if (*qs == 0)
178                 return APR_SUCCESS;
179
180             nlen = 0;
181             start = qs + 1;
182         }
183     }
184     /* not reached */
185     return APR_INCOMPLETE;
186 }
187
188
189
190
191 static int param_push(void *data, const char *key, const char *val)
192 {
193     apr_array_header_t *arr = data;
194     *(apreq_param_t **)apr_array_push(arr) =
195         apreq_value_to_param(val);
196     return 1;   /* keep going */
197 }
198
199
200 APREQ_DECLARE(apr_array_header_t *) apreq_params_as_array(apr_pool_t *p,
201                                                           const apr_table_t *t,
202                                                           const char *key)
203 {
204     apr_array_header_t *arr;
205
206     arr = apr_array_make(p, apr_table_elts(t)->nelts,
207                          sizeof(apreq_param_t *));
208
209     apr_table_do(param_push, arr, t, key, NULL);
210     return arr;
211 }
212
213 APREQ_DECLARE(const char *) apreq_params_as_string(apr_pool_t *p,
214                                                    const apr_table_t *t,
215                                                    const char *key,
216                                                    apreq_join_t mode)
217 {
218     apr_array_header_t *arr = apreq_params_as_array(p, t, key);
219     apreq_param_t **elt = (apreq_param_t **)arr->elts;
220     apreq_param_t **const end = elt + arr->nelts;
221     if (arr->nelts == 0)
222         return apr_pstrdup(p, "");
223
224     while (elt < end) {
225         *(const apreq_value_t **)elt = &(**elt).v;
226         ++elt;
227     }
228     return apreq_join(p, ", ", arr, mode);
229 }
230
231
232
233 static int upload_push(void *data, const char *key, const char *val)
234 {
235     apr_table_t *t = data;
236     apreq_param_t *p = apreq_value_to_param(val);
237
238     if (p->upload != NULL)
239         apreq_value_table_add(&p->v, t);
240     return 1;   /* keep going */
241 }
242
243
244 APREQ_DECLARE(const apr_table_t *) apreq_uploads(const apr_table_t *body,
245                                                  apr_pool_t *pool)
246 {
247     apr_table_t *t = apr_table_make(pool, APREQ_DEFAULT_NELTS);
248     apr_table_do(upload_push, t, body, NULL);
249     return t;
250 }
251
252 static int upload_set(void *data, const char *key, const char *val)
253 {
254     const apreq_param_t **q = data;
255     apreq_param_t *p = apreq_value_to_param(val);
256
257     if (p->upload != NULL) {
258         *q = p;
259         return 0; /* upload found, stop */
260     }
261     else
262         return 1; /* keep searching */
263 }
264
265
266 APREQ_DECLARE(const apreq_param_t *) apreq_upload(const apr_table_t *body,
267                                                   const char *name)
268 {
269     apreq_param_t *param = NULL;
270     apr_table_do(upload_set, &param, body, name, NULL);
271     return param;
272 }