From 1eef7300be5d4390edb7a63d6f23a01b1623cd93 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Thu, 21 May 2020 23:19:39 +0100
Subject: [PATCH] PosInit: fix a crash with invalid park-pos.

Add test-cases for this,
---
 src/ATC/atc_mgr.cxx                         |  4 +-
 src/GUI/LauncherArgumentTokenizer.cxx       |  2 +-
 test_suite/unit_tests/Main/test_posinit.cxx | 74 +++++++++++++++++++++
 test_suite/unit_tests/Main/test_posinit.hxx |  6 +-
 4 files changed, 81 insertions(+), 5 deletions(-)

diff --git a/src/ATC/atc_mgr.cxx b/src/ATC/atc_mgr.cxx
index 5b7df5baa..a3b004a7a 100644
--- a/src/ATC/atc_mgr.cxx
+++ b/src/ATC/atc_mgr.cxx
@@ -193,11 +193,9 @@ void FGATCManager::postinit()
             // We're on the ground somewhere. Handle this case later.
             
             // important : we are on the ground, so reset the AIFlightPlan back to
-            // a default one. Otherwise, in the reposition case, we end up with a
+            // an empty one. Otherwise, in the reposition case, we end up with a
             // stale flight-plan which confuses other code (eg, PositionInit::finalizeForParking)
             // see unit test: PosInitTests::testRepositionAtOccupied
-            
-            fp.reset(new FGAIFlightPlan);
             userAircraft->FGAIBase::setFlightPlan(std::move(fp));
             controller = nullptr;
             
diff --git a/src/GUI/LauncherArgumentTokenizer.cxx b/src/GUI/LauncherArgumentTokenizer.cxx
index 562651326..dff0e5540 100644
--- a/src/GUI/LauncherArgumentTokenizer.cxx
+++ b/src/GUI/LauncherArgumentTokenizer.cxx
@@ -147,7 +147,7 @@ void LauncherArgumentTokenizer::setArgString(QString argString)
 }
 
 const std::set<std::string> positionalArgs({
-    "lat", "lon", "vor", "ndb", "fix"
+    "lat", "lon", "vor", "ndb", "fix", "parkpos",
     "airport", "parking-id", "runway", "carrier", "carrier-position"
 });
 
diff --git a/test_suite/unit_tests/Main/test_posinit.cxx b/test_suite/unit_tests/Main/test_posinit.cxx
index eeb639bea..4368b64e3 100644
--- a/test_suite/unit_tests/Main/test_posinit.cxx
+++ b/test_suite/unit_tests/Main/test_posinit.cxx
@@ -615,6 +615,35 @@ void PosInitTests::testAirportRepositionAirport()
    
 }
 
+void PosInitTests::testParkInvalid()
+{
+    {
+        Options* opts = Options::sharedInstance();
+        opts->setShouldLoadDefaultConfig(false);
+        const char* args[] = {"dummypath", "--airport=EDDF", "--parkpos=foobar"};
+        opts->init(3, (char**) args, SGPath());
+        opts->processOptions();
+    }
+    
+    CPPUNIT_ASSERT(fgGetBool("/sim/presets/airport-requested"));
+    CPPUNIT_ASSERT(! fgGetBool("/sim/presets/runway-requested"));
+
+    checkStringProp("/sim/presets/parkpos", "foobar");
+    initPosition();
+    
+    auto apt = FGAirport::getByIdent("EDDF");
+    
+
+    fgSetDouble("/environment/metar/base-wind-dir-deg",  350.0);
+    fgSetBool("/environment/metar/valid", true);
+    
+    simulateFinalizePosition();
+    checkClosestAirport(std::string("EDDF"));
+    // we should be on the best runway, let's see
+    auto runway = apt->getRunwayByIdent("36");
+    checkPosition(runway->threshold());
+}
+
 void PosInitTests::testParkAtOccupied()
 {
     {
@@ -807,3 +836,48 @@ void PosInitTests::testRepositionAtOccupied()
     auto runway = apt->getRunwayByIdent("36");
     checkPosition(runway->threshold());
 }
+
+
+void PosInitTests::testRepositionAtInvalid()
+{
+     {
+        Options* opts = Options::sharedInstance();
+        opts->setShouldLoadDefaultConfig(false);
+
+        const char* args[] = {"dummypath", "--airport=EDDF", "--parkpos=F235"};
+        opts->init(3, (char**) args, SGPath());
+        opts->processOptions();
+    }
+
+    CPPUNIT_ASSERT(fgGetBool("/sim/presets/airport-requested"));
+    CPPUNIT_ASSERT(! fgGetBool("/sim/presets/runway-requested"));
+
+    checkStringProp("/sim/presets/parkpos", "F235");
+    initPosition();
+
+    auto apt = FGAirport::getByIdent("EDDF");
+    auto parking1 = apt->groundNetwork()->findParkingByName("F235");
+         
+
+    fgSetDouble("/environment/metar/base-wind-dir-deg",  350.0);
+    fgSetBool("/environment/metar/valid", true);
+
+    simulateFinalizePosition();
+
+    checkClosestAirport(std::string("EDDF"));
+    checkPosition(parking1->geod(), 20);
+
+    //////////
+    fgSetDouble("/sim/presets/longitude-deg", -9990.00);
+    fgSetDouble("/sim/presets/latitude-deg",  -9990.00);
+    fgSetString("/sim/presets/airport-id", "EDDF");
+    fgSetDouble("/sim/presets/heading-deg",  9990.00);
+    fgSetString("/sim/presets/parkpos", "foobarzot");
+
+    simulateStartReposition();
+    finalizePosition();
+        
+    // we should be on the best runway, let's see
+    auto runway = apt->getRunwayByIdent("36");
+    checkPosition(runway->threshold());
+}
diff --git a/test_suite/unit_tests/Main/test_posinit.hxx b/test_suite/unit_tests/Main/test_posinit.hxx
index fd12a85b2..d32c21232 100644
--- a/test_suite/unit_tests/Main/test_posinit.hxx
+++ b/test_suite/unit_tests/Main/test_posinit.hxx
@@ -45,6 +45,8 @@ class PosInitTests : public CppUnit::TestFixture
     CPPUNIT_TEST(testDefaultStartup);
     CPPUNIT_TEST(testRepositionAtParking);
     CPPUNIT_TEST(testParkAtOccupied);
+    CPPUNIT_TEST(testParkInvalid);
+    
     
     // Navaid tests
     CPPUNIT_TEST(testVOROnlyStartup);
@@ -67,6 +69,7 @@ class PosInitTests : public CppUnit::TestFixture
     CPPUNIT_TEST(testAirportRepositionAirport);
     CPPUNIT_TEST(testRepositionAtSameParking);
     CPPUNIT_TEST(testRepositionAtOccupied);
+    CPPUNIT_TEST(testRepositionAtInvalid);
     
     CPPUNIT_TEST_SUITE_END();
 
@@ -90,6 +93,7 @@ public:
     void testAirportRunwayOffsetGlideslopeStartup();
     void testDefaultStartup();
     void testParkAtOccupied();
+    void testParkInvalid();
     
     // Navaid tests
     void testVOROnlyStartup();
@@ -111,7 +115,7 @@ public:
     void testRepositionAtParking();
     void testRepositionAtSameParking();
     void testRepositionAtOccupied();
-    
+    void testRepositionAtInvalid();
 private:
     // Helper functions for tests.  Return void as they use CPPUNIT_ASSERT
     void checkAlt(float value);