]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common/compressor: fix improper length value passed to zlib compressor
authorIgor Fedotov <ifedotov@mirantis.com>
Wed, 14 Sep 2016 12:21:02 +0000 (12:21 +0000)
committerIgor Fedotov <ifedotov@mirantis.com>
Wed, 14 Sep 2016 12:25:10 +0000 (12:25 +0000)
Signed-off-by: Igor Fedotov <ifedotovo@miranitis.com>
src/compressor/zlib/ZlibCompressor.cc
src/test/compressor/test_compression_zlib.cc

index 7612dd8d7f56547161b920c697b64329eb844f0e..d201880c86a04297d3cfeaa10276256cfb8dbe34 100644 (file)
@@ -71,9 +71,9 @@ int ZlibCompressor::zlib_compress(const bufferlist &in, bufferlist &out)
     strm.next_in = c_in;
 
     do {
-      strm.avail_out = max_len;
       bufferptr ptr = buffer::create_page_aligned(max_len);
       strm.next_out = (unsigned char*)ptr.c_str() + begin;
+      strm.avail_out = max_len - begin;
       if (begin) {
         ptr.c_str()[0] = 0;
         begin = 0;
@@ -126,9 +126,9 @@ int ZlibCompressor::isal_compress(const bufferlist &in, bufferlist &out)
     strm.next_in = c_in;
 
     do {
-      strm.avail_out = max_len;
       bufferptr ptr = buffer::create_page_aligned(max_len);
       strm.next_out = (unsigned char*)ptr.c_str() + begin;
+      strm.avail_out = max_len - begin;
       if (begin) {
         ptr.c_str()[0] = 1;
         begin = 0;
@@ -189,11 +189,11 @@ int ZlibCompressor::decompress(bufferlist::iterator &p, size_t compressed_size,
   }
 
   size_t remaining = MIN(p.get_remaining(), compressed_size);
-  while(remaining) {
 
+  while(remaining) {
     long unsigned int len = p.get_ptr_and_advance(remaining, &c_in);
     remaining -= len;
-    strm.avail_in = len;
+    strm.avail_in = len - begin;
     strm.next_in = (unsigned char*)c_in + begin;
     begin = 0;
 
@@ -211,7 +211,6 @@ int ZlibCompressor::decompress(bufferlist::iterator &p, size_t compressed_size,
       have = max_len - strm.avail_out;
       out.append(ptr, 0, have);
     } while (strm.avail_out == 0);
-
   }
 
   /* clean up and return */
index e2faf83e03486f2544544ea05752010543eee73a..6eff6815cc4f8e3cdd2eaf2de3d1c3a772c77ad5 100644 (file)
@@ -29,15 +29,16 @@ TEST(ZlibCompressor, compress_decompress)
   ZlibCompressor sp(false);
   EXPECT_STREQ(sp.get_type().c_str(), "zlib");
   const char* test = "This is test text";
+  int res;
   int len = strlen(test);
   bufferlist in, out;
+  bufferlist after;
+  bufferlist exp;
   in.append(test, len);
-  int res = sp.compress(in, out);
+  res = sp.compress(in, out);
   EXPECT_EQ(res, 0);
-  bufferlist after;
   res = sp.decompress(out, after);
   EXPECT_EQ(res, 0);
-  bufferlist exp;
   exp.append(test);
   EXPECT_TRUE(exp.contents_equal(after));
   after.clear();
@@ -47,6 +48,31 @@ TEST(ZlibCompressor, compress_decompress)
   res = sp.decompress(it, compressed_len, after);
   EXPECT_EQ(res, 0);
   EXPECT_TRUE(exp.contents_equal(after));
+
+  //large block and non-begin iterator for continuous block
+  std::string data;
+  data.resize(0x10000 * 1);
+  for(size_t i = 0; i < data.size(); i++)
+    data[i] = i / 256;
+  in.clear();
+  out.clear();
+  in.append(data);
+  exp = in;
+  res = sp.compress(in, out);
+  EXPECT_EQ(res, 0);
+  compressed_len = out.length();
+  out.append_zero(0x10000 - out.length());
+  after.clear();
+  out.c_str();
+  bufferlist prefix;
+  prefix.append(string("some prefix"));
+  size_t prefix_len = prefix.length();
+  out.claim_prepend(prefix);
+  it = out.begin();
+  it.advance(prefix_len);
+  res = sp.decompress(it, compressed_len, after);
+  EXPECT_EQ(res, 0);
+  EXPECT_TRUE(exp.contents_equal(after));
 }
 
 TEST(ZlibCompressor, compress_decompress_chunk)
@@ -67,6 +93,8 @@ TEST(ZlibCompressor, compress_decompress_chunk)
   bufferlist exp;
   exp.append("This is test text1234567890");
   EXPECT_TRUE(exp.contents_equal(after));
+
+
 }
 
 TEST(ZlibCompressor, compress_decompress_isal)
@@ -149,7 +177,6 @@ TEST(ZlibCompressor, zlib_isal_compatibility)
   EXPECT_TRUE(exp.contents_equal(after));
 }
 
-
 int main(int argc, char **argv) {
   vector<const char*> args;
   argv_to_vec(argc, (const char **)argv, args);