Skip to content

Commit

Permalink
* buckets/apr_brigade.c (apr_brigade_split_line,
Browse files Browse the repository at this point in the history
  apr_brigade_to_iovec, apr_brigade_flatten): Ignore or cope
  with metadata buckets which return (NULL, 0) on read().

* test/testbuckets.c (test_flatten): Test that EOS is ignored.
  (test_iovec, test_splitline_eos): New tests.

PR: 68278
Submitted by: Ben Kallus <benjamin.p.kallus.gr dartmouth.edu>, jorton
  • Loading branch information
notroj committed Dec 19, 2023
1 parent 1efa47e commit 1c99315
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 8 deletions.
23 changes: 15 additions & 8 deletions buckets/apr_brigade.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,9 @@ APR_DECLARE(apr_status_t) apr_brigade_flatten(apr_bucket_brigade *bb,
*
* No, we only copy the data up to their requested size. -- jre
*/
memcpy(c, str, str_len);
if (str_len) {
memcpy(c, str, str_len);
}

c += str_len;
actual += str_len;
Expand Down Expand Up @@ -353,13 +355,15 @@ APR_DECLARE(apr_status_t) apr_brigade_split_line(apr_bucket_brigade *bbOut,
return rv;
}

pos = memchr(str, APR_ASCII_LF, len);
/* We found a match. */
if (pos != NULL) {
apr_bucket_split(e, pos - str + 1);
APR_BUCKET_REMOVE(e);
APR_BRIGADE_INSERT_TAIL(bbOut, e);
return APR_SUCCESS;
if (len) {
pos = memchr(str, APR_ASCII_LF, len);
/* We found a match. */
if (pos != NULL) {
apr_bucket_split(e, pos - str + 1);
APR_BUCKET_REMOVE(e);
APR_BRIGADE_INSERT_TAIL(bbOut, e);
return APR_SUCCESS;
}
}
APR_BUCKET_REMOVE(e);
if (APR_BUCKET_IS_METADATA(e) || len > APR_BUCKET_BUFF_SIZE/4) {
Expand Down Expand Up @@ -700,6 +704,9 @@ APR_DECLARE(apr_status_t) apr_brigade_to_iovec(apr_bucket_brigade *b,
e != APR_BRIGADE_SENTINEL(b);
e = APR_BUCKET_NEXT(e))
{
/* Skip metadata buckets. */
if (APR_BUCKET_IS_METADATA(e)) continue;

if (left-- == 0)
break;

Expand Down
67 changes: 67 additions & 0 deletions test/testbuckets.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,14 @@ static void test_flatten(abts_case *tc, void *data)
{
apr_bucket_alloc_t *ba = apr_bucket_alloc_create(p);
apr_bucket_brigade *bb;
apr_bucket *e;

bb = make_simple_brigade(ba, "hello, ", "world");

/* add an EOS, which should be silently ignored. */
e = apr_bucket_eos_create(ba);
APR_BRIGADE_INSERT_HEAD(bb, e);

flatten_match(tc, "flatten brigade", bb, "hello, world");

apr_brigade_destroy(bb);
Expand Down Expand Up @@ -209,6 +214,36 @@ static void test_splitline(abts_case *tc, void *data)
apr_bucket_alloc_destroy(ba);
}

static void test_splitline_eos(abts_case *tc, void *data)
{
apr_bucket_alloc_t *ba = apr_bucket_alloc_create(p);
apr_bucket_brigade *bin, *bout;
apr_bucket *eos = apr_bucket_eos_create(ba);

bin = make_simple_brigade(ba, "blah blah\n",
"foo foo");
APR_BRIGADE_INSERT_TAIL(bin, eos);

bout = apr_brigade_create(p, ba);

APR_ASSERT_SUCCESS(tc, "split line eos #1",
apr_brigade_split_line(bout, bin,
APR_BLOCK_READ, 100));

flatten_match(tc, "split line eos", bout, "blah blah\n");

apr_brigade_cleanup(bout);
APR_ASSERT_SUCCESS(tc, "split line eos #2",
apr_brigade_split_line(bout, bin,
APR_BLOCK_READ, 100));

flatten_match(tc, "split line eos", bout, "foo foo");

apr_brigade_destroy(bout);
apr_brigade_destroy(bin);
apr_bucket_alloc_destroy(ba);
}

static void test_splitboundary(abts_case *tc, void *data)
{
apr_bucket_alloc_t *ba = apr_bucket_alloc_create(p);
Expand Down Expand Up @@ -559,6 +594,9 @@ static void test_write_putstrs(abts_case *tc, void *data)
apr_brigade_putstrs(bb, NULL, NULL, "2", "34", "567", "8", "9a", "bcd",
"e", "f", "gh", "i", NULL);
apr_brigade_putstrs(bb, NULL, NULL, "j", NULL);
e = apr_bucket_eos_create(ba);
APR_BRIGADE_INSERT_HEAD(bb, e);

APR_ASSERT_SUCCESS(tc, "apr_brigade_flatten",
apr_brigade_flatten(bb, buf, &len));
ABTS_STR_NEQUAL(tc, expect, buf, strlen(expect));
Expand All @@ -567,6 +605,33 @@ static void test_write_putstrs(abts_case *tc, void *data)
apr_bucket_alloc_destroy(ba);
}

static void test_iovec(abts_case *tc, void *data)
{
apr_bucket_alloc_t *ba = apr_bucket_alloc_create(p);
apr_bucket_brigade *bb;
apr_bucket *e;
struct iovec vec[3];
int vecs = 3;

bb = make_simple_brigade(ba, "foo", "bar");

/* add an EOS, which should be silently ignored. */
e = apr_bucket_eos_create(ba);
APR_BRIGADE_INSERT_HEAD(bb, e);

APR_ASSERT_SUCCESS(tc, "apr_brigade_to_iovec",
apr_brigade_to_iovec(bb, vec, &vecs));

ABTS_INT_EQUAL(tc, 2, vecs);
ABTS_STR_EQUAL(tc, "foo", vec[0].iov_base);
ABTS_INT_EQUAL(tc, 3, vec[0].iov_len);
ABTS_STR_EQUAL(tc, "bar", vec[1].iov_base);
ABTS_INT_EQUAL(tc, 3, vec[1].iov_len);

apr_brigade_destroy(bb);
apr_bucket_alloc_destroy(ba);
}

abts_suite *testbuckets(abts_suite *suite)
{
suite = ADD_SUITE(suite);
Expand All @@ -577,6 +642,7 @@ abts_suite *testbuckets(abts_suite *suite)
abts_run_test(suite, test_split, NULL);
abts_run_test(suite, test_bwrite, NULL);
abts_run_test(suite, test_splitline, NULL);
abts_run_test(suite, test_splitline_eos, NULL);
abts_run_test(suite, test_splitboundary, NULL);
abts_run_test(suite, test_splits, NULL);
abts_run_test(suite, test_insertfile, NULL);
Expand All @@ -585,6 +651,7 @@ abts_suite *testbuckets(abts_suite *suite)
abts_run_test(suite, test_partition, NULL);
abts_run_test(suite, test_write_split, NULL);
abts_run_test(suite, test_write_putstrs, NULL);
abts_run_test(suite, test_iovec, NULL);

return suite;
}
Expand Down

0 comments on commit 1c99315

Please sign in to comment.