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


Reply via email to