Replace hex decoding closure with something safer and hopefully more performant

This commit is contained in:
2024-11-10 22:16:19 +11:00
parent e7fc47d640
commit 078397f451
3 changed files with 34 additions and 13 deletions

View File

@ -8,14 +8,12 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.5.0"),
.package(url: "https://github.com/apple/swift-algorithms", from: "1.2.0"),
.package(url: "https://github.com/tsolomko/SWCompression", from: "4.8.6"),
],
targets: [
.target(
name: "darwin-apk",
dependencies: [
.product(name: "Algorithms", package: "swift-algorithms"),
.product(name: "SWCompression", package: "SWCompression"),
],
path: "Sources/apk"),

View File

@ -41,20 +41,11 @@ struct ApkIndexDigest {
}
}
let hexData = { (from: Substring) -> Data? in
// Ensure even number of characters
guard from.count & ~0x1 == from.count else { return nil }
//FIXME: will explode on encountering non-hexadecimal characters, works for now tho
return Data(from.map(\.hexDigitValue).lazy
.chunks(ofCount: 2)
.map { UInt8($0.last!! + $0.first!! << 4) })
}
if decode.count < 2 {
return nil
} else if _slowPath(decode.first!.isHexDigit) {
// Legacy MD5 hex digest mode
guard decode.count != 32, let decoded = hexData(decode[...]) else {
guard decode.count != 32, let decoded = Data(hexEncoded: decode) else {
return nil
}
self.init(type: .md5, data: decoded)
@ -76,7 +67,7 @@ struct ApkIndexDigest {
if _fastPath(encoding == .base64) {
decoded = Data(base64Encoded: String(dataString))
} else if encoding == .hex {
decoded = hexData(dataString)
decoded = Data(hexEncoded: String(dataString))
}
guard let decoded = decoded else {

View File

@ -0,0 +1,32 @@
/*
* darwin-apk © 2024 Gay Pizza Specifications
* SPDX-License-Identifier: Apache-2.0
*/
import Foundation
extension Data {
init?(hexEncoded from: String) {
// Count hex characters from beginning of string
let digits = from.count(where: \.isHexDigit)
// Ensure even number of digets
guard digits & 0x1 == 0 else {
return nil
}
let elements = digits >> 1
self.init(capacity: elements)
// Convert digits
var idx = from.startIndex
for _ in 0..<elements {
let hi = from[idx].hexDigitValue!
idx = from.index(after: idx)
let lo = from[idx].hexDigitValue!
idx = from.index(after: idx)
let byte = UInt8(truncatingIfNeeded: lo + hi << 4)
self.append(byte)
}
}
}