Bug 1842773 - Part 21: Throw for out-of-bounds in (PossiblyWrapped)TypedArrayLength...
[gecko.git] / build / macosx / catalog.py
blobe3d937ffafb5df090a388ee8342fd82a089bd767
1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 import argparse
6 import plistlib
7 import ssl
8 import sys
9 from io import BytesIO
10 from urllib.request import urlopen
11 from xml.dom import minidom
13 import certifi
14 from mozpack.macpkg import Pbzx, uncpio, unxar
17 def get_english(dict, default=None):
18 english = dict.get("English")
19 if english is None:
20 english = dict.get("en", default)
21 return english
24 def get_content_at(url):
25 ssl_context = ssl.create_default_context(cafile=certifi.where())
26 f = urlopen(url, context=ssl_context)
27 return f.read()
30 def get_plist_at(url):
31 return plistlib.loads(get_content_at(url))
34 def show_package_content(url, digest=None, size=None):
35 package = get_content_at(url)
36 if size is not None and len(package) != size:
37 print(f"Package does not match size given in catalog: {url}", file=sys.stderr)
38 sys.exit(1)
39 # Ideally we'd check the digest, but it's not md5, sha1 or sha256...
40 # if digest is not None and hashlib.???(package).hexdigest() != digest:
41 # print(f"Package does not match digest given in catalog: {url}", file=sys.stderr)
42 # sys.exit(1)
43 for name, content in unxar(BytesIO(package)):
44 if name == "Payload":
45 for path, _, __ in uncpio(Pbzx(content)):
46 if path:
47 print(path.decode("utf-8"))
50 def show_product_info(product, package_id=None):
51 # An alternative here would be to look at the MetadataURLs in
52 # product["Packages"], but going with Distributions allows to
53 # only do one request.
54 dist = get_english(product.get("Distributions"))
55 data = get_content_at(dist)
56 dom = minidom.parseString(data.decode("utf-8"))
57 for pkg_ref in dom.getElementsByTagName("pkg-ref"):
58 if pkg_ref.childNodes:
59 if pkg_ref.hasAttribute("packageIdentifier"):
60 id = pkg_ref.attributes["packageIdentifier"].value
61 else:
62 id = pkg_ref.attributes["id"].value
64 if package_id and package_id != id:
65 continue
67 for child in pkg_ref.childNodes:
68 if child.nodeType != minidom.Node.TEXT_NODE:
69 continue
70 for p in product["Packages"]:
71 if p["URL"].endswith("/" + child.data):
72 if package_id:
73 show_package_content(
74 p["URL"], p.get("Digest"), p.get("Size")
76 else:
77 print(id, p["URL"])
80 def show_products(products, filter=None):
81 for key, product in products.items():
82 metadata_url = product.get("ServerMetadataURL", "")
83 if metadata_url and (not filter or filter in metadata_url):
84 metadata = get_plist_at(metadata_url)
85 localization = get_english(metadata.get("localization", {}), {})
86 title = localization.get("title", None)
87 version = metadata.get("CFBundleShortVersionString", None)
88 print(key, title, version)
91 def main():
92 parser = argparse.ArgumentParser()
93 parser.add_argument(
94 "--catalog",
95 help="URL of the catalog",
96 default="https://swscan.apple.com/content/catalogs/others/index-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog",
98 parser.add_argument(
99 "--filter", help="Only show entries with metadata url matching the filter"
101 parser.add_argument(
102 "what", nargs="?", help="Show packages information about the given entry"
104 args = parser.parse_args()
106 data = get_plist_at(args.catalog)
107 products = data["Products"]
109 if args.what:
110 if args.filter:
111 print(
112 "Cannot use --filter when showing verbose information about an entry",
113 file=sys.stderr,
115 sys.exit(1)
116 product_id, _, package_id = args.what.partition("/")
117 show_product_info(products[product_id], package_id)
118 else:
119 show_products(products, args.filter)
122 if __name__ == "__main__":
123 main()