Skip to content

Commit 3c9de83

Browse files
darinfcompnerd
authored andcommitted
[WPP-2267] Avoid HttpsCallableReference copy constructor (#67)
Unfortunately `HttpsCallableReference` does not use internal reference counting, and as a result, we need to avoid the copy-constructor for `HttpsCallableReference`. Otherwise, if Swift creates a copy of the object and deletes that copy, it will result in any pending `Call` being interrupted or triggering memory corruption in the case that `Call` has not completed. To avoid this and to prevent Swift from seeing the copy constructor, wrap with a `std::shared_ptr`.
1 parent cfd3c10 commit 3c9de83

File tree

2 files changed

+17
-8
lines changed

2 files changed

+17
-8
lines changed

Sources/FirebaseFunctions/HTTPSCallable+Swift.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import CxxShim
99
import Foundation
1010

1111
public class HTTPSCallable {
12-
let impl: firebase.functions.HttpsCallableReference
12+
let impl: swift_firebase.swift_cxx_shims.firebase.functions.HttpsCallableRef
1313

14-
init(_ impl: firebase.functions.HttpsCallableReference) {
14+
init(_ impl: swift_firebase.swift_cxx_shims.firebase.functions.HttpsCallableRef) {
1515
self.impl = impl
1616
}
1717

Sources/firebase/include/FirebaseFunctions.hh

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace swift_firebase::swift_cxx_shims::firebase::functions {
1515

1616
typedef std::shared_ptr<::firebase::functions::Functions> FunctionsRef;
17+
typedef std::shared_ptr<::firebase::functions::HttpsCallableReference> HttpsCallableRef;
1718

1819
inline bool
1920
functions_is_valid(const FunctionsRef& ref) {
@@ -25,22 +26,30 @@ functions_get_instance(::firebase::App* app) {
2526
return FunctionsRef(::firebase::functions::Functions::GetInstance(app));
2627
}
2728

28-
inline ::firebase::functions::HttpsCallableReference
29+
inline HttpsCallableRef
2930
functions_get_https_callable(FunctionsRef ref, const char* name) {
30-
return ref.get()->GetHttpsCallable(name);
31+
// Unfortunately `HttpsCallableReference` does not use internal reference
32+
// counting, and as a result, we need to avoid the copy-constructor for
33+
// `HttpsCallableReference`. Otherwise, if Swift creates a copy of the object
34+
// and deletes that copy, it will result in any pending `Call` being
35+
// interrupted or triggering memory corruption in the case that `Call` has
36+
// not completed. To avoid this and to prevent Swift from seeing the copy
37+
// constructor, wrap with a `std::shared_ptr`.
38+
return HttpsCallableRef(new ::firebase::functions::HttpsCallableReference(
39+
std::move(ref.get()->GetHttpsCallable(name))));
3140
}
3241

3342
inline ::swift_firebase::swift_cxx_shims::firebase::Future<
3443
::firebase::functions::HttpsCallableResult>
35-
https_callable_call(::firebase::functions::HttpsCallableReference ref) {
36-
return ref.Call();
44+
https_callable_call(HttpsCallableRef ref) {
45+
return ref.get()->Call();
3746
}
3847

3948
inline ::swift_firebase::swift_cxx_shims::firebase::Future<
4049
::firebase::functions::HttpsCallableResult>
41-
https_callable_call(::firebase::functions::HttpsCallableReference ref,
50+
https_callable_call(HttpsCallableRef ref,
4251
const ::firebase::Variant& data) {
43-
return ref.Call(data);
52+
return ref.get()->Call(data);
4453
}
4554

4655
inline ::firebase::Variant

0 commit comments

Comments
 (0)