]> git.mxchange.org Git - simgear.git/blobdiff - simgear/package/Catalog.cxx
Fix a leak / potential crash
[simgear.git] / simgear / package / Catalog.cxx
index 2ce17d5ebcad9db638771fc63034ae0dc06499b3..46f85e77b538b2f0dbd7adb2bfa1ea7102c35dd4 100644 (file)
@@ -37,34 +37,43 @@ namespace simgear {
 
 namespace pkg {
 
-bool checkVersion(const std::string& aVersion, SGPropertyNode_ptr props)
+bool checkVersionString(const std::string& aVersion, const std::string& aCandidate)
 {
-    BOOST_FOREACH(SGPropertyNode* v, props->getChildren("version")) {
-        std::string s(v->getStringValue());
-        if (s == aVersion) {
-            return true;
-        }
+    if (aCandidate == aVersion) {
+        return true;
+    }
 
-        // examine each dot-seperated component in turn, supporting a wildcard
-        // in the versions from the catalog.
-        string_list appVersionParts = simgear::strutils::split(aVersion, ".");
-        string_list catVersionParts = simgear::strutils::split(s, ".");
+    // examine each dot-seperated component in turn, supporting a wildcard
+    // in the versions from the catalog.
+    string_list appVersionParts = simgear::strutils::split(aVersion, ".");
+    string_list catVersionParts = simgear::strutils::split(aCandidate, ".");
 
-        size_t partCount = appVersionParts.size();
-        if (partCount != catVersionParts.size()) {
-            continue;
+    size_t partCount = appVersionParts.size();
+    bool previousCandidatePartWasWildcard = false;
+
+    for (unsigned int p=0; p < partCount; ++p) {
+        // candidate string is too short, can match if it ended with wildcard
+        // part. This allows candidate '2016.*' to match '2016.1.2' and so on
+        if (catVersionParts.size() <= p) {
+            return previousCandidatePartWasWildcard;
         }
 
-        bool ok = true;
-        for (unsigned int p=0; p < partCount; ++p) {
-            if (catVersionParts[p] == "*") {
-                // always passes
-            } else if (appVersionParts[p] != catVersionParts[p]) {
-                ok = false;
-            }
+        if (catVersionParts[p] == "*") {
+            // always passes
+            previousCandidatePartWasWildcard = true;
+        } else if (appVersionParts[p] != catVersionParts[p]) {
+            return false;
         }
+    }
 
-        if (ok) {
+    return true;
+}
+
+bool checkVersion(const std::string& aVersion, SGPropertyNode_ptr props)
+{
+    BOOST_FOREACH(SGPropertyNode* v, props->getChildren("version")) {
+        std::string s(v->getStringValue());
+        if (checkVersionString(aVersion, s)) {
             return true;
         }
     }
@@ -74,8 +83,9 @@ bool checkVersion(const std::string& aVersion, SGPropertyNode_ptr props)
 std::string redirectUrlForVersion(const std::string& aVersion, SGPropertyNode_ptr props)
 {
     BOOST_FOREACH(SGPropertyNode* v, props->getChildren("alternate-version")) {
-        if (v->getStringValue("version") == aVersion) {
-            return v->getStringValue("url");
+        std::string s(v->getStringValue("version"));
+        if (checkVersionString(aVersion, s)) {
+            return  v->getStringValue("url");;
         }
     }
 
@@ -114,7 +124,7 @@ protected:
             return;
         }
 
-        SGPropertyNode* props = new SGPropertyNode;
+        SGPropertyNode_ptr props = new SGPropertyNode;
 
         try {
             readProperties(m_buffer.data(), m_buffer.size(), props);
@@ -125,14 +135,6 @@ protected:
             return;
         }
 
-        if (m_owner->root()->catalogVersion() != props->getIntValue("catalog-version")) {
-            SG_LOG(SG_GENERAL, SG_WARN, "catalog:" << m_owner->url() << " is not version "
-                   << m_owner->root()->catalogVersion());
-            m_owner->refreshComplete(Delegate::FAIL_VERSION);
-            return;
-        }
-
-
         std::string ver(m_owner->root()->applicationVersion());
         if (!checkVersion(ver, props)) {
             SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", version required " << ver);
@@ -144,7 +146,7 @@ protected:
                        " to \n\t" << url);
 
                 // update the URL and kick off a new request
-                m_owner->m_url = url;
+                m_owner->setUrl(url);
                 Downloader* dl = new Downloader(m_owner, url);
                 m_owner->root()->makeHTTPRequest(dl);
             } else {
@@ -211,7 +213,6 @@ CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
     }
 
     bool versionCheckOk = checkVersion(aRoot->applicationVersion(), props);
-
     if (!versionCheckOk) {
         SG_LOG(SG_GENERAL, SG_INFO, "catalog at:" << aPath << " failed version check: need" << aRoot->applicationVersion());
         // keep the catalog but mark it as needing an update
@@ -437,6 +438,14 @@ std::string Catalog::url() const
     return m_url;
 }
 
+void Catalog::setUrl(const std::string &url)
+{
+    m_url = url;
+    if (m_status == Delegate::FAIL_NOT_FOUND) {
+        m_status = Delegate::FAIL_UNKNOWN;
+    }
+}
+
 std::string Catalog::name() const
 {
     return getLocalisedString(m_props, "name");
@@ -505,8 +514,8 @@ std::string Catalog::getLocalisedString(const SGPropertyNode* aRoot, const char*
 
 void Catalog::refreshComplete(Delegate::StatusCode aReason)
 {
-    changeStatus(aReason);
     m_refreshRequest.reset();
+    changeStatus(aReason);
 }
 
 void Catalog::changeStatus(Delegate::StatusCode newStatus)