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);
}