Bug 847479 - Sanity check that szip's compressed output can properly be decompressed. r=nfroyd
authorMike Hommey <mh+mozilla@glandium.org>
Wed, 06 Mar 2013 07:29:33 +0100
changeset 123913 4b2e14d6c70508ea9de28e34c1ccda87db37e141
parent 123912 2244aa90a7b32e82c0218dbf24aa0a8a5b6daf48
child 123914 9a66a2a47f2bb492b68b1a41e712d5f8e87fdc5c
push id1401
push userpastithas@mozilla.com
push dateThu, 07 Mar 2013 07:26:45 +0000
treeherderfx-team@ee4879719f78 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnfroyd
bugs847479
milestone22.0a1
Bug 847479 - Sanity check that szip's compressed output can properly be decompressed. r=nfroyd
mozglue/linker/szip.cpp
--- a/mozglue/linker/szip.cpp
+++ b/mozglue/linker/szip.cpp
@@ -9,29 +9,45 @@
 #include <fcntl.h>
 #include <errno.h>
 #include "mozilla/Assertions.h"
 #include "mozilla/Scoped.h"
 #include "SeekableZStream.h"
 #include "Utils.h"
 #include "Logging.h"
 
-class FileBuffer: public MappedPtr
+class Buffer: public MappedPtr
+{
+public:
+  virtual bool Resize(size_t size)
+  {
+    void *buf = mmap(NULL, size, PROT_READ | PROT_WRITE,
+                     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+    if (buf == MAP_FAILED)
+      return false;
+    if (*this != MAP_FAILED)
+      memcpy(buf, *this, std::min(size, GetLength()));
+    Assign(buf, size);
+    return true;
+  }
+};
+
+class FileBuffer: public Buffer
 {
 public:
   bool Init(const char *name, bool writable_ = false)
   {
     fd = open(name, writable_ ? O_RDWR | O_CREAT | O_TRUNC : O_RDONLY, 0666);
     if (fd == -1)
       return false;
     writable = writable_;
     return true;
   }
 
-  bool Resize(size_t size)
+  virtual bool Resize(size_t size)
   {
     if (writable) {
       if (ftruncate(fd, size) == -1)
         return false;
     }
     Assign(mmap(NULL, size, PROT_READ | (writable ? PROT_WRITE : 0),
                 writable ? MAP_SHARED : MAP_PRIVATE, fd, 0), size);
     return this != MAP_FAILED;
@@ -45,18 +61,18 @@ public:
 private:
   AutoCloseFD fd;
   bool writable;
 };
 
 static const size_t CHUNK = 16384;
 
 /* Decompress a seekable compressed stream */
-int do_decompress(const char *name, FileBuffer &origBuf,
-                  const char *outName, FileBuffer &outBuf)
+int do_decompress(const char *name, Buffer &origBuf,
+                  const char *outName, Buffer &outBuf)
 {
   size_t origSize = origBuf.GetLength();
   if (origSize < sizeof(SeekableZStreamHeader)) {
     log("%s is not a seekable zstream", name);
     return 1;
   }
 
   SeekableZStream zstream;
@@ -73,18 +89,18 @@ int do_decompress(const char *name, File
 
   if (!zstream.Decompress(outBuf, 0, size))
     return 1;
 
   return 0;
 }
 
 /* Generate a seekable compressed stream. */
-int do_compress(const char *name, FileBuffer &origBuf,
-                const char *outName, FileBuffer &outBuf)
+int do_compress(const char *name, Buffer &origBuf,
+                const char *outName, Buffer &outBuf)
 {
   size_t origSize = origBuf.GetLength();
   if (origSize == 0) {
     log("Won't compress %s: it's empty", name);
     return 1;
   }
   log("Size = %" PRIuSize, origSize);
 
@@ -147,23 +163,37 @@ int do_compress(const char *name, FileBu
   if (!outBuf.Resize(offset)) {
     log("Error resizing %s: %s", outName, strerror(errno));
     return 1;
   }
 
   MOZ_ASSERT(header->nChunks == nChunks);
   log("Compressed size is %" PRIuSize, offset);
 
+  /* Sanity check */
+  Buffer tmpBuf;
+  if (do_decompress("buffer", outBuf, "buffer", tmpBuf))
+    return 1;
+
+  size = tmpBuf.GetLength();
+  if (size != origSize) {
+    log("Compression error: %" PRIuSize " != %" PRIuSize, size, origSize);
+    return 1;
+  }
+  if (memcmp(static_cast<void *>(origBuf), static_cast<void *>(tmpBuf), size)) {
+    log("Compression error: content mismatch");
+    return 1;
+  }
+
   return 0;
 }
 
 int main(int argc, char* argv[])
 {
-  int (*func)(const char *, FileBuffer &,
-              const char *, FileBuffer &) = do_compress;
+  int (*func)(const char *, Buffer &, const char *, Buffer &) = do_compress;
   char **firstArg = &argv[1];
 
   if ((argc > 1) && strcmp(argv[1], "-d") == 0) {
     func = do_decompress;
     firstArg++;
     argc--;
   }