From 8a8973fe151007b23b85d8497c81d7e831b7aa75 Mon Sep 17 00:00:00 2001
From: Lars Toenning <dev@ltoenning.de>
Date: Sat, 5 Jun 2021 15:07:03 +0200
Subject: [PATCH] AIManager: Explicitly take SGSharedPtr

Otherwise a SGSharedPtr is implicitly created on ai_list.push_back(model). It's not clear to the caller that FGAIManager takes care of the passed raw pointer.

Also fixes a bug for swift using the passed dangling pointer after the created SGSharedPtr of FGAIManager got out of scope and deleted the resource.

As this commit mainly addresses the swift crash (also for backport to LTS) it doesn't fix other calls to ::attach(..) which might also use the raw pointer afterwards.
---
 src/AIModel/AIManager.cxx                  | 2 +-
 src/AIModel/AIManager.hxx                  | 2 +-
 src/Network/Swift/SwiftAircraftManager.cpp | 4 ++--
 src/Network/Swift/SwiftAircraftManager.h   | 4 +++-
 4 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/AIModel/AIManager.cxx b/src/AIModel/AIManager.cxx
index 4aea54672..d438ae7fb 100644
--- a/src/AIModel/AIManager.cxx
+++ b/src/AIModel/AIManager.cxx
@@ -419,7 +419,7 @@ FGAIManager::updateLOD(SGPropertyNode* node)
 }
 
 void
-FGAIManager::attach(FGAIBase *model)
+FGAIManager::attach(const SGSharedPtr<FGAIBase> &model)
 {
     const char* typeString = model->getTypeString();
     SGPropertyNode* root = globals->get_props()->getNode("ai/models", true);
diff --git a/src/AIModel/AIManager.hxx b/src/AIModel/AIManager.hxx
index de99783b1..087f245db 100644
--- a/src/AIModel/AIManager.hxx
+++ b/src/AIModel/AIManager.hxx
@@ -54,7 +54,7 @@ public:
     static const char* staticSubsystemClassId() { return "ai-model"; }
 
     void updateLOD(SGPropertyNode* node);
-    void attach(FGAIBase *model);
+    void attach(const SGSharedPtr<FGAIBase> &model);
 
     const FGAIBase *calcCollision(double alt, double lat, double lon, double fuse_range);
 
diff --git a/src/Network/Swift/SwiftAircraftManager.cpp b/src/Network/Swift/SwiftAircraftManager.cpp
index c2bdde941..e32fd67ce 100644
--- a/src/Network/Swift/SwiftAircraftManager.cpp
+++ b/src/Network/Swift/SwiftAircraftManager.cpp
@@ -40,12 +40,12 @@ bool FGSwiftAircraftManager::isInitialized() const
 bool FGSwiftAircraftManager::addPlane(const std::string& callsign, const std::string& modelString)
 {
     this->removePlane(callsign); // Remove plane if already exists e.g. when rematching is done.
-    auto curAircraft = new FGAISwiftAircraft(callsign, modelString);
+    auto curAircraft = FGAISwiftAircraftPtr(new FGAISwiftAircraft(callsign, modelString));
     globals->get_subsystem<FGAIManager>()->attach(curAircraft);
     // Init props after prop-root is assigned
     curAircraft->initProps();
 
-    aircraftByCallsign.insert(std::pair<std::string, FGAISwiftAircraft*>(callsign, curAircraft));
+    aircraftByCallsign.insert(std::pair<std::string, FGAISwiftAircraftPtr>(callsign, curAircraft));
     return true;
 }
 
diff --git a/src/Network/Swift/SwiftAircraftManager.h b/src/Network/Swift/SwiftAircraftManager.h
index 6ebb9e273..92dbfb19c 100644
--- a/src/Network/Swift/SwiftAircraftManager.h
+++ b/src/Network/Swift/SwiftAircraftManager.h
@@ -29,6 +29,8 @@
 
 class FGSwiftAircraftManager
 {
+    using FGAISwiftAircraftPtr = SGSharedPtr<FGAISwiftAircraft>;
+
 public:
     FGSwiftAircraftManager();
     ~FGSwiftAircraftManager();
@@ -44,7 +46,7 @@ public:
     void setPlanesSurfaces(const std::vector<AircraftSurfaces>& surfaces);
 
 private:
-    std::unordered_map<std::string, FGAISwiftAircraft*> aircraftByCallsign;
+    std::unordered_map<std::string, FGAISwiftAircraftPtr> aircraftByCallsign;
     bool m_initialized = false;
 
 };