diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj
index 4caedb50a..b97983858 100644
--- a/Session.xcodeproj/project.pbxproj
+++ b/Session.xcodeproj/project.pbxproj
@@ -7810,7 +7810,7 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
COMPILE_LIB_SESSION = "";
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 567;
+ CURRENT_PROJECT_VERSION = 569;
ENABLE_BITCODE = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@@ -7890,7 +7890,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Distribution";
COMPILE_LIB_SESSION = "";
- CURRENT_PROJECT_VERSION = 567;
+ CURRENT_PROJECT_VERSION = 569;
ENABLE_BITCODE = NO;
ENABLE_MODULE_VERIFIER = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -8075,6 +8075,7 @@
GENERATE_INFOPLIST_FILE = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.oxen.SessionSnodeKitTests;
PRODUCT_NAME = SessionSnodeKitTests;
+ SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -8085,6 +8086,7 @@
GENERATE_INFOPLIST_FILE = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.oxen.SessionSnodeKitTests;
PRODUCT_NAME = SessionSnodeKitTests;
+ SWIFT_VERSION = 5.0;
};
name = App_Store_Release;
};
@@ -8279,14 +8281,20 @@
FD860CBF2D6E981900BBE29C /* Debug_Compile_LibSession */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ GENERATE_INFOPLIST_FILE = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = io.oxen.SessionSnodeKitTests;
PRODUCT_NAME = SessionSnodeKitTests;
+ SWIFT_VERSION = 5.0;
};
name = Debug_Compile_LibSession;
};
FD860CC02D6E981900BBE29C /* App_Store_Release_Compile_LibSession */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ GENERATE_INFOPLIST_FILE = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = io.oxen.SessionSnodeKitTests;
PRODUCT_NAME = SessionSnodeKitTests;
+ SWIFT_VERSION = 5.0;
};
name = App_Store_Release_Compile_LibSession;
};
@@ -8413,7 +8421,7 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
COMPILE_LIB_SESSION = YES;
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 567;
+ CURRENT_PROJECT_VERSION = 569;
ENABLE_BITCODE = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@@ -9051,7 +9059,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Distribution";
COMPILE_LIB_SESSION = YES;
- CURRENT_PROJECT_VERSION = 567;
+ CURRENT_PROJECT_VERSION = 569;
ENABLE_BITCODE = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
diff --git a/Session.xcodeproj/xcshareddata/xcschemes/Session.xcscheme b/Session.xcodeproj/xcshareddata/xcschemes/Session.xcscheme
index 9f0430f09..ad1576e05 100644
--- a/Session.xcodeproj/xcshareddata/xcschemes/Session.xcscheme
+++ b/Session.xcodeproj/xcshareddata/xcschemes/Session.xcscheme
@@ -20,34 +20,6 @@
ReferencedContainer = "container:Session.xcodeproj">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ shouldUseLaunchSchemeArgsEnv = "YES">
+
+
+
+
AnyPublisher {
let updateNavigationBackStack: () -> Void = {
@@ -2610,11 +2607,11 @@ extension ConversationVC {
else { return Just(()).eraseToAnyPublisher() }
return viewModel.dependencies[singleton: .storage]
- .writePublisher { [displayName = self.viewModel.threadData.displayName, dependencies = viewModel.dependencies] db in
- // If we aren't creating a new thread (ie. sending a message request) then send a
- // messageRequestResponse back to the sender (this allows the sender to know that
- // they have been approved and can now use this contact in closed groups)
- if !isNewThread {
+ .writePublisher { [dependencies = viewModel.dependencies] db in
+ /// If this isn't a draft thread (ie. sending a message request) then send a `messageRequestResponse`
+ /// back to the sender (this allows the sender to know that they have been approved and can now use this
+ /// contact in closed groups)
+ if !isDraft {
_ = try? Interaction(
threadId: threadId,
threadVariant: threadVariant,
@@ -2648,7 +2645,7 @@ extension ConversationVC {
db,
Contact.Columns.isApproved.set(to: true),
Contact.Columns.didApproveMe
- .set(to: contact.didApproveMe || !isNewThread),
+ .set(to: contact.didApproveMe || !isDraft),
using: dependencies
)
}
@@ -2673,8 +2670,8 @@ extension ConversationVC {
return viewModel.dependencies[singleton: .storage]
.writePublisher { [dependencies = viewModel.dependencies] db in
- /// Remove any existing `infoGroupInfoInvited` interactions from the group (don't want to have a duplicate one from
- /// inside the group history)
+ /// Remove any existing `infoGroupInfoInvited` interactions from the group (don't want to have a
+ /// duplicate one from inside the group history)
_ = try Interaction
.filter(Interaction.Columns.threadId == group.id)
.filter(Interaction.Columns.variant == Interaction.Variant.infoGroupInfoInvited)
@@ -2691,10 +2688,10 @@ extension ConversationVC {
isHidden: false
).upsert(db)
- /// If we aren't creating a new thread (ie. sending a message request) and the user is not an admin
- /// then schedule sending a `GroupUpdateInviteResponseMessage` to the group (this allows
- /// other members to know that the user has joined the group)
- if !isNewThread && group.groupIdentityPrivateKey == nil {
+ /// If this isn't a draft thread (ie. sending a message request) and the user is not an admin then schedule
+ /// sending a `GroupUpdateInviteResponseMessage` to the group (this allows other members to
+ /// know that the user has joined the group)
+ if !isDraft && group.groupIdentityPrivateKey == nil {
try MessageSender.send(
db,
message: GroupUpdateInviteResponseMessage(
@@ -2733,7 +2730,8 @@ extension ConversationVC {
approveMessageRequestIfNeeded(
for: self.viewModel.threadData.threadId,
threadVariant: self.viewModel.threadData.threadVariant,
- isNewThread: false,
+ displayName: self.viewModel.threadData.displayName,
+ isDraft: (self.viewModel.threadData.threadIsDraft == true),
timestampMs: viewModel.dependencies[cache: .snodeAPI].currentOffsetTimestampMs()
).sinkUntilComplete()
}
diff --git a/SessionMessagingKit/Crypto/Crypto+SessionMessagingKit.swift b/SessionMessagingKit/Crypto/Crypto+SessionMessagingKit.swift
index d8d090bf9..902c21ab4 100644
--- a/SessionMessagingKit/Crypto/Crypto+SessionMessagingKit.swift
+++ b/SessionMessagingKit/Crypto/Crypto+SessionMessagingKit.swift
@@ -76,36 +76,35 @@ public extension Crypto.Generator {
args: [messages, recipients, ed25519PrivateKey, domain]
) {
var outLen: Int = 0
- var cMessages: [UnsafePointer?] = (try? (messages
- .map { message -> [UInt8] in Array(message) }
- .unsafeCopyUInt8Array()))
- .defaulting(to: [])
- var messageSizes: [Int] = messages.map { $0.count }
- var cRecipients: [UnsafePointer?] = (try? (recipients
- .map { recipient -> [UInt8] in recipient.publicKey }
- .unsafeCopyUInt8Array()))
- .defaulting(to: [])
- var secretKey: [UInt8] = ed25519PrivateKey
- var cDomain: [CChar] = try domain.cString(using: .utf8) ?? { throw LibSessionError.invalidCConversion }()
- let cEncryptedDataPtr: UnsafeMutablePointer? = session_encrypt_for_multiple_simple_ed25519(
- &outLen,
- &cMessages,
- &messageSizes,
- messages.count,
- &cRecipients,
- recipients.count,
- &secretKey,
- &cDomain,
- nil,
- 0
- )
-
- let encryptedData: Data? = cEncryptedDataPtr.map { Data(bytes: $0, count: outLen) }
- cMessages.forEach { $0?.deallocate() }
- cRecipients.forEach { $0?.deallocate() }
- cEncryptedDataPtr?.deallocate()
-
- return try encryptedData ?? { throw MessageSenderError.encryptionFailed }()
+ return try messages.map { Array($0) }.withUnsafeUInt8CArray { cMessages in
+ try recipients.map { Array($0.publicKey) }.withUnsafeUInt8CArray { cRecipients in
+ var messageSizes: [Int] = messages.map { $0.count }
+ var secretKey: [UInt8] = ed25519PrivateKey
+ var cDomain: [CChar] = try domain.cString(using: .utf8) ?? {
+ throw LibSessionError.invalidCConversion
+ }()
+
+ let cEncryptedDataPtr: UnsafeMutablePointer? = session_encrypt_for_multiple_simple_ed25519(
+ &outLen,
+ cMessages.baseAddress,
+ &messageSizes,
+ messages.count,
+ cRecipients.baseAddress,
+ recipients.count,
+ &secretKey,
+ &cDomain,
+ nil,
+ 0
+ )
+
+ let encryptedData: Data? = cEncryptedDataPtr.map { Data(bytes: $0, count: outLen) }
+ cMessages.forEach { $0?.deallocate() }
+ cRecipients.forEach { $0?.deallocate() }
+ cEncryptedDataPtr?.deallocate()
+
+ return try encryptedData ?? { throw MessageSenderError.encryptionFailed }()
+ }
+ }
}
}
}
diff --git a/SessionMessagingKit/LibSession/Config Handling/LibSession+GroupKeys.swift b/SessionMessagingKit/LibSession/Config Handling/LibSession+GroupKeys.swift
index b2e404070..5cba9d169 100644
--- a/SessionMessagingKit/LibSession/Config Handling/LibSession+GroupKeys.swift
+++ b/SessionMessagingKit/LibSession/Config Handling/LibSession+GroupKeys.swift
@@ -107,33 +107,27 @@ internal extension LibSession {
throw LibSessionError.invalidConfigObject
}
- var cMemberIds: [UnsafePointer?] = ( try? (memberIds
- .map { id in id.cString(using: .utf8) }
- .unsafeCopyCStringArray()))
- .defaulting(to: [])
-
- defer { cMemberIds.forEach { $0?.deallocate() } }
-
- // Performing a `key_supplement` returns the supplemental key changes, since our state doesn't care
- // about the `GROUP_KEYS` needed for other members this change won't result in the `GROUP_KEYS` config
- // going into a pending state or the `ConfigurationSyncJob` getting triggered so return the data so that
- // the caller can push it directly
- var cSupplementData: UnsafeMutablePointer!
- var cSupplementDataLen: Int = 0
-
- guard
- groups_keys_key_supplement(conf, &cMemberIds, cMemberIds.count, &cSupplementData, &cSupplementDataLen),
- let cSupplementData: UnsafeMutablePointer = cSupplementData
- else { throw LibSessionError.failedToKeySupplementGroup }
-
- // Must deallocate on success
- let supplementData: Data = Data(
- bytes: cSupplementData,
- count: cSupplementDataLen
- )
- cSupplementData.deallocate()
-
- return supplementData
+ return try memberIds.withUnsafeCStrArray { cMemberIds in
+ /// Performing a `key_supplement` returns the supplemental key changes, since our state doesn't care about the
+ /// `GROUP_KEYS` needed for other members this change won't result in the `GROUP_KEYS` config going into a pending
+ /// state or the `ConfigurationSyncJob` getting triggered so return the data so that the caller can push it directly
+ var cSupplementData: UnsafeMutablePointer!
+ var cSupplementDataLen: Int = 0
+
+ guard
+ groups_keys_key_supplement(conf, cMemberIds.baseAddress, cMemberIds.count, &cSupplementData, &cSupplementDataLen),
+ let cSupplementData: UnsafeMutablePointer = cSupplementData
+ else { throw LibSessionError.failedToKeySupplementGroup }
+
+ // Must deallocate on success
+ let supplementData: Data = Data(
+ bytes: cSupplementData,
+ count: cSupplementDataLen
+ )
+ cSupplementData.deallocate()
+
+ return supplementData
+ }
}
}
diff --git a/SessionMessagingKit/LibSession/Types/Config.swift b/SessionMessagingKit/LibSession/Types/Config.swift
index b9ee340d9..d6eee8374 100644
--- a/SessionMessagingKit/LibSession/Types/Config.swift
+++ b/SessionMessagingKit/LibSession/Types/Config.swift
@@ -216,10 +216,9 @@ public extension LibSession {
}
let result: [String] = [String](
- pointer: hashList.pointee.value,
- count: hashList.pointee.len,
- defaultValue: []
- )
+ cStringArray: hashList.pointee.value,
+ count: hashList.pointee.len
+ ).defaulting(to: [])
hashList.deallocate()
return result
@@ -230,10 +229,9 @@ public extension LibSession {
}
let result: [String] = [String](
- pointer: hashList.pointee.value,
- count: hashList.pointee.len,
- defaultValue: []
- )
+ cStringArray: hashList.pointee.value,
+ count: hashList.pointee.len
+ ).defaulting(to: [])
hashList.deallocate()
return result
@@ -251,10 +249,9 @@ public extension LibSession {
}
let result: [String] = [String](
- pointer: hashList.pointee.value,
- count: hashList.pointee.len,
- defaultValue: []
- )
+ cStringArray: hashList.pointee.value,
+ count: hashList.pointee.len
+ ).defaulting(to: [])
hashList.deallocate()
return result
@@ -266,64 +263,41 @@ public extension LibSession {
case .userProfile(let conf), .contacts(let conf),
.convoInfoVolatile(let conf), .userGroups(let conf),
.groupInfo(let conf), .groupMembers(let conf):
- var mergeHashes: [UnsafePointer?] = (try? (messages
- .compactMap { message in message.serverHash.cString(using: .utf8) }
- .unsafeCopyCStringArray()))
- .defaulting(to: [])
- var mergeData: [UnsafePointer?] = (try? (messages
- .map { message -> [UInt8] in Array(message.data) }
- .unsafeCopyUInt8Array()))
- .defaulting(to: [])
- defer {
- mergeHashes.forEach { $0?.deallocate() }
- mergeData.forEach { $0?.deallocate() }
- }
-
- guard
- mergeHashes.count == messages.count,
- mergeData.count == messages.count,
- mergeHashes.allSatisfy({ $0 != nil }),
- mergeData.allSatisfy({ $0 != nil })
- else {
- Log.error(.libSession, "Failed to correctly allocate merge data")
- return nil
- }
-
- var mergeSize: [size_t] = messages.map { size_t($0.data.count) }
- let mergedHashesPtr: UnsafeMutablePointer? = config_merge(
- conf,
- &mergeHashes,
- &mergeData,
- &mergeSize,
- messages.count
- )
-
- // If we got an error then throw it
- try LibSessionError.throwIfNeeded(conf)
-
- // Get the list of hashes from the config (to determine which were successful)
- let mergedHashes: [String] = mergedHashesPtr
- .map { ptr in
- [String](
- pointer: ptr.pointee.value,
- count: ptr.pointee.len,
- defaultValue: []
+ return try messages.map { $0.serverHash }.withUnsafeCStrArray { cMergehashes in
+ try messages.map { Array($0.data) }.withUnsafeUInt8CArray { cMergeData in
+ var mergeSize: [size_t] = messages.map { size_t($0.data.count) }
+ let mergedHashesPtr: UnsafeMutablePointer? = config_merge(
+ conf,
+ cMergehashes.baseAddress,
+ cMergeData.baseAddress,
+ &mergeSize,
+ messages.count
)
+
+ // If we got an error then throw it
+ try LibSessionError.throwIfNeeded(conf)
+
+ // Get the list of hashes from the config (to determine which were successful)
+ let mergedHashes: [String] = mergedHashesPtr
+ .map { ptr in
+ [String](cStringArray: ptr.pointee.value, count: ptr.pointee.len)
+ .defaulting(to: [])
+ }
+ .defaulting(to: [])
+ mergedHashesPtr?.deallocate()
+
+ if mergedHashes.count != messages.count {
+ Log.warn(.libSession, "Unable to merge \(messages[0].namespace) messages (\(mergedHashes.count)/\(messages.count))")
+ }
+
+ return messages
+ .filter { mergedHashes.contains($0.serverHash) }
+ .map { $0.serverTimestampMs }
+ .sorted()
+ .last
}
- .defaulting(to: [])
- mergedHashesPtr?.deallocate()
-
- if mergedHashes.count != messages.count {
- Log.warn(.libSession, "Unable to merge \(messages[0].namespace) messages (\(mergedHashes.count)/\(messages.count))")
}
- return messages
- .filter { mergedHashes.contains($0.serverHash) }
- .map { $0.serverTimestampMs }
- .sorted()
- .last
-
-
case .groupKeys(let conf, let infoConf, let membersConf):
let successfulMergeTimestamps: [Int64] = try messages
.map { message -> (Bool, Int64) in
diff --git a/SessionMessagingKitTests/LibSession/LibSessionUtilSpec.swift b/SessionMessagingKitTests/LibSession/LibSessionUtilSpec.swift
index 41baf5fb6..816888578 100644
--- a/SessionMessagingKitTests/LibSession/LibSessionUtilSpec.swift
+++ b/SessionMessagingKitTests/LibSession/LibSessionUtilSpec.swift
@@ -402,7 +402,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData: [UnsafePointer?] = [UnsafePointer(pushData4.pointee.config)]
var mergeSize: [Int] = [pushData4.pointee.config_len]
let mergedHashes: UnsafeMutablePointer? = config_merge(conf, &mergeHashes, &mergeData, &mergeSize, 1)
- expect([String](pointer: mergedHashes?.pointee.value, count: mergedHashes?.pointee.len))
+ expect([String](cStringArray: mergedHashes?.pointee.value, count: mergedHashes?.pointee.len))
.to(equal(["fakehash2"]))
config_confirm_pushed(conf2, pushData4.pointee.seqno, &cFakeHash2)
mergeHashes.forEach { $0?.deallocate() }
@@ -465,9 +465,9 @@ fileprivate extension LibSessionUtilSpec {
let pushData6Data: Data = Data(bytes: pushData6.pointee.config, count: pushData6.pointee.config_len)
let pushData7Data: Data = Data(bytes: pushData7.pointee.config, count: pushData7.pointee.config_len)
expect(pushData6Data).toNot(equal(pushData7Data))
- expect([String](pointer: pushData6.pointee.obsolete, count: pushData6.pointee.obsolete_len))
+ expect([String](cStringArray: pushData6.pointee.obsolete, count: pushData6.pointee.obsolete_len))
.to(equal([fakeHash2]))
- expect([String](pointer: pushData7.pointee.obsolete, count: pushData7.pointee.obsolete_len))
+ expect([String](cStringArray: pushData7.pointee.obsolete, count: pushData7.pointee.obsolete_len))
.to(equal([fakeHash2]))
let fakeHash3a: String = "fakehash3a"
@@ -481,7 +481,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData2: [UnsafePointer?] = [UnsafePointer(pushData7.pointee.config)]
var mergeSize2: [Int] = [pushData7.pointee.config_len]
let mergedHashes2: UnsafeMutablePointer? = config_merge(conf, &mergeHashes2, &mergeData2, &mergeSize2, 1)
- expect([String](pointer: mergedHashes2?.pointee.value, count: mergedHashes2?.pointee.len))
+ expect([String](cStringArray: mergedHashes2?.pointee.value, count: mergedHashes2?.pointee.len))
.to(equal(["fakehash3b"]))
expect(config_needs_push(conf)).to(beTrue())
mergeHashes2.forEach { $0?.deallocate() }
@@ -492,7 +492,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData3: [UnsafePointer?] = [UnsafePointer(pushData6.pointee.config)]
var mergeSize3: [Int] = [pushData6.pointee.config_len]
let mergedHashes3: UnsafeMutablePointer? = config_merge(conf2, &mergeHashes3, &mergeData3, &mergeSize3, 1)
- expect([String](pointer: mergedHashes3?.pointee.value, count: mergedHashes3?.pointee.len))
+ expect([String](cStringArray: mergedHashes3?.pointee.value, count: mergedHashes3?.pointee.len))
.to(equal(["fakehash3a"]))
expect(config_needs_push(conf2)).to(beTrue())
mergeHashes3.forEach { $0?.deallocate() }
@@ -508,9 +508,9 @@ fileprivate extension LibSessionUtilSpec {
let pushData8Data: Data = Data(bytes: pushData8.pointee.config, count: pushData8.pointee.config_len)
let pushData9Data: Data = Data(bytes: pushData9.pointee.config, count: pushData9.pointee.config_len)
expect(pushData8Data).to(equal(pushData9Data))
- expect([String](pointer: pushData8.pointee.obsolete, count: pushData8.pointee.obsolete_len))
+ expect([String](cStringArray: pushData8.pointee.obsolete, count: pushData8.pointee.obsolete_len))
.to(equal([fakeHash3b, fakeHash3a]))
- expect([String](pointer: pushData9.pointee.obsolete, count: pushData9.pointee.obsolete_len))
+ expect([String](cStringArray: pushData9.pointee.obsolete, count: pushData9.pointee.obsolete_len))
.to(equal([fakeHash3a, fakeHash3b]))
let fakeHash4: String = "fakeHash4"
@@ -712,7 +712,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData: [UnsafePointer?] = ((try? [expPush1Encrypted].unsafeCopyUInt8Array()) ?? [])
var mergeSize: [Int] = [expPush1Encrypted.count]
let mergedHashes: UnsafeMutablePointer? = config_merge(conf2, &mergeHashes, &mergeData, &mergeSize, 1)
- expect([String](pointer: mergedHashes?.pointee.value, count: mergedHashes?.pointee.len))
+ expect([String](cStringArray: mergedHashes?.pointee.value, count: mergedHashes?.pointee.len))
.to(equal(["fakehash1"]))
mergeHashes.forEach { $0?.deallocate() }
mergeData.forEach { $0?.deallocate() }
@@ -795,7 +795,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData2: [UnsafePointer?] = [UnsafePointer(pushData3.pointee.config)]
var mergeSize2: [Int] = [pushData3.pointee.config_len]
let mergedHashes2: UnsafeMutablePointer? = config_merge(conf2, &mergeHashes2, &mergeData2, &mergeSize2, 1)
- expect([String](pointer: mergedHashes2?.pointee.value, count: mergedHashes2?.pointee.len))
+ expect([String](cStringArray: mergedHashes2?.pointee.value, count: mergedHashes2?.pointee.len))
.to(equal(["fakehash2"]))
mergeHashes2.forEach { $0?.deallocate() }
mergedHashes2?.deallocate()
@@ -805,7 +805,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData3: [UnsafePointer?] = [UnsafePointer(pushData4.pointee.config)]
var mergeSize3: [Int] = [pushData4.pointee.config_len]
let mergedHashes3: UnsafeMutablePointer? = config_merge(conf, &mergeHashes3, &mergeData3, &mergeSize3, 1)
- expect([String](pointer: mergedHashes3?.pointee.value, count: mergedHashes3?.pointee.len))
+ expect([String](cStringArray: mergedHashes3?.pointee.value, count: mergedHashes3?.pointee.len))
.to(equal(["fakehash3"]))
mergeHashes3.forEach { $0?.deallocate() }
mergedHashes3?.deallocate()
@@ -1021,7 +1021,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData: [UnsafePointer?] = [UnsafePointer(pushData2.pointee.config)]
var mergeSize: [Int] = [pushData2.pointee.config_len]
let mergedHashes: UnsafeMutablePointer? = config_merge(conf, &mergeHashes, &mergeData, &mergeSize, 1)
- expect([String](pointer: mergedHashes?.pointee.value, count: mergedHashes?.pointee.len))
+ expect([String](cStringArray: mergedHashes?.pointee.value, count: mergedHashes?.pointee.len))
.to(equal(["fakehash2"]))
config_confirm_pushed(conf, pushData2.pointee.seqno, &cFakeHash2)
mergeHashes.forEach { $0?.deallocate() }
@@ -1188,7 +1188,7 @@ fileprivate extension LibSessionUtilSpec {
// testing:
let pushData1: UnsafeMutablePointer = config_push(conf)
expect(pushData1.pointee.seqno).to(equal(0))
- expect([String](pointer: pushData1.pointee.obsolete, count: pushData1.pointee.obsolete_len))
+ expect([String](cStringArray: pushData1.pointee.obsolete, count: pushData1.pointee.obsolete_len))
.to(beEmpty())
expect(pushData1.pointee.config_len).to(equal(432))
pushData1.deallocate()
@@ -1286,7 +1286,7 @@ fileprivate extension LibSessionUtilSpec {
// dumps; even though we changed two fields here).
let pushData2: UnsafeMutablePointer = config_push(conf)
expect(pushData2.pointee.seqno).to(equal(1))
- expect([String](pointer: pushData2.pointee.obsolete, count: pushData2.pointee.obsolete_len))
+ expect([String](cStringArray: pushData2.pointee.obsolete, count: pushData2.pointee.obsolete_len))
.to(beEmpty())
// Pretend we uploaded it
@@ -1310,12 +1310,12 @@ fileprivate extension LibSessionUtilSpec {
let pushData3: UnsafeMutablePointer = config_push(conf)
expect(pushData3.pointee.seqno).to(equal(1))
- expect([String](pointer: pushData3.pointee.obsolete, count: pushData3.pointee.obsolete_len))
+ expect([String](cStringArray: pushData3.pointee.obsolete, count: pushData3.pointee.obsolete_len))
.to(beEmpty())
pushData3.deallocate()
let currentHashes1: UnsafeMutablePointer? = config_current_hashes(conf)
- expect([String](pointer: currentHashes1?.pointee.value, count: currentHashes1?.pointee.len))
+ expect([String](cStringArray: currentHashes1?.pointee.value, count: currentHashes1?.pointee.len))
.to(equal(["fakehash1"]))
currentHashes1?.deallocate()
@@ -1325,12 +1325,12 @@ fileprivate extension LibSessionUtilSpec {
let pushData4: UnsafeMutablePointer = config_push(conf2)
expect(pushData4.pointee.seqno).to(equal(1))
expect(config_needs_dump(conf2)).to(beFalse())
- expect([String](pointer: pushData4.pointee.obsolete, count: pushData4.pointee.obsolete_len))
+ expect([String](cStringArray: pushData4.pointee.obsolete, count: pushData4.pointee.obsolete_len))
.to(beEmpty())
pushData4.deallocate()
let currentHashes2: UnsafeMutablePointer? = config_current_hashes(conf2)
- expect([String](pointer: currentHashes2?.pointee.value, count: currentHashes2?.pointee.len))
+ expect([String](cStringArray: currentHashes2?.pointee.value, count: currentHashes2?.pointee.len))
.to(equal(["fakehash1"]))
currentHashes2?.deallocate()
@@ -1440,11 +1440,11 @@ fileprivate extension LibSessionUtilSpec {
let pushData7: UnsafeMutablePointer = config_push(conf2)
expect(pushData7.pointee.seqno).to(equal(2))
config_confirm_pushed(conf2, pushData7.pointee.seqno, &cFakeHash2)
- expect([String](pointer: pushData7.pointee.obsolete, count: pushData7.pointee.obsolete_len))
+ expect([String](cStringArray: pushData7.pointee.obsolete, count: pushData7.pointee.obsolete_len))
.to(equal([fakeHash1]))
let currentHashes3: UnsafeMutablePointer? = config_current_hashes(conf2)
- expect([String](pointer: currentHashes3?.pointee.value, count: currentHashes3?.pointee.len))
+ expect([String](cStringArray: currentHashes3?.pointee.value, count: currentHashes3?.pointee.len))
.to(equal([fakeHash2]))
currentHashes3?.deallocate()
@@ -1464,7 +1464,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData1: [UnsafePointer?] = [UnsafePointer(pushData8.pointee.config)]
var mergeSize1: [Int] = [pushData8.pointee.config_len]
let mergedHashes1: UnsafeMutablePointer? = config_merge(conf, &mergeHashes1, &mergeData1, &mergeSize1, 1)
- expect([String](pointer: mergedHashes1?.pointee.value, count: mergedHashes1?.pointee.len))
+ expect([String](cStringArray: mergedHashes1?.pointee.value, count: mergedHashes1?.pointee.len))
.to(equal(["fakehash2"]))
mergeHashes1.forEach { $0?.deallocate() }
mergedHashes1?.deallocate()
@@ -1509,11 +1509,11 @@ fileprivate extension LibSessionUtilSpec {
config_confirm_pushed(conf2, pushData10.pointee.seqno, &cFakeHash3)
expect(pushData10.pointee.seqno).to(equal(3))
- expect([String](pointer: pushData10.pointee.obsolete, count: pushData10.pointee.obsolete_len))
+ expect([String](cStringArray: pushData10.pointee.obsolete, count: pushData10.pointee.obsolete_len))
.to(equal([fakeHash2]))
let currentHashes4: UnsafeMutablePointer? = config_current_hashes(conf2)
- expect([String](pointer: currentHashes4?.pointee.value, count: currentHashes4?.pointee.len))
+ expect([String](cStringArray: currentHashes4?.pointee.value, count: currentHashes4?.pointee.len))
.to(equal([fakeHash3]))
currentHashes4?.deallocate()
@@ -1521,7 +1521,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData2: [UnsafePointer?] = [UnsafePointer(pushData10.pointee.config)]
var mergeSize2: [Int] = [pushData10.pointee.config_len]
let mergedHashes2: UnsafeMutablePointer? = config_merge(conf, &mergeHashes2, &mergeData2, &mergeSize2, 1)
- expect([String](pointer: mergedHashes2?.pointee.value, count: mergedHashes2?.pointee.len))
+ expect([String](cStringArray: mergedHashes2?.pointee.value, count: mergedHashes2?.pointee.len))
.to(equal(["fakehash3"]))
mergeHashes2.forEach { $0?.deallocate() }
mergedHashes2?.deallocate()
@@ -1556,7 +1556,7 @@ fileprivate extension LibSessionUtilSpec {
let pushData11: UnsafeMutablePointer = config_push(conf)
config_confirm_pushed(conf, pushData11.pointee.seqno, &cFakeHash4)
expect(pushData11.pointee.seqno).to(equal(4))
- expect([String](pointer: pushData11.pointee.obsolete, count: pushData11.pointee.obsolete_len))
+ expect([String](cStringArray: pushData11.pointee.obsolete, count: pushData11.pointee.obsolete_len))
.to(equal([fakeHash3, fakeHash2, fakeHash1]))
// Load some obsolete ones in just to check that they get immediately obsoleted
@@ -1580,7 +1580,7 @@ fileprivate extension LibSessionUtilSpec {
pushData11.pointee.config_len
]
let mergedHashes3: UnsafeMutablePointer? = config_merge(conf2, &mergeHashes3, &mergeData3, &mergeSize3, 4)
- expect([String](pointer: mergedHashes3?.pointee.value, count: mergedHashes3?.pointee.len))
+ expect([String](cStringArray: mergedHashes3?.pointee.value, count: mergedHashes3?.pointee.len))
.to(equal(["fakehash10", "fakehash11", "fakehash12", "fakehash4"]))
expect(config_needs_dump(conf2)).to(beTrue())
expect(config_needs_push(conf2)).to(beFalse())
@@ -1592,13 +1592,13 @@ fileprivate extension LibSessionUtilSpec {
pushData11.deallocate()
let currentHashes5: UnsafeMutablePointer? = config_current_hashes(conf2)
- expect([String](pointer: currentHashes5?.pointee.value, count: currentHashes5?.pointee.len))
+ expect([String](cStringArray: currentHashes5?.pointee.value, count: currentHashes5?.pointee.len))
.to(equal([fakeHash4]))
currentHashes5?.deallocate()
let pushData12: UnsafeMutablePointer = config_push(conf2)
expect(pushData12.pointee.seqno).to(equal(4))
- expect([String](pointer: pushData12.pointee.obsolete, count: pushData12.pointee.obsolete_len))
+ expect([String](cStringArray: pushData12.pointee.obsolete, count: pushData12.pointee.obsolete_len))
.to(equal([fakeHash11, fakeHash12, fakeHash10, fakeHash3]))
pushData12.deallocate()
@@ -1716,7 +1716,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData1: [UnsafePointer?] = [UnsafePointer(pushData1.pointee.config)]
var mergeSize1: [Int] = [pushData1.pointee.config_len]
let mergedHashes1: UnsafeMutablePointer? = config_merge(conf2, &mergeHashes1, &mergeData1, &mergeSize1, 1)
- expect([String](pointer: mergedHashes1?.pointee.value, count: mergedHashes1?.pointee.len))
+ expect([String](cStringArray: mergedHashes1?.pointee.value, count: mergedHashes1?.pointee.len))
.to(equal(["fakehash1"]))
expect(config_needs_push(conf2)).to(beFalse())
mergeHashes1.forEach { $0?.deallocate() }
@@ -1745,10 +1745,9 @@ fileprivate extension LibSessionUtilSpec {
groups_info_destroy_group(conf2)
let pushData2: UnsafeMutablePointer = config_push(conf2)
- let obsoleteHashes: [String] = [String](
- pointer: pushData2.pointee.obsolete,
- count: pushData2.pointee.obsolete_len,
- defaultValue: []
+ let obsoleteHashes: [String]? = [String](
+ cStringArray: pushData2.pointee.obsolete,
+ count: pushData2.pointee.obsolete_len
)
expect(pushData2.pointee.seqno).to(equal(2))
expect(pushData2.pointee.config_len).to(equal(512))
@@ -1762,7 +1761,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData2: [UnsafePointer?] = [UnsafePointer(pushData2.pointee.config)]
var mergeSize2: [Int] = [pushData2.pointee.config_len]
let mergedHashes2: UnsafeMutablePointer? = config_merge(conf, &mergeHashes2, &mergeData2, &mergeSize2, 1)
- expect([String](pointer: mergedHashes2?.pointee.value, count: mergedHashes2?.pointee.len))
+ expect([String](cStringArray: mergedHashes2?.pointee.value, count: mergedHashes2?.pointee.len))
.to(equal(["fakehash2"]))
mergeHashes2.forEach { $0?.deallocate() }
mergedHashes2?.deallocate()
@@ -1800,7 +1799,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData3: [UnsafePointer?] = [UnsafePointer(pushData3.pointee.config)]
var mergeSize3: [Int] = [pushData3.pointee.config_len]
let mergedHashes3: UnsafeMutablePointer? = config_merge(conf2, &mergeHashes3, &mergeData3, &mergeSize3, 1)
- expect([String](pointer: mergedHashes3?.pointee.value, count: mergedHashes3?.pointee.len))
+ expect([String](cStringArray: mergedHashes3?.pointee.value, count: mergedHashes3?.pointee.len))
.to(equal(["fakehash3"]))
mergeHashes3.forEach { $0?.deallocate() }
mergedHashes3?.deallocate()
@@ -2069,7 +2068,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData1: [UnsafePointer?] = [UnsafePointer(pushData1.pointee.config)]
var mergeSize1: [Int] = [pushData1.pointee.config_len]
let mergedHashes1: UnsafeMutablePointer? = config_merge(conf2, &mergeHashes1, &mergeData1, &mergeSize1, 1)
- expect([String](pointer: mergedHashes1?.pointee.value, count: mergedHashes1?.pointee.len))
+ expect([String](cStringArray: mergedHashes1?.pointee.value, count: mergedHashes1?.pointee.len))
.to(equal(["fakehash1"]))
expect(config_needs_push(conf2)).to(beFalse())
mergeHashes1.forEach { $0?.deallocate() }
@@ -2160,10 +2159,9 @@ fileprivate extension LibSessionUtilSpec {
groups_members_set(conf2, &member1)
let pushData2: UnsafeMutablePointer = config_push(conf2)
- let obsoleteHashes: [String] = [String](
- pointer: pushData2.pointee.obsolete,
- count: pushData2.pointee.obsolete_len,
- defaultValue: []
+ let obsoleteHashes: [String]? = [String](
+ cStringArray: pushData2.pointee.obsolete,
+ count: pushData2.pointee.obsolete_len
)
expect(pushData2.pointee.seqno).to(equal(2))
expect(pushData2.pointee.config_len).to(equal(1024))
@@ -2177,7 +2175,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData2: [UnsafePointer?] = [UnsafePointer(pushData2.pointee.config)]
var mergeSize2: [Int] = [pushData2.pointee.config_len]
let mergedHashes2: UnsafeMutablePointer? = config_merge(conf, &mergeHashes2, &mergeData2, &mergeSize2, 1)
- expect([String](pointer: mergedHashes2?.pointee.value, count: mergedHashes2?.pointee.len))
+ expect([String](cStringArray: mergedHashes2?.pointee.value, count: mergedHashes2?.pointee.len))
.to(equal(["fakehash2"]))
mergeHashes2.forEach { $0?.deallocate() }
mergedHashes2?.deallocate()
@@ -2334,10 +2332,9 @@ fileprivate extension LibSessionUtilSpec {
}
let pushData3: UnsafeMutablePointer = config_push(conf)
- let obsoleteHashes3: [String] = [String](
- pointer: pushData3.pointee.obsolete,
- count: pushData3.pointee.obsolete_len,
- defaultValue: []
+ let obsoleteHashes3: [String]? = [String](
+ cStringArray: pushData3.pointee.obsolete,
+ count: pushData3.pointee.obsolete_len
)
expect(pushData3.pointee.seqno).to(equal(3))
expect(pushData3.pointee.config_len).to(equal(1024))
@@ -2351,7 +2348,7 @@ fileprivate extension LibSessionUtilSpec {
var mergeData3: [UnsafePointer?] = [UnsafePointer(pushData3.pointee.config)]
var mergeSize3: [Int] = [pushData3.pointee.config_len]
let mergedHashes3: UnsafeMutablePointer? = config_merge(conf2, &mergeHashes3, &mergeData3, &mergeSize3, 1)
- expect([String](pointer: mergedHashes3?.pointee.value, count: mergedHashes3?.pointee.len))
+ expect([String](cStringArray: mergedHashes3?.pointee.value, count: mergedHashes3?.pointee.len))
.to(equal(["fakehash3"]))
mergeHashes3.forEach { $0?.deallocate() }
mergedHashes3?.deallocate()
@@ -2703,3 +2700,50 @@ private extension LibSessionUtilSpec {
return false
}
}
+
+private extension Collection where Element == [CChar]? {
+ /// This creates an array of UnsafePointer types to access data of the C strings in memory. This array provides no automated
+ /// memory management of it's children so after use you are responsible for handling the life cycle of the child elements and
+ /// need to call `deallocate()` on each child.
+ func unsafeCopyCStringArray() throws -> [UnsafePointer?] {
+ return try self.map { value in
+ guard let value: [CChar] = value else { return nil }
+
+ let copy = UnsafeMutableBufferPointer.allocate(capacity: value.underestimatedCount)
+ var remaining: (unwritten: Array.Iterator, index: Int) = copy.initialize(from: value)
+ guard remaining.unwritten.next() == nil else { throw LibSessionError.invalidCConversion }
+
+ return UnsafePointer(copy.baseAddress)
+ }
+ }
+}
+
+private extension Collection where Element == [CChar] {
+ /// This creates an array of UnsafePointer types to access data of the C strings in memory. This array provides no automated
+ /// memory management of it's children so after use you are responsible for handling the life cycle of the child elements and
+ /// need to call `deallocate()` on each child.
+ func unsafeCopyCStringArray() throws -> [UnsafePointer?] {
+ return try self.map { value in
+ let copy = UnsafeMutableBufferPointer.allocate(capacity: value.underestimatedCount)
+ var remaining: (unwritten: Array.Iterator, index: Int) = copy.initialize(from: value)
+ guard remaining.unwritten.next() == nil else { throw LibSessionError.invalidCConversion }
+
+ return UnsafePointer(copy.baseAddress)
+ }
+ }
+}
+
+private extension Collection where Element == [UInt8] {
+ /// This creates an array of UnsafePointer types to access data of the C strings in memory. This array provides no automated
+ /// memory management of it's children so after use you are responsible for handling the life cycle of the child elements and
+ /// need to call `deallocate()` on each child.
+ func unsafeCopyUInt8Array() throws -> [UnsafePointer?] {
+ return try self.map { value in
+ let copy = UnsafeMutableBufferPointer.allocate(capacity: value.underestimatedCount)
+ var remaining: (unwritten: Array.Iterator, index: Int) = copy.initialize(from: value)
+ guard remaining.unwritten.next() == nil else { throw LibSessionError.invalidCConversion }
+
+ return UnsafePointer(copy.baseAddress)
+ }
+ }
+}
diff --git a/SessionSnodeKit/LibSession/LibSession+Networking.swift b/SessionSnodeKit/LibSession/LibSession+Networking.swift
index fed40b519..3d314fc36 100644
--- a/SessionSnodeKit/LibSession/LibSession+Networking.swift
+++ b/SessionSnodeKit/LibSession/LibSession+Networking.swift
@@ -253,13 +253,12 @@ class LibSessionNetwork: NetworkType {
throw NetworkError.invalidPreparedRequest
case .snode(let snode, let swarmPublicKey):
- let cSwarmPublicKey: UnsafePointer? = try swarmPublicKey.map {
+ let cSwarmPublicKey: [CChar]? = try swarmPublicKey.map {
_ = try SessionId(from: $0)
// Quick way to drop '05' prefix if present
- return $0.suffix(64).cString(using: .utf8)?.unsafeCopy()
- }
- wrapper.addUnsafePointerToCleanup(cSwarmPublicKey)
+ return $0.suffix(64).cString(using: .utf8)
+ }.flatMap { $0 }
network_send_onion_request_to_snode_destination(
network,
@@ -279,56 +278,62 @@ class LibSessionNetwork: NetworkType {
)
case .server:
- network_send_onion_request_to_server_destination(
- network,
- try wrapper.cServerDestination(destination),
- cPayloadBytes,
- cPayloadBytes.count,
- Int64(floor(requestTimeout * 1000)),
- Int64(floor((requestAndPathBuildTimeout ?? 0) * 1000)),
- { success, timeout, statusCode, cHeaders, cHeaderVals, headerLen, dataPtr, dataLen, ctx in
- let headers: [String: String] = CallbackWrapper