Skip to content

Commit

Permalink
add a progress indicator
Browse files Browse the repository at this point in the history
  • Loading branch information
zhuowei committed Dec 28, 2022
1 parent 96768b6 commit 2e1e5a5
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 71 deletions.
103 changes: 47 additions & 56 deletions WDBFontOverwrite/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,77 +34,68 @@ let fonts = [
name: "Choco Cooky", postScriptName: "Chococooky", repackedPath: "Chococooky.woff2"),
]

struct CustomFont {
var name: String
var targetPath: String
var localPath: String
}

let customFonts = [
CustomFont(
name: "SFUI.ttf", targetPath: "/System/Library/Fonts/CoreUI/SFUI.ttf",
localPath: "CustomSFUI.woff2"),
CustomFont(
name: "Emoji", targetPath: "/System/Library/Fonts/CoreAddition/AppleColorEmoji-160px.ttc",
localPath: "CustomAppleColorEmoji.woff2"),
CustomFont(
name: "PingFang.ttc", targetPath: "/System/Library/Fonts/LanguageSupport/PingFang.ttc",
localPath: "CustomPingFang.woff2"),
]

struct ContentView: View {
@State private var message = "Choose a font."
@State private var progress: Progress!
var body: some View {
ScrollView {
VStack {
Text(message).padding(16)
Text(message).padding(8)
if let progress = progress {
ProgressView(progress)
}
ForEach(fonts, id: \.name) { font in
Button(action: {
message = "Running"
overwriteWithFont(name: font.repackedPath) {
progress = Progress(totalUnitCount: 1)
overwriteWithFont(name: font.repackedPath, progress: progress) {
message = $0
}
}) {
Text(font.name).font(.custom(font.postScriptName, size: 18))
}.padding(8)
}
Button(action: {
message = "Running"
overwriteWithCustomFont(name: "CustomSFUI.woff2") {
message = $0
}
}) {
Text("Custom SFUI.ttf")
}.padding(8)
Button(action: {
message = "Importing"
importCustomFont(name: "CustomSFUI.woff2") {
message = $0
}
}) {
Text("Import custom SFUI.ttf")
}.padding(8)
Button(action: {
message = "Running"
overwriteWithCustomFont(
name: "CustomAppleColorEmoji.woff2",
targetName: "/System/Library/Fonts/CoreAddition/AppleColorEmoji-160px.ttc"
) {
message = $0
}
}) {
Text("Custom emoji")
}.padding(8)
Button(action: {
message = "Importing"
importCustomFont(name: "CustomAppleColorEmoji.woff2") {
message = $0
}
}) {
Text("Import custom emoji")
}.padding(8)
}
Button(action: {
message = "Running"
overwriteWithCustomFont(
name: "CustomPingFang.woff2",
targetName: "/System/Library/Fonts/LanguageSupport/PingFang.ttc"
) {
message = $0
}
}) {
Text("Custom PingFang.ttc")
}.padding(8)
Button(action: {
message = "Importing"
importCustomFont(name: "CustomPingFang.woff2") {
message = $0
Divider()
ForEach(customFonts, id: \.name) { font in
Button(action: {
message = "Running"
progress = Progress(totalUnitCount: 1)
overwriteWithCustomFont(
name: font.localPath, targetName: font.targetPath, progress: progress
) {
message = $0
}
}) {
Text("Custom \(font.name)")
}.padding(8)
Button(action: {
message = "Importing..."
importCustomFont(name: font.localPath) {
message = $0
}
}) {
Text("Import custom \(font.name)")
}.padding(8)
}
}) {
Text("Import custom PingFang.ttc")
}.padding(8)
}
Text(
"Custom fonts require font files that are ported for iOS.\nSee https://github.com/zhuowei/WDBFontOverwrite for details."
).font(.system(size: 12))
Expand Down
44 changes: 29 additions & 15 deletions WDBFontOverwrite/OverwriteFontImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,20 @@
import UIKit
import UniformTypeIdentifiers

func overwriteWithFont(name: String, completion: @escaping (String) -> Void) {
func overwriteWithFont(name: String, progress: Progress, completion: @escaping (String) -> Void) {
let fontURL = Bundle.main.url(
forResource: name, withExtension: nil, subdirectory: "RepackedFonts")!
overwriteWithFont(
fontURL: fontURL, pathToTargetFont: "/System/Library/Fonts/CoreUI/SFUI.ttf", progress: progress,
completion: completion)
}

func overwriteWithFont(
fontURL: URL, pathToTargetFont: String, progress: Progress, completion: @escaping (String) -> Void
) {
DispatchQueue.global(qos: .userInteractive).async {
let fontURL = Bundle.main.url(
forResource: name, withExtension: nil, subdirectory: "RepackedFonts")!
let succeeded = overwriteWithFontImpl(fontURL: fontURL)
let succeeded = overwriteWithFontImpl(
fontURL: fontURL, pathToTargetFont: pathToTargetFont, progress: progress)
DispatchQueue.main.async {
completion(succeeded ? "Success: force close an app to see results" : "Failed")
}
Expand All @@ -22,9 +31,7 @@ func overwriteWithFont(name: String, completion: @escaping (String) -> Void) {
/// Overwrite the system font with the given font using CVE-2022-46689.
/// The font must be specially prepared so that it skips past the last byte in every 16KB page.
/// See BrotliPadding.swift for an implementation that adds this padding to WOFF2 fonts.
func overwriteWithFontImpl(
fontURL: URL, pathToTargetFont: String = "/System/Library/Fonts/CoreUI/SFUI.ttf"
) -> Bool {
func overwriteWithFontImpl(fontURL: URL, pathToTargetFont: String, progress: Progress) -> Bool {
var fontData = try! Data(contentsOf: fontURL)
#if false
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[
Expand Down Expand Up @@ -78,8 +85,17 @@ func overwriteWithFontImpl(
return false
}

// TODO(zhuowei): probably not the right way to use NSProgress...
let overwriteProgress = Progress(totalUnitCount: Int64(fontData.count))
progress.addChild(overwriteProgress, withPendingUnitCount: Int64(1))

// for every 16k chunk, rewrite
print(Date())
for chunkOff in stride(from: 0, to: fontData.count, by: 0x4000) {
print(String(format: "%lx", chunkOff))
if chunkOff % 0x40000 == 0 {
overwriteProgress.completedUnitCount = Int64(chunkOff)
}
// we only rewrite 16383 bytes out of every 16384 bytes.
let dataChunk = fontData[chunkOff..<min(fontData.count, chunkOff + 0x3fff)]
var overwroteOne = false
Expand All @@ -93,14 +109,15 @@ func overwriteWithFontImpl(
break
}
print("try again?!")
sleep(1)
}
guard overwroteOne else {
print("can't overwrite")
return false
}
}
print(Date())
print("successfully overwrote everything")
overwriteProgress.completedUnitCount = Int64(fontData.count)
return true
}

Expand All @@ -115,7 +132,8 @@ func dumpCurrentFont() {
}

func overwriteWithCustomFont(
name: String, targetName: String = "/System/Library/Fonts/CoreUI/SFUI.ttf",
name: String, targetName: String,
progress: Progress,
completion: @escaping (String) -> Void
) {
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[
Expand All @@ -126,12 +144,8 @@ func overwriteWithCustomFont(
completion("No custom font imported")
return
}
DispatchQueue.global(qos: .userInteractive).async {
let succeeded = overwriteWithFontImpl(fontURL: fontURL, pathToTargetFont: targetName)
DispatchQueue.main.async {
completion(succeeded ? "Success: force close an app to see results" : "Failed")
}
}
overwriteWithFont(
fontURL: fontURL, pathToTargetFont: targetName, progress: progress, completion: completion)
}

class WDBImportCustomFontPickerViewControllerDelegate: NSObject, UIDocumentPickerDelegate {
Expand Down
1 change: 1 addition & 0 deletions WDBFontOverwrite/vm_unaligned_copy_switch_race.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ switcheroo_thread(__unused void *arg)
/* wait for main thread to be done setting things up */
pthread_mutex_lock(&ctx->mtx);
if (ctx->done) {
pthread_mutex_unlock(&ctx->mtx);
break;
}
/* switch e0 to RW mapping */
Expand Down

0 comments on commit 2e1e5a5

Please sign in to comment.