kdk_handler: Fix some parsing and logic bugs

This commit is contained in:
Dhinak G
2022-10-04 15:21:32 -04:00
parent 1be56542b1
commit 67c9c4633b

View File

@@ -1,9 +1,10 @@
# Kernel Debug Kit downloader # Kernel Debug Kit downloader
import datetime import datetime
from typing import cast import re
import urllib.parse import urllib.parse
from pathlib import Path from pathlib import Path
from typing import cast
import packaging.version import packaging.version
import requests import requests
@@ -27,7 +28,7 @@ class kernel_debug_kit_handler:
print("- Could not fetch KDK list") print("- Could not fetch KDK list")
return None return None
return results.json().sort(key=lambda x: (packaging.version.parse(x["version"]), datetime.datetime.fromisoformat(x["date"])), reverse=True) return sorted(results.json(), key=lambda x: (packaging.version.parse(x["version"]), datetime.datetime.fromisoformat(x["date"])), reverse=True)
def get_closest_match_legacy(self, host_version: str, host_build: str): def get_closest_match_legacy(self, host_version: str, host_build: str):
# Get the closest match to the provided version # Get the closest match to the provided version
@@ -45,26 +46,33 @@ class kernel_debug_kit_handler:
if results.status_code != 200: if results.status_code != 200:
print("- Could not fetch database") print("- Could not fetch database")
return None, "" return None, "", ""
macos_builds = [i for i in results.json()["ios"] if i["osType"] == "macOS"] macos_builds = [i for i in results.json()["ios"] if i["osType"] == "macOS"]
macos_builds.sort(key=lambda x: (packaging.version.parse(x["version"]), datetime.datetime.fromisoformat(x["released"])), reverse=True) # If the version is borked, put it at the bottom of the list
# Would omit it, but can't do that in this lambda
macos_builds.sort(key=lambda x: (packaging.version.parse(re.match(r"\d+\.\d+", x["version"]).group() if re.match(r"\d+\.\d+", x["version"]) else "0.0.0"), datetime.datetime.fromisoformat(x["released"])), reverse=True) # type: ignore
# Iterate through, find build that is closest to the host version # Iterate through, find build that is closest to the host version
# Use date to determine which is closest # Use date to determine which is closest
for build_info in macos_builds: for build_info in macos_builds:
if build_info["osType"] == "macOS": if build_info["osType"] == "macOS":
version = cast(packaging.version.Version, packaging.version.parse(build_info["version"])) raw_version = re.match(r"\d+\.\d+", build_info["version"])
if version == parsed_host_version: if not raw_version:
# Skip if version is borked
continue
version = cast(packaging.version.Version, packaging.version.parse(raw_version.group()))
build = build_info["build"]
if build == host_build:
# Skip, as we want the next closest match # Skip, as we want the next closest match
continue continue
elif version <= parsed_host_version and version.major == parsed_host_version.major and version.minor == parsed_host_version.minor: elif version <= parsed_host_version and version.major == parsed_host_version.major and version.minor == parsed_host_version.minor:
# The KDK list is already sorted by date then version, so the first match is the closest # The KDK list is already sorted by date then version, so the first match is the closest
print(f"- Closest match: {build_info['version']} build {build_info['build']}") print(f"- Closest match: {version} build {build}")
return self.generate_kdk_link(build_info["version"], build_info["build"]), build_info["build"] return self.generate_kdk_link(str(version), build), str(version), build
print("- Could not find a match") print("- Could not find a match")
return None, "" return None, "", ""
def generate_kdk_link(self, version: str, build: str): def generate_kdk_link(self, version: str, build: str):
return f"https://download.developer.apple.com/macOS/Kernel_Debug_Kit_{version}_build_{build}/Kernel_Debug_Kit_{version}_build_{build}.dmg" return f"https://download.developer.apple.com/macOS/Kernel_Debug_Kit_{version}_build_{build}/Kernel_Debug_Kit_{version}_build_{build}.dmg"
@@ -108,6 +116,7 @@ class kernel_debug_kit_handler:
download_link = None download_link = None
closest_match_download_link = None closest_match_download_link = None
closest_version = ""
closest_build = "" closest_build = ""
kdk_list = self.get_available_kdks() kdk_list = self.get_available_kdks()
@@ -118,15 +127,16 @@ class kernel_debug_kit_handler:
for kdk in kdk_list: for kdk in kdk_list:
kdk_version = cast(packaging.version.Version, packaging.version.parse(kdk["version"])) kdk_version = cast(packaging.version.Version, packaging.version.parse(kdk["version"]))
if kdk["build"] == build: if kdk["build"] == build:
download_link = kdk["download_url"] download_link = kdk["url"]
elif not closest_match_download_link and kdk_version <= parsed_version and kdk_version.major == parsed_version.major and kdk_version.minor == parsed_version.minor: elif not closest_match_download_link and kdk_version <= parsed_version and kdk_version.major == parsed_version.major and kdk_version.minor == parsed_version.minor:
# The KDK list is already sorted by date then version, so the first match is the closest # The KDK list is already sorted by date then version, so the first match is the closest
closest_match_download_link = kdk["download_url"] closest_match_download_link = kdk["url"]
closest_version = kdk["version"]
closest_build = kdk["build"] closest_build = kdk["build"]
else: else:
print("- Could not fetch KDK list, falling back to brute force") print("- Could not fetch KDK list, falling back to brute force")
download_link = self.generate_kdk_link(version, build) download_link = self.generate_kdk_link(version, build)
closest_match_download_link, closest_build = self.get_closest_match_legacy(version, build) closest_match_download_link, closest_version, closest_build = self.get_closest_match_legacy(version, build)
print(f"- Downloading Apple KDK for macOS {version} build {build}") print(f"- Downloading Apple KDK for macOS {version} build {build}")
# download_link is None if no matching KDK is found, so we'll fall back to the closest match # download_link is None if no matching KDK is found, so we'll fall back to the closest match
@@ -142,6 +152,7 @@ class kernel_debug_kit_handler:
if closest_match_download_link is None: if closest_match_download_link is None:
return False, "Could not find KDK for host, nor closest match", "" return False, "Could not find KDK for host, nor closest match", ""
print(f"- Closest match: {closest_version} build {closest_build}")
result = self.verify_apple_developer_portal(closest_match_download_link) result = self.verify_apple_developer_portal(closest_match_download_link)
if result == 0: if result == 0: