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
--- 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;
}