Author: gstein Date: Thu Nov 12 01:43:38 2015 New Revision: 1713955 URL: http://svn.apache.org/viewvc?rev=1713955&view=rev Log: Fix a potential over-read in serf_bucket_limited_readline()
* buckets/buckets.c: (serf_bucket_limited_readline): handle peek_len==0 for a fast-exit when EOF is hit. only read a single character, and document why reading more could be Bad. (serf_default_readline): remove an obsolete comment Modified: serf/trunk/buckets/buckets.c Modified: serf/trunk/buckets/buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/buckets.c?rev=1713955&r1=1713954&r2=1713955&view=diff ============================================================================== --- serf/trunk/buckets/buckets.c (original) +++ serf/trunk/buckets/buckets.c Thu Nov 12 01:43:38 2015 @@ -134,11 +134,29 @@ apr_status_t serf_bucket_limited_readlin apr_size_t peek_len; status = bucket->type->peek(bucket, &peek_data, &peek_len); - if (SERF_BUCKET_READ_ERROR(status)) return status; - if (peek_len > 0) { + if (peek_len == 0) { + /* peek() returned no data. */ + + /* ... if that's because the bucket has no data, then we're done. */ + if (APR_STATUS_IS_EOF(status)) { + *found = SERF_NEWLINE_NONE; + *len = 0; + return APR_EOF; + } + + /* We can only read and return a single character. + + For example, if we tried reading 2 characters seeking CRLF, and + got CR followed by 'a', then we have over-read the line, and + consumed a character from the next line. Bad. */ + requested = 1; + } + else { + /* peek_len > 0 */ + const char *cr = NULL; const char *lf = NULL; @@ -176,17 +194,8 @@ apr_status_t serf_bucket_limited_readlin else requested = peek_len; } - else if (requested > 1) { - /* We can't peek... - The only valid thing to do is try to read upto one EOL */ - if ((acceptable & SERF_NEWLINE_ANY) == SERF_NEWLINE_CRLF) - requested = 2; - else - requested = 1; - } status = bucket->type->read(bucket, requested, data, len); - if (SERF_BUCKET_READ_ERROR(status)) return status; @@ -218,7 +227,6 @@ apr_status_t serf_default_readline(serf_ int *found, const char **data, apr_size_t *len) { - /* We explicitly call this function directly and *not* via the callback */ return serf_bucket_limited_readline(bucket, acceptable, SERF_READ_ALL_AVAIL, found, data, len); }