Skip to content

Commit 4cd308a

Browse files
authored
Merge pull request #13 from swift-libp2p/fix-unaligned-pointer
Fix unaligned pointer
2 parents 3a6ab07 + 352d5b7 commit 4cd308a

File tree

4 files changed

+34
-21
lines changed

4 files changed

+34
-21
lines changed

Sources/Multiaddr/Address.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ extension Address {
9595
switch addrProtocol {
9696
case .tcp, .udp, .dccp, .sctp:
9797
guard addressData.count == 2 else { throw MultiaddrError.parseAddressFail }
98-
return String(addressData.uint16.bigEndian)
98+
guard let uint16 = addressData.uint16 else { throw MultiaddrError.parseAddressFail }
99+
return String(uint16.bigEndian)
99100
case .ip4:
100101
return try IPv4.string(for: addressData)
101102
case .ip6:

Sources/Multiaddr/Extensions/Data+Multiaddr.swift

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,25 @@
1919
import Foundation
2020

2121
extension Data {
22-
var uint16: UInt16 {
23-
withUnsafeBytes {
24-
$0.load(as: UInt16.self)
22+
23+
var uint16: UInt16? {
24+
self.value(ofType: UInt16.self, at: 0, convertEndian: true)
25+
}
26+
27+
var uint32: UInt32? {
28+
self.value(ofType: UInt32.self, at: 0, convertEndian: true)
29+
}
30+
31+
fileprivate func value<T: BinaryInteger>(ofType: T.Type, at offset: Int, convertEndian: Bool = false) -> T? {
32+
let byteCount = MemoryLayout<T>.size
33+
let startIndex = self.index(self.startIndex, offsetBy: offset)
34+
let endIndex = self.index(startIndex, offsetBy: byteCount)
35+
guard self.endIndex >= endIndex else { return nil }
36+
let bytes = self[startIndex..<endIndex]
37+
if convertEndian {
38+
return bytes.reversed().reduce(0) { T($0) << 8 + T($1) }
39+
} else {
40+
return bytes.reduce(0) { T($0) << 8 + T($1) }
2541
}
2642
}
2743
}

Sources/Multiaddr/Protocol Helpers/IPV4.swift

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,11 @@ struct IPv4 {
4141
guard data.count == MemoryLayout<UInt32>.size else {
4242
throw MultiaddrError.parseIPv4AddressFail
4343
}
44+
guard let uint32 = data.uint32 else {
45+
throw MultiaddrError.parseIPv4AddressFail
46+
}
4447
var output = Data(count: Int(INET_ADDRSTRLEN))
45-
var address = in_addr(s_addr: data.uint32)
48+
var address = in_addr(s_addr: uint32)
4649

4750
guard
4851
let presentationBytes = output.withUnsafeMutableBytes({
@@ -59,14 +62,6 @@ struct IPv4 {
5962
}
6063
}
6164

62-
extension Data {
63-
var uint32: UInt32 {
64-
withUnsafeBytes {
65-
$0.load(as: UInt32.self)
66-
}
67-
}
68-
}
69-
7065
extension BinaryInteger {
7166
// returns little endian; use .bigEndian.bytes for BE.
7267
var bytes: Data {

Sources/Multiaddr/Protocol Helpers/Onion.swift

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ struct Onion {
3434
guard let portValue = UInt16(port) else { throw MultiaddrError.invalidPortValue }
3535
guard portValue != 0 else { throw MultiaddrError.invalidPortValue }
3636

37-
//base32DecodeToData(host)
3837
guard var onionData = try? BaseEncoding.decode(host, as: .base32).data else {
3938
throw MultiaddrError.invalidOnionHostAddress
4039
}
@@ -48,12 +47,14 @@ struct Onion {
4847

4948
static func string(for data: Data) throws -> String {
5049
guard data.count == 12 else { throw MultiaddrError.invalidOnionHostAddress }
50+
5151
let addressBytes = data.prefix(10)
52+
let addressEncodedString = addressBytes.asString(base: .base32).lowercased()
53+
5254
let portBytes = data.suffix(2)
55+
guard let port = portBytes.uint16 else { throw MultiaddrError.invalidPortValue }
56+
let portString = String(port.bigEndian)
5357

54-
//base32Encode(addressBytes).lowercased()
55-
let addressEncodedString = addressBytes.asString(base: .base32).lowercased()
56-
let portString = String(portBytes.uint16.bigEndian)
5758
return "\(addressEncodedString):\(portString)"
5859
}
5960
}
@@ -73,7 +74,6 @@ struct Onion3 {
7374
guard let portValue = UInt16(port) else { throw MultiaddrError.invalidPortValue }
7475
guard portValue != 0 else { throw MultiaddrError.invalidPortValue }
7576

76-
//base32DecodeToData(host)
7777
guard var onionData = try? BaseEncoding.decode(host, as: .base32).data else {
7878
throw MultiaddrError.invalidOnionHostAddress
7979
}
@@ -88,11 +88,12 @@ struct Onion3 {
8888
static func string(for data: Data) throws -> String {
8989
//guard data.count == 52 else { throw MultiaddrError.invalidOnionHostAddress }
9090
let portBytes = Data(data.suffix(2))
91-
let addressBytes = Data(data.dropLast(2))
91+
guard let port = portBytes.uint16 else { throw MultiaddrError.invalidPortValue }
92+
let portString = String(port.bigEndian)
9293

93-
//base32Encode(addressBytes).lowercased()
94+
let addressBytes = Data(data.dropLast(2))
9495
let addressEncodedString = addressBytes.asString(base: .base32).lowercased()
95-
let portString = String(portBytes.uint16.bigEndian)
96+
9697
return "\(addressEncodedString):\(portString)"
9798
}
9899
}

0 commit comments

Comments
 (0)