Author: rhuijben
Date: Mon Nov  9 12:03:42 2015
New Revision: 1713402

URL: http://svn.apache.org/viewvc?rev=1713402&view=rev
Log:
Make the limit bucket verify that it actually limits the result and not
just passes EOF early. Add some testing on the limit bucket while we're
working on it.

* buckets/limit_buckets.c
  (serf_limit_read,
   serf_limit_read_iovec): Don't just pass early EOF as non failure.

* test/test_buckets.c
  (test_limit_buckets): New function.
  (test_buckets): Add test_limit_buckets.

Modified:
    serf/trunk/buckets/limit_buckets.c
    serf/trunk/test/test_buckets.c

Modified: serf/trunk/buckets/limit_buckets.c
URL: 
http://svn.apache.org/viewvc/serf/trunk/buckets/limit_buckets.c?rev=1713402&r1=1713401&r2=1713402&view=diff
==============================================================================
--- serf/trunk/buckets/limit_buckets.c (original)
+++ serf/trunk/buckets/limit_buckets.c Mon Nov  9 12:03:42 2015
@@ -66,11 +66,14 @@ static apr_status_t serf_limit_read(serf
 
     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;
+        /* If we have met our limit and don't have a status, return EOF. */
+        if (!ctx->remaining && !status) {
+            status = APR_EOF;
+        }
+        else if (APR_STATUS_IS_EOF(status) && ctx->remaining) {
+            status = SERF_ERROR_TRUNCATED_HTTP_RESPONSE;
+        }
     }
 
     return status;
@@ -136,11 +139,14 @@ static apr_status_t serf_limit_read_iove
         len += vecs[i].iov_len;
 
       ctx->remaining -= len;
-  }
 
-  /* If we have met our limit and don't have a status, return EOF. */
-  if (!ctx->remaining && !status) {
-      status = APR_EOF;
+      /* If we have met our limit and don't have a status, return EOF. */
+      if (!ctx->remaining && !status) {
+          status = APR_EOF;
+      }
+      else if (APR_STATUS_IS_EOF(status) && ctx->remaining) {
+          status = SERF_ERROR_TRUNCATED_HTTP_RESPONSE;
+      }
   }
 
   return status;

Modified: serf/trunk/test/test_buckets.c
URL: 
http://svn.apache.org/viewvc/serf/trunk/test/test_buckets.c?rev=1713402&r1=1713401&r2=1713402&view=diff
==============================================================================
--- serf/trunk/test/test_buckets.c (original)
+++ serf/trunk/test/test_buckets.c Mon Nov  9 12:03:42 2015
@@ -2069,6 +2069,47 @@ static void test_prefix_buckets(CuTest *
     serf_bucket_destroy(prefix);
 }
 
+static void test_limit_buckets(CuTest *tc)
+{
+  test_baton_t *tb = tc->testBaton;
+  serf_bucket_alloc_t *alloc = tb->bkt_alloc;
+  char buffer[26];
+  apr_size_t len;
+  serf_bucket_t *raw;
+  serf_bucket_t *limit;
+  serf_bucket_t *agg;
+  apr_status_t status;
+
+  /* The normal usecase */
+  raw = SERF_BUCKET_SIMPLE_STRING("ABCDEFGHIJKLMNOPQRSTUVWXYZ", alloc);
+  limit = serf_bucket_limit_create(raw, 13, alloc);
+  read_and_check_bucket(tc, limit, "ABCDEFGHIJKLM");
+  read_and_check_bucket(tc, raw, "NOPQRSTUVWXYZ");
+  serf_bucket_destroy(limit);
+
+  /* The normal usecase but different way */
+  raw = SERF_BUCKET_SIMPLE_STRING("ABCDEFGHIJKLMNOPQRSTUVWXYZ", alloc);
+  limit = serf_bucket_limit_create(
+                serf_bucket_barrier_create(raw, alloc),
+                13, alloc);
+  agg = serf_bucket_aggregate_create(alloc);
+  serf_bucket_aggregate_prepend(agg, limit);
+  serf_bucket_aggregate_append(agg,
+                               serf_bucket_simple_create("!", 1, NULL, NULL,
+                                                         alloc));
+  serf_bucket_aggregate_append(agg, raw);
+  read_and_check_bucket(tc, agg, "ABCDEFGHIJKLM!NOPQRSTUVWXYZ");
+  serf_bucket_destroy(agg);
+
+  /* What if there is not enough data? */
+  raw = SERF_BUCKET_SIMPLE_STRING("ABCDE", alloc);
+  limit = serf_bucket_limit_create(raw, 13, alloc);
+
+  status = read_all(limit, buffer, sizeof(buffer), &len);
+  CuAssertIntEquals(tc, SERF_ERROR_TRUNCATED_HTTP_RESPONSE, status);
+  serf_bucket_destroy(limit);
+}
+
 /* Basic test for unframe buckets. */
 static void test_http2_unframe_buckets(CuTest *tc)
 {
@@ -2573,6 +2614,7 @@ CuSuite *test_buckets(void)
     SUITE_ADD_TEST(suite, test_dechunk_buckets);
     SUITE_ADD_TEST(suite, test_deflate_buckets);
     SUITE_ADD_TEST(suite, test_prefix_buckets);
+    SUITE_ADD_TEST(suite, test_limit_buckets);
     SUITE_ADD_TEST(suite, test_http2_unframe_buckets);
     SUITE_ADD_TEST(suite, test_http2_unpad_buckets);
     SUITE_ADD_TEST(suite, test_hpack_huffman_decode);


Reply via email to