From 5e0da5845e8409b3229a095e3bb2649ed8072bee Mon Sep 17 00:00:00 2001
From: David Garcia Quintas <dgq@google.com>
Date: Thu, 10 Dec 2015 18:27:32 -0800
Subject: [PATCH] More coverage

---
 src/core/compression/algorithm.c              | 10 +--
 src/core/compression/message_compress.c       |  4 +-
 test/core/compression/compression_test.c      | 89 ++++++++++++++++++-
 test/core/compression/message_compress_test.c | 40 ++++++++-
 4 files changed, 130 insertions(+), 13 deletions(-)

diff --git a/src/core/compression/algorithm.c b/src/core/compression/algorithm.c
index 73d91fa8ea..9624c52310 100644
--- a/src/core/compression/algorithm.c
+++ b/src/core/compression/algorithm.c
@@ -84,7 +84,7 @@ int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
     case GRPC_COMPRESS_ALGORITHMS_COUNT:
       return 0;
   }
-  return 0;
+  GPR_UNREACHABLE_CODE(return 0);
 }
 
 grpc_compression_algorithm grpc_compression_algorithm_from_mdstr(
@@ -139,10 +139,9 @@ grpc_compression_algorithm grpc_compression_algorithm_for_level(
     case GRPC_COMPRESS_LEVEL_HIGH:
       return GRPC_COMPRESS_DEFLATE;
     default:
-      /* we shouldn't be making it here */
-      abort();
-      return GRPC_COMPRESS_NONE;
+      break;
   }
+  GPR_UNREACHABLE_CODE(return GRPC_COMPRESS_NONE);
 }
 
 grpc_compression_level grpc_compression_level_for_algorithm(
@@ -156,8 +155,7 @@ grpc_compression_level grpc_compression_level_for_algorithm(
       return clevel;
     }
   }
-  abort();
-  return GRPC_COMPRESS_LEVEL_NONE;
+  GPR_UNREACHABLE_CODE(return GRPC_COMPRESS_LEVEL_NONE);
 }
 
 void grpc_compression_options_init(grpc_compression_options *opts) {
diff --git a/src/core/compression/message_compress.c b/src/core/compression/message_compress.c
index 94f4e89d7a..e72347118f 100644
--- a/src/core/compression/message_compress.c
+++ b/src/core/compression/message_compress.c
@@ -69,8 +69,8 @@ static int zlib_body(z_stream* zs, gpr_slice_buffer* input,
         zs->next_out = GPR_SLICE_START_PTR(outbuf);
       }
       r = flate(zs, flush);
-      if (r == Z_STREAM_ERROR) {
-        gpr_log(GPR_INFO, "zlib: stream error");
+      if (r < 0 && r != Z_BUF_ERROR /* not fatal */) {
+        gpr_log(GPR_INFO, "zlib error (%d)", r);
         goto error;
       }
     } while (zs->avail_out == 0);
diff --git a/test/core/compression/compression_test.c b/test/core/compression/compression_test.c
index 35fadc00c0..85228fa47f 100644
--- a/test/core/compression/compression_test.c
+++ b/test/core/compression/compression_test.c
@@ -53,9 +53,8 @@ static void test_compression_algorithm_parse(void) {
   for (i = 0; i < GPR_ARRAY_SIZE(valid_names); i++) {
     const char *valid_name = valid_names[i];
     grpc_compression_algorithm algorithm;
-    int success;
-    success = grpc_compression_algorithm_parse(valid_name, strlen(valid_name),
-                                               &algorithm);
+    const int success = grpc_compression_algorithm_parse(
+        valid_name, strlen(valid_name), &algorithm);
     GPR_ASSERT(success != 0);
     GPR_ASSERT(algorithm == valid_algorithms[i]);
   }
@@ -71,9 +70,93 @@ static void test_compression_algorithm_parse(void) {
   }
 }
 
+static void test_compression_algorithm_name(void) {
+  int success;
+  char *name;
+  size_t i;
+  const char *valid_names[] = {"identity", "gzip", "deflate"};
+  const grpc_compression_algorithm valid_algorithms[] = {
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_DEFLATE};
+
+  gpr_log(GPR_DEBUG, "test_compression_algorithm_name");
+
+  for (i = 0; i < GPR_ARRAY_SIZE(valid_algorithms); i++) {
+    success = grpc_compression_algorithm_name(valid_algorithms[i], &name);
+    GPR_ASSERT(success != 0);
+    GPR_ASSERT(strcmp(name, valid_names[i]) == 0);
+  }
+
+  success =
+      grpc_compression_algorithm_name(GRPC_COMPRESS_ALGORITHMS_COUNT, &name);
+  GPR_ASSERT(success == 0);
+  /* the value of "name" is undefined upon failure */
+}
+
+
+static void test_compression_algorithm_for_level(void) {
+  size_t i;
+  grpc_compression_level levels[] = {
+      GRPC_COMPRESS_LEVEL_NONE, GRPC_COMPRESS_LEVEL_LOW,
+      GRPC_COMPRESS_LEVEL_MED, GRPC_COMPRESS_LEVEL_HIGH};
+  grpc_compression_algorithm algorithms[] = {GRPC_COMPRESS_NONE,
+    GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_DEFLATE};
+  gpr_log(GPR_DEBUG, "test_compression_algorithm_for_level");
+
+  for (i = 0; i < GPR_ARRAY_SIZE(levels); i++) {
+    GPR_ASSERT(algorithms[i] ==
+               grpc_compression_algorithm_for_level(levels[i]));
+  }
+}
+
+static void test_compression_level_for_algorithm(void) {
+
+  size_t i;
+  grpc_compression_level levels[] = {
+      GRPC_COMPRESS_LEVEL_NONE, GRPC_COMPRESS_LEVEL_LOW,
+      GRPC_COMPRESS_LEVEL_LOW, GRPC_COMPRESS_LEVEL_LOW};
+  grpc_compression_algorithm algorithms[] = {GRPC_COMPRESS_NONE,
+    GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_DEFLATE};
+  gpr_log(GPR_DEBUG, "test_compression_level_for_algorithm");
+
+  for (i = 0; i < GPR_ARRAY_SIZE(algorithms); i++) {
+    GPR_ASSERT(levels[i] ==
+               grpc_compression_level_for_algorithm(algorithms[i]));
+  }
+}
+
+static void test_compression_enable_disable_algorithm(void) {
+  grpc_compression_options options;
+  grpc_compression_algorithm algorithm;
+
+  gpr_log(GPR_DEBUG, "test_compression_enable_disable_algorithm");
+
+  grpc_compression_options_init(&options);
+  for (algorithm = GRPC_COMPRESS_NONE; algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT; algorithm++) {
+    /* all algorithms are enabled by default */
+    GPR_ASSERT(grpc_compression_options_is_algorithm_enabled(&options,
+                                                             algorithm) != 0);
+  }
+  /* disable one by one */
+  for (algorithm = GRPC_COMPRESS_NONE; algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT; algorithm++) {
+    grpc_compression_options_disable_algorithm(&options, algorithm);
+    GPR_ASSERT(grpc_compression_options_is_algorithm_enabled(&options,
+                                                             algorithm) == 0);
+  }
+  /* re-enable one by one */
+  for (algorithm = GRPC_COMPRESS_NONE; algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT; algorithm++) {
+    grpc_compression_options_enable_algorithm(&options, algorithm);
+    GPR_ASSERT(grpc_compression_options_is_algorithm_enabled(&options,
+                                                             algorithm) != 0);
+  }
+}
+
 int main(int argc, char **argv) {
   grpc_init();
   test_compression_algorithm_parse();
+  test_compression_algorithm_name();
+  test_compression_algorithm_for_level();
+  test_compression_level_for_algorithm();
+  test_compression_enable_disable_algorithm();
   grpc_shutdown();
 
   return 0;
diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c
index 131b5e7f65..bd454099ce 100644
--- a/test/core/compression/message_compress_test.c
+++ b/test/core/compression/message_compress_test.c
@@ -167,7 +167,7 @@ static void test_tiny_data_compress(void) {
   gpr_slice_buffer_destroy(&output);
 }
 
-static void test_bad_data_decompress(void) {
+static void test_bad_decompression_data_crc(void) {
   gpr_slice_buffer input;
   gpr_slice_buffer corrupted;
   gpr_slice_buffer output;
@@ -195,6 +195,40 @@ static void test_bad_data_decompress(void) {
   gpr_slice_buffer_destroy(&output);
 }
 
+static void test_bad_decompression_data_trailing_garbage(void) {
+  gpr_slice_buffer input;
+  gpr_slice_buffer output;
+
+  gpr_slice_buffer_init(&input);
+  gpr_slice_buffer_init(&output);
+  /* append 0x99 to the end of an otherwise valid stream */
+  gpr_slice_buffer_add(
+      &input, gpr_slice_from_copied_buffer(
+                  "\x78\xda\x63\x60\x60\x60\x00\x00\x00\x04\x00\x01\x99", 13));
+
+  /* try (and fail) to decompress the invalid compresed buffer */
+  GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_DEFLATE, &input, &output));
+
+  gpr_slice_buffer_destroy(&input);
+  gpr_slice_buffer_destroy(&output);
+}
+
+static void test_bad_decompression_data_stream(void) {
+  gpr_slice_buffer input;
+  gpr_slice_buffer output;
+
+  gpr_slice_buffer_init(&input);
+  gpr_slice_buffer_init(&output);
+  gpr_slice_buffer_add(&input,
+                       gpr_slice_from_copied_buffer("\x78\xda\xff\xff", 4));
+
+  /* try (and fail) to decompress the invalid compresed buffer */
+  GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_DEFLATE, &input, &output));
+
+  gpr_slice_buffer_destroy(&input);
+  gpr_slice_buffer_destroy(&output);
+}
+
 static void test_bad_compression_algorithm(void) {
   gpr_slice_buffer input;
   gpr_slice_buffer output;
@@ -262,7 +296,9 @@ int main(int argc, char **argv) {
   }
 
   test_tiny_data_compress();
-  test_bad_data_decompress();
+  test_bad_decompression_data_crc();
+  test_bad_decompression_data_stream();
+  test_bad_decompression_data_trailing_garbage();
   test_bad_compression_algorithm();
   test_bad_decompression_algorithm();
   grpc_shutdown();
-- 
GitLab