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
import datetime
from typing import cast
import re
import urllib.parse
from pathlib import Path
from typing import cast
import packaging.version
import requests
@@ -27,7 +28,7 @@ class kernel_debug_kit_handler:
print("- Could not fetch KDK list")
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):
# Get the closest match to the provided version
@@ -45,26 +46,33 @@ class kernel_debug_kit_handler:
if results.status_code != 200:
print("- Could not fetch database")
return None, ""
return None, "", ""
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
# Use date to determine which is closest
for build_info in macos_builds:
if build_info["osType"] == "macOS":
version = cast(packaging.version.Version, packaging.version.parse(build_info["version"]))
if version == parsed_host_version:
raw_version = re.match(r"\d+\.\d+", build_info["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
continue
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
print(f"- Closest match: {build_info['version']} build {build_info['build']}")
return self.generate_kdk_link(build_info["version"], build_info["build"]), build_info["build"]
print(f"- Closest match: {version} build {build}")
return self.generate_kdk_link(str(version), build), str(version), build
print("- Could not find a match")
return None, ""
return None, "", ""
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"
@@ -108,6 +116,7 @@ class kernel_debug_kit_handler:
download_link = None
closest_match_download_link = None
closest_version = ""
closest_build = ""
kdk_list = self.get_available_kdks()
@@ -118,15 +127,16 @@ class kernel_debug_kit_handler:
for kdk in kdk_list:
kdk_version = cast(packaging.version.Version, packaging.version.parse(kdk["version"]))
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:
# 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"]
else:
print("- Could not fetch KDK list, falling back to brute force")
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}")
# 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:
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)
if result == 0: