Bug 641212 Part 8 - Remove bz2 support from the updater. r?rstrong draft
authorMatt Howell <mhowell@mozilla.com>
Thu, 26 Jan 2017 15:09:27 -0800
changeset 607675 e1afe3a47e76b5755cf13d7f087ba211fd1aa27b
parent 607659 596043d866cae0bc6850a4c8a31d973e38416cd1
child 607676 cac959118af0e1f0b34c6d9b74c583b83dce3cda
push id68081
push usermhowell@mozilla.com
push dateWed, 12 Jul 2017 18:00:48 +0000
reviewersrstrong
bugs641212
milestone56.0a1
Bug 641212 Part 8 - Remove bz2 support from the updater. r?rstrong The updater no longer needs to perform any decompression, it's handled in libmar now, so remove the associated code from the archive reader. Also replace the CRC32 code in the updater with a call to liblzma's function, since the old code depends on libbz2. MozReview-Commit-ID: 9HIkXVdenYv
config/external/moz.build
toolkit/mozapps/update/common/errors.h
toolkit/mozapps/update/updater/archivereader.cpp
toolkit/mozapps/update/updater/archivereader.h
toolkit/mozapps/update/updater/updater-common.build
toolkit/mozapps/update/updater/updater.cpp
--- a/config/external/moz.build
+++ b/config/external/moz.build
@@ -8,27 +8,23 @@ external_dirs = []
 
 DIRS += [
     'lgpllibs',
     'sqlite',
 ]
 if not CONFIG['MOZ_SYSTEM_JPEG']:
     external_dirs += ['media/libjpeg']
 
-if CONFIG['MOZ_UPDATER']:
-    if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android'
-        external_dirs += ['modules/libbz2']
+if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
+    external_dirs += ['modules/xz']
 
 # There's no "native" brotli or woff2 yet, but probably in the future...
 external_dirs += ['modules/brotli']
 external_dirs += ['modules/woff2']
 
-if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
-    external_dirs += ['modules/xz']
-
 if CONFIG['MOZ_VORBIS']:
     external_dirs += ['media/libvorbis']
 
 if CONFIG['MOZ_TREMOR']:
     external_dirs += ['media/libtremor']
 
 if CONFIG['MOZ_WEBM_ENCODER']:
     external_dirs += ['media/libmkv']
--- a/toolkit/mozapps/update/common/errors.h
+++ b/toolkit/mozapps/update/common/errors.h
@@ -52,21 +52,24 @@
 #define SERVICE_UPDATER_NOT_FIXED_DRIVE 31
 #define SERVICE_COULD_NOT_LOCK_UPDATER 32
 #define SERVICE_INSTALLDIR_ERROR 33
 
 #define NO_INSTALLDIR_ERROR 34
 #define WRITE_ERROR_ACCESS_DENIED 35
 // #define WRITE_ERROR_SHARING_VIOLATION 36 // Replaced with errors 46-48
 #define WRITE_ERROR_CALLBACK_APP 37
-#define UNEXPECTED_BZIP_ERROR 39
-#define UNEXPECTED_MAR_ERROR 40
+// UNEXPECTED_BZIP_ERROR and UNEXPECTED_MAR_ERROR are never returned now
+// that LZMA is used instead of BZ2.
+// #define UNEXPECTED_BZIP_ERROR 39
+// #define UNEXPECTED_MAR_ERROR 40
 #define UNEXPECTED_BSPATCH_ERROR 41
 #define UNEXPECTED_FILE_OPERATION_ERROR 42
-// #define FILESYSTEM_MOUNT_READWRITE_ERROR 43 // Removed support for gonk
+// 43 was previously FILESYSTEM_MOUNT_READWRITE_ERROR, which was gonk-only
+#define UNEXPECTED_XZ_ERROR 43
 #define DELETE_ERROR_EXPECTED_DIR 46
 #define DELETE_ERROR_EXPECTED_FILE 47
 #define RENAME_ERROR_EXPECTED_FILE 48
 
 // Error codes 24-33 and 49-57 are for the Windows maintenance service.
 #define SERVICE_COULD_NOT_COPY_UPDATER 49
 #define SERVICE_STILL_APPLYING_TERMINATED 50
 #define SERVICE_STILL_APPLYING_NO_EXIT_CODE 51
--- a/toolkit/mozapps/update/updater/archivereader.cpp
+++ b/toolkit/mozapps/update/updater/archivereader.cpp
@@ -2,17 +2,16 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <string.h>
 #include <stdlib.h>
 #include <fcntl.h>
-#include "bzlib.h"
 #include "archivereader.h"
 #include "errors.h"
 #ifdef XP_WIN
 #include "nsAlgorithm.h" // Needed by nsVersionComparator.cpp
 #include "updatehelper.h"
 #endif
 
 // These are generated at compile time based on the DER file for the channel
@@ -266,59 +265,30 @@ ArchiveReader::ExtractFileToStream(const
     return READ_ERROR;
 
   return ExtractItemToStream(item, fp);
 }
 
 int
 ArchiveReader::ExtractItemToStream(const MarItem *item, FILE *fp)
 {
-  /* decompress the data chunk by chunk */
-
-  bz_stream strm;
-  int offset, inlen, outlen, ret = OK;
-
-  memset(&strm, 0, sizeof(strm));
-  if (BZ2_bzDecompressInit(&strm, 0, 0) != BZ_OK)
-    return UNEXPECTED_BZIP_ERROR;
-
-  offset = 0;
-  for (;;) {
-    if (!item->length) {
-      ret = UNEXPECTED_MAR_ERROR;
-      break;
-    }
+  // We shouldn't extract from the archive until after we know the signature is
+  // good, so that we don't run a bunch of complicated decompression code on
+  // a file of unknown validity. That means that, if signatures are being
+  // checked, the check should be done before this function is ever called.
+  if (mar_decompress(mArchive) == -1) {
+    return UNEXPECTED_XZ_ERROR;
+  }
 
-    if (offset < (int) item->length && strm.avail_in == 0) {
-      inlen = mar_read(mArchive, item, offset, inbuf, inbuf_size);
-      if (inlen <= 0)
-        return READ_ERROR;
-      offset += inlen;
-      strm.next_in = inbuf;
-      strm.avail_in = inlen;
+  int offset = 0;
+  while (offset < (int)(item->length)) {
+    int inlen = mar_read(mArchive, item, offset, inbuf, inbuf_size);
+    if (inlen <= 0) {
+      return READ_ERROR;
     }
-
-    strm.next_out = outbuf;
-    strm.avail_out = outbuf_size;
-
-    ret = BZ2_bzDecompress(&strm);
-    if (ret != BZ_OK && ret != BZ_STREAM_END) {
-      ret = UNEXPECTED_BZIP_ERROR;
-      break;
-    }
-
-    outlen = outbuf_size - strm.avail_out;
-    if (outlen) {
-      if (fwrite(outbuf, outlen, 1, fp) != 1) {
-        ret = WRITE_ERROR_EXTRACT;
-        break;
-      }
-    }
-
-    if (ret == BZ_STREAM_END) {
-      ret = OK;
-      break;
+    offset += inlen;
+    if (fwrite(inbuf, inlen, 1, fp) != 1) {
+      return WRITE_ERROR_EXTRACT;
     }
   }
 
-  BZ2_bzDecompressEnd(&strm);
-  return ret;
+  return OK;
 }
--- a/toolkit/mozapps/update/updater/archivereader.h
+++ b/toolkit/mozapps/update/updater/archivereader.h
@@ -6,19 +6,20 @@
 
 #ifndef ArchiveReader_h__
 #define ArchiveReader_h__
 
 #include <stdio.h>
 #include "mar.h"
 
 #ifdef XP_WIN
-  typedef WCHAR NS_tchar;
+#include <windows.h>
+typedef WCHAR NS_tchar;
 #else
-  typedef char NS_tchar;
+typedef char NS_tchar;
 #endif
 
 // This class provides an API to extract files from an update archive.
 class ArchiveReader
 {
 public:
   ArchiveReader() : mArchive(nullptr) {}
   ~ArchiveReader() { Close(); }
--- a/toolkit/mozapps/update/updater/updater-common.build
+++ b/toolkit/mozapps/update/updater/updater-common.build
@@ -55,17 +55,16 @@ else:
     USE_LIBS += [
         'updatecommon',
     ]
 
 USE_LIBS += [
     'lzma',
     'mar',
 ]
-
 DEFINES['LZMA_API_STATIC'] = 1
 HOST_DEFINES['LZMA_API_STATIC'] = 1
 
 if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
     have_progressui = 1
     srcs += [
         'progressui_gtk.cpp',
     ]
--- a/toolkit/mozapps/update/updater/updater.cpp
+++ b/toolkit/mozapps/update/updater/updater.cpp
@@ -33,17 +33,17 @@
  *  -----------
  *  method   = "remove" | "rmdir"
  */
 #include "bspatch.h"
 #include "progressui.h"
 #include "archivereader.h"
 #include "readstrings.h"
 #include "errors.h"
-#include "bzlib.h"
+#include "lzma.h"
 
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdarg.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -135,47 +135,16 @@ BOOL PathGetSiblingFilePath(LPWSTR desti
         LogFinish(); \
         return retCode; \
       } \
   }
 #endif
 
 //-----------------------------------------------------------------------------
 
-// This variable lives in libbz2.  It's declared in bzlib_private.h, so we just
-// declare it here to avoid including that entire header file.
-#define BZ2_CRC32TABLE_UNDECLARED
-
-#if MOZ_IS_GCC || defined(__clang__)
-extern "C"  __attribute__((visibility("default"))) unsigned int BZ2_crc32Table[256];
-#undef BZ2_CRC32TABLE_UNDECLARED
-#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
-extern "C" __global unsigned int BZ2_crc32Table[256];
-#undef BZ2_CRC32TABLE_UNDECLARED
-#endif
-#if defined(BZ2_CRC32TABLE_UNDECLARED)
-extern "C" unsigned int BZ2_crc32Table[256];
-#undef BZ2_CRC32TABLE_UNDECLARED
-#endif
-
-static unsigned int
-crc32(const unsigned char *buf, unsigned int len)
-{
-  unsigned int crc = 0xffffffffL;
-
-  const unsigned char *end = buf + len;
-  for (; buf != end; ++buf)
-    crc = (crc << 8) ^ BZ2_crc32Table[(crc >> 24) ^ *buf];
-
-  crc = ~crc;
-  return crc;
-}
-
-//-----------------------------------------------------------------------------
-
 // A simple stack based container for a FILE struct that closes the
 // file descriptor from its destructor.
 class AutoFile
 {
 public:
   explicit AutoFile(FILE* file = nullptr)
     : mFile(file) {
   }
@@ -1522,19 +1491,17 @@ PatchFile::LoadSourceFile(FILE* ofile)
       return READ_ERROR;
     }
 
     r -= c;
     rb += c;
   }
 
   // Verify that the contents of the source file correspond to what we expect.
-
-  unsigned int crc = crc32(buf, header.slen);
-
+  uint32_t crc = lzma_crc32(buf, header.slen, 0);
   if (crc != header.scrc32) {
     LOG(("LoadSourceFile: destination file crc %d does not match expected " \
          "crc %d", crc, header.scrc32));
     return CRC_ERROR;
   }
 
   return OK;
 }