Author: rhuijben Date: Wed Nov 11 10:20:53 2015 New Revision: 1713800 URL: http://svn.apache.org/viewvc?rev=1713800&view=rev Log: Resolve an issue in the limit buckets where readline previously allowed reading further than the set limit.
* buckets/buckets.c (serf_default_readline): Fix several issues. * buckets/limit_buckets.c (serf_limit_readline): Remove function that has known issues. (serf_bucket_type_limit): Use default readline code. * test/test_buckets.c (test_limit_buckets): Extend test. Modified: serf/trunk/buckets/buckets.c serf/trunk/buckets/limit_buckets.c serf/trunk/test/test_buckets.c Modified: serf/trunk/buckets/buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/buckets.c?rev=1713800&r1=1713799&r2=1713800&view=diff ============================================================================== --- serf/trunk/buckets/buckets.c (original) +++ serf/trunk/buckets/buckets.c Wed Nov 11 10:20:53 2015 @@ -164,7 +164,7 @@ apr_status_t serf_default_readline(serf_ Let's make the buffering in the caller handle that case for now. */ - if (*cr == '\r' && (acceptable & SERF_NEWLINE_CRLF) + if (cr && *cr == '\r' && (acceptable & SERF_NEWLINE_CRLF) && ((cr + 1) < (peek_data + peek_len)) && *(cr + 1) == '\n') { requested = (cr + 2) - peek_data; @@ -192,16 +192,16 @@ apr_status_t serf_default_readline(serf_ *found = SERF_NEWLINE_NONE; } else if ((acceptable & SERF_NEWLINE_CRLF) && *len >= 2 - && data[*len - 1] == '\n' && data[*len - 2] == '\r') + && (*data)[*len - 1] == '\n' && (*data)[*len - 2] == '\r') { *found = SERF_NEWLINE_CRLF; } - else if ((acceptable & SERF_NEWLINE_LF) && data[*len - 1] == '\n') + else if ((acceptable & SERF_NEWLINE_LF) && (*data)[*len - 1] == '\n') { *found = SERF_NEWLINE_LF; } else if ((acceptable & (SERF_NEWLINE_CRLF | SERF_NEWLINE_CR)) - && data[*len - 1] == '\r') + && (*data)[*len - 1] == '\r') { *found = (acceptable & (SERF_NEWLINE_CRLF)) ? SERF_NEWLINE_CRLF_SPLIT : SERF_NEWLINE_CR; Modified: serf/trunk/buckets/limit_buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/limit_buckets.c?rev=1713800&r1=1713799&r2=1713800&view=diff ============================================================================== --- serf/trunk/buckets/limit_buckets.c (original) +++ serf/trunk/buckets/limit_buckets.c Wed Nov 11 10:20:53 2015 @@ -79,34 +79,6 @@ static apr_status_t serf_limit_read(serf return status; } -static apr_status_t serf_limit_readline(serf_bucket_t *bucket, - int acceptable, int *found, - const char **data, apr_size_t *len) -{ - limit_context_t *ctx = bucket->data; - apr_status_t status; - - if (!ctx->remaining) { - *len = 0; - *found = SERF_NEWLINE_NONE; - return APR_EOF; - } - /* ### Where does this obey/verify the limit? -> It doesn't */ - status = serf_bucket_readline(ctx->stream, acceptable, found, data, len); - - /* So this may potentially underflow! */ - if (!SERF_BUCKET_READ_ERROR(status)) { - ctx->remaining -= *len; - } - - /* If we have met our limit and don't have a status, return EOF. */ - if (!ctx->remaining && !status) { - status = APR_EOF; - } - - return status; -} - static apr_status_t serf_limit_read_iovec(serf_bucket_t *bucket, apr_size_t requested, int vecs_size, @@ -197,7 +169,7 @@ static apr_status_t serf_limit_set_confi const serf_bucket_type_t serf_bucket_type_limit = { "LIMIT", serf_limit_read, - serf_limit_readline, + serf_default_readline, serf_limit_read_iovec, serf_default_read_for_sendfile, serf_buckets_are_v2, Modified: serf/trunk/test/test_buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/test/test_buckets.c?rev=1713800&r1=1713799&r2=1713800&view=diff ============================================================================== --- serf/trunk/test/test_buckets.c (original) +++ serf/trunk/test/test_buckets.c Wed Nov 11 10:20:53 2015 @@ -2136,6 +2136,21 @@ static void test_limit_buckets(CuTest *t CuAssertIntEquals(tc, 5, len); } serf_bucket_destroy(agg); + + { + const char *data; + int found; + + raw = SERF_BUCKET_SIMPLE_STRING("ABCDEF\nGHIJKLMNOP", alloc); + limit = serf_bucket_limit_create(raw, 5, alloc); + + CuAssertIntEquals(tc, APR_EOF, + serf_bucket_readline(limit, SERF_NEWLINE_ANY, &found, + &data, &len)); + CuAssertIntEquals(tc, SERF_NEWLINE_NONE, found); + CuAssertIntEquals(tc, len, 5); /* > 5 is over limit -> bug */ + DRAIN_BUCKET(raw); + } } /* Basic test for unframe buckets. */