static void test_decodev(dAT) { char src1[] = "%2540%2"; char src2[] = "0%u0"; char src3[] = "041"; struct iovec iovec1[] = { { src1, sizeof(src1) - 1 }, { src2, sizeof(src2) - 1 }, { src3, sizeof(src3) - 1 }, }; struct iovec iovec2[] = { { src1, sizeof(src1) - 1 }, { src2, sizeof(src2) - 1 }, }; const char expect1[] = "%40 A"; const char expect2[] = "%40 "; char dest[sizeof(src1) + sizeof(src2) + sizeof(src3)]; apr_size_t dest_len; apr_status_t status; status = apreq_decodev(dest, &dest_len, iovec1, 3); AT_int_eq(status, APR_SUCCESS); AT_int_eq(dest_len, sizeof(expect1) - 1); AT_mem_eq(dest, expect1, sizeof(expect1) - 1); status = apreq_decodev(dest, &dest_len, iovec2, 2); AT_int_eq(status, APR_INCOMPLETE); AT_int_eq(dest_len, sizeof(expect2) - 1); AT_mem_eq(dest, expect2, sizeof(expect2) - 1); }
static apr_status_t split_urlword(apreq_param_t **p, apr_pool_t *pool, apr_bucket_brigade *bb, apr_size_t nlen, apr_size_t vlen) { apreq_param_t *param; apreq_value_t *v; apr_bucket *e, *f; apr_status_t s; struct iovec vec[APREQ_DEFAULT_NELTS]; apr_array_header_t arr; apr_size_t mark; apreq_charset_t charset; if (nlen == 0) return APR_EBADARG; param = apreq_param_make(pool, NULL, nlen, NULL, vlen); *(const apreq_value_t **)&v = ¶m->v; arr.pool = pool; arr.elt_size = sizeof(struct iovec); arr.nelts = 0; arr.nalloc = APREQ_DEFAULT_NELTS; arr.elts = (char *)vec; ++nlen, ++vlen; e = APR_BRIGADE_FIRST(bb); while (!APR_BUCKET_IS_EOS(e)) { struct iovec *iov = apr_array_push(&arr); apr_size_t len; s = apr_bucket_read(e, (const char **)&iov->iov_base, &len, APR_BLOCK_READ); if (s != APR_SUCCESS) return s; iov->iov_len = len; nlen -= len; e = APR_BUCKET_NEXT(e); if (nlen == 0) { iov->iov_len--; break; } } mark = arr.nelts; while (!APR_BUCKET_IS_EOS(e)) { struct iovec *iov = apr_array_push(&arr); apr_size_t len; s = apr_bucket_read(e, (const char **)&iov->iov_base, &len, APR_BLOCK_READ); if (s != APR_SUCCESS) return s; iov->iov_len = len; vlen -= len; e = APR_BUCKET_NEXT(e); if (vlen == 0) { iov->iov_len--; break; } } s = apreq_decodev(v->data, &vlen, (struct iovec *)arr.elts + mark, arr.nelts - mark); if (s > APR_SUCCESS + APREQ_CHARSET_UTF8) return s; charset = s; v->name = v->data + vlen + 1; v->dlen = vlen; s = apreq_decodev(v->name, &nlen, (struct iovec *)arr.elts, mark); if (s > APR_SUCCESS + APREQ_CHARSET_UTF8) return s; switch (s) { case APREQ_CHARSET_UTF8: if (charset == APREQ_CHARSET_ASCII) charset = APREQ_CHARSET_UTF8; case APREQ_CHARSET_ASCII: break; case APREQ_CHARSET_LATIN1: if (charset != APREQ_CHARSET_CP1252) charset = APREQ_CHARSET_LATIN1; break; case APREQ_CHARSET_CP1252: charset = APREQ_CHARSET_CP1252; } v->nlen = nlen; while ((f = APR_BRIGADE_FIRST(bb)) != e) apr_bucket_delete(f); apreq_param_tainted_on(param); apreq_param_charset_set(param, charset); *p = param; return APR_SUCCESS; }