From f84188c1dc2a9555d8cead6d2971f968f762690e Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Wed, 11 Jan 2023 22:10:14 +0000 Subject: [PATCH] Bug 1809575 - Replace the use of the external xar tool with a simple python implementation. r=gsvelto Differential Revision: https://phabricator.services.mozilla.com/D166504 --- .../docker/system-symbols-mac/setup.sh | 6 -- .../system-symbols/mac/PackageSymbolDumper.py | 7 ++- .../system-symbols/mac/macpkg.py | 57 +++++++++++++++++++ 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/taskcluster/docker/system-symbols-mac/setup.sh b/taskcluster/docker/system-symbols-mac/setup.sh index f1312dcf1b20..c0c4e766acb3 100644 --- a/taskcluster/docker/system-symbols-mac/setup.sh +++ b/taskcluster/docker/system-symbols-mac/setup.sh @@ -4,12 +4,6 @@ set -v -e -x ncpu=-j$(grep -c ^processor /proc/cpuinfo) WORK=/setup/ -cd $WORK -git clone --depth=1 --single-branch -b system-symbols https://github.com/mozilla/xar xar -cd xar/xar -./autogen.sh --prefix=/builds/worker -make "$ncpu" && make install - cd $WORK git clone --depth=1 --single-branch -b system-symbols-mac https://github.com/gabrielesvelto/libdmg-hfsplus.git cd libdmg-hfsplus diff --git a/tools/crashreporter/system-symbols/mac/PackageSymbolDumper.py b/tools/crashreporter/system-symbols/mac/PackageSymbolDumper.py index 47a582454945..5e63a2f39f3a 100755 --- a/tools/crashreporter/system-symbols/mac/PackageSymbolDumper.py +++ b/tools/crashreporter/system-symbols/mac/PackageSymbolDumper.py @@ -32,7 +32,6 @@ Required tools for Linux: pax gzip tar - xar (http://code.google.com/p/xar/) xpwn's dmg (https://github.com/planetbeing/xpwn) Created on Apr 11, 2012 @@ -50,6 +49,7 @@ import subprocess import tempfile import traceback +from macpkg import Pbzx, uncpio, unxar from scrapesymbols.gathersymbols import process_paths @@ -60,7 +60,9 @@ def expand_pkg(pkg_path, out_path): @param pkg_path: a path to an installer package (.pkg) @param out_path: a path to hold the package contents """ - subprocess.check_call(["xar", "-x", "-C", out_path, "-f", pkg_path]) + for name, content in unxar(open(pkg_path, "rb")): + with open(os.path.join(out_path, name), "wb") as fh: + shutil.copyfileobj(content, fh) def expand_dmg(dmg_path, out_path): @@ -178,7 +180,6 @@ def extract_payload(payload_path, output_path): return True elif header == b"pb": logging.info("Extracting pbzx payload") - from macpkg import Pbzx, uncpio for path, mode, content in uncpio(Pbzx(open(payload_path, "rb"))): if not path or not stat.S_ISREG(mode): diff --git a/tools/crashreporter/system-symbols/mac/macpkg.py b/tools/crashreporter/system-symbols/mac/macpkg.py index 0a8a6ec8411c..6cdee015bda5 100644 --- a/tools/crashreporter/system-symbols/mac/macpkg.py +++ b/tools/crashreporter/system-symbols/mac/macpkg.py @@ -2,8 +2,65 @@ # 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/. +import bz2 import lzma +import os import struct +import zlib +from xml.etree.ElementTree import XML + + +def unxar(fileobj): + magic = fileobj.read(4) + if magic != b"xar!": + raise Exception("Not a XAR?") + + header_size = fileobj.read(2) + header_size = struct.unpack(">H", header_size)[0] + if header_size > 64: + raise Exception( + f"Don't know how to handle a {header_size} bytes XAR header size" + ) + header_size -= 6 # what we've read so far. + header = fileobj.read(header_size) + if len(header) != header_size: + raise Exception("Failed to read XAR header") + ( + version, + compressed_toc_len, + uncompressed_toc_len, + checksum_type, + ) = struct.unpack(">HQQL", header[:22]) + if version != 1: + raise Exception(f"XAR version {version} not supported") + toc = fileobj.read(compressed_toc_len) + base = fileobj.tell() + if len(toc) != compressed_toc_len: + raise Exception("Failed to read XAR TOC") + toc = zlib.decompress(toc) + if len(toc) != uncompressed_toc_len: + raise Exception("Corrupted XAR?") + toc = XML(toc).find("toc") + for f in toc.findall("file"): + if f.find("type").text != "file": + continue + filename = f.find("name").text + data = f.find("data") + length = int(data.find("length").text) + size = int(data.find("size").text) + offset = int(data.find("offset").text) + encoding = data.find("encoding").get("style") + fileobj.seek(base + offset, os.SEEK_SET) + content = Take(fileobj, length) + if encoding == "application/octet-stream": + if length != size: + raise Exception(f"{length} != {size}") + elif encoding == "application/x-bzip2": + content = bz2.BZ2File(content) + else: + raise Exception(f"XAR encoding {encoding} not supported") + + yield filename, content class Pbzx(object):