From 8c9fda9137971da1e06ac4cac10ccd5782e29ca5 Mon Sep 17 00:00:00 2001 From: James Turner Date: Fri, 31 Aug 2018 16:03:49 +0100 Subject: [PATCH 1/8] Fix Utf-8 literal on MSVC --- simgear/misc/path_test.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/simgear/misc/path_test.cxx b/simgear/misc/path_test.cxx index 19e82a27..dac7c0d2 100644 --- a/simgear/misc/path_test.cxx +++ b/simgear/misc/path_test.cxx @@ -160,7 +160,7 @@ void test_path_dir() SG_VERIFY(sub2.isFile()); SG_CHECK_EQUAL(sub2.sizeInBytes(), 250); - SGPath sub3 = p / "subß" / "file𝕽"; + SGPath sub3 = p / "subß" / u8"file𝕽"; sub3.create_dir(0755); { @@ -174,7 +174,7 @@ void test_path_dir() sub3.set_cached(false); SG_VERIFY(sub3.exists()); SG_CHECK_EQUAL(sub3.sizeInBytes(), 100); - SG_CHECK_EQUAL(sub3.file(), "file𝕽"); + SG_CHECK_EQUAL(sub3.file(), u8"file𝕽"); simgear::Dir subD(p / "subA"); simgear::PathList dirChildren = subD.children(simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT); @@ -188,7 +188,7 @@ void test_path_dir() simgear::Dir subS(sub3.dirPath()); fileChildren = subS.children(simgear::Dir::TYPE_FILE | simgear::Dir::NO_DOT_OR_DOTDOT); SG_CHECK_EQUAL(fileChildren.size(), 1); - SG_CHECK_EQUAL(fileChildren[0], subS.path() / "file𝕽"); + SG_CHECK_EQUAL(fileChildren[0], subS.path() / u8"file𝕽"); } From c192071f030fc690a6daa3d668db85cad55bb10d Mon Sep 17 00:00:00 2001 From: James Turner Date: Fri, 31 Aug 2018 16:05:25 +0100 Subject: [PATCH 2/8] TerraSync: improve copy-installed-files logic --- simgear/io/HTTPRepository.cxx | 101 ++++++++++++++++------------------ 1 file changed, 47 insertions(+), 54 deletions(-) diff --git a/simgear/io/HTTPRepository.cxx b/simgear/io/HTTPRepository.cxx index 41be821a..a2e009ba 100644 --- a/simgear/io/HTTPRepository.cxx +++ b/simgear/io/HTTPRepository.cxx @@ -182,17 +182,11 @@ class HTTPDirectory ChildInfo(Type ty, const std::string & nameData, const std::string & hashData) : type(ty), name(nameData), - hash(hashData), - sizeInBytes(0) + hash(hashData) { } - ChildInfo(const ChildInfo& other) : - type(other.type), - name(other.name), - hash(other.hash), - sizeInBytes(other.sizeInBytes) - { } + ChildInfo(const ChildInfo& other) = default; void setSize(const std::string & sizeData) { @@ -206,7 +200,8 @@ class HTTPDirectory Type type; std::string name, hash; - size_t sizeInBytes; + size_t sizeInBytes = 0; + SGPath path; // absolute path on disk }; typedef std::vector ChildInfoList; @@ -273,44 +268,45 @@ public: return; } - string_list indexNames = indexChildren(); - const_string_list_iterator nameIt = indexNames.begin(); - for (; nameIt != indexNames.end(); ++nameIt) { - SGPath p(absolutePath()); - p.append(*nameIt); - if (p.exists()) { - continue; // only copy if the file is missing entirely - } + char* buf = nullptr; + size_t bufSize = 0; - ChildInfoList::iterator c = findIndexChild(*nameIt); - if (c->type == ChildInfo::DirectoryType) { - continue; // only care about files - } + for (const auto& child : children) { + if (child.type != ChildInfo::FileType) + continue; - SGPath cp = _repository->installedCopyPath; - cp.append(relativePath()); - cp.append(*nameIt); - if (!cp.exists()) { - continue; - } + if (child.path.exists()) + continue; - SGBinaryFile src(cp); - SGBinaryFile dst(p); - src.open(SG_IO_IN); - dst.open(SG_IO_OUT); + SGPath cp = _repository->installedCopyPath; + cp.append(relativePath()); + cp.append(child.name); + if (!cp.exists()) { + continue; + } - char* buf = (char*) malloc(cp.sizeInBytes()); - if (!buf) { - continue; - } + SGBinaryFile src(cp); + SGBinaryFile dst(child.path); + src.open(SG_IO_IN); + dst.open(SG_IO_OUT); - src.read(buf, cp.sizeInBytes()); - dst.write(buf, cp.sizeInBytes()); - src.close(); - dst.close(); + if (bufSize < cp.sizeInBytes()) { + bufSize = cp.sizeInBytes(); + free(buf); + buf = (char*) malloc(bufSize); + if (!buf) { + continue; + } + } - free(buf); - } + src.read(buf, cp.sizeInBytes()); + dst.write(buf, cp.sizeInBytes()); + src.close(); + dst.close(); + + } + + free(buf); } void updateChildrenBasedOnHash() @@ -319,19 +315,20 @@ public: copyInstalledChildren(); - string_list indexNames = indexChildren(), - toBeUpdated, orphans; + string_list toBeUpdated, orphans, + indexNames = indexChildren(); simgear::Dir d(absolutePath()); PathList fsChildren = d.children(0); - for (const auto& child : fsChildren) { const auto& fileName = child.file(); if ((fileName == ".dirindex") || (fileName == ".hashes")) { continue; } - ChildInfo info(child.isDir() ? ChildInfo::DirectoryType : ChildInfo::FileType, fileName, ""); + ChildInfo info(child.isDir() ? ChildInfo::DirectoryType : ChildInfo::FileType, + fileName, ""); + info.path = child; std::string hash = hashForChild(info); ChildInfoList::iterator c = findIndexChild(fileName); @@ -428,19 +425,16 @@ public: void didUpdateFile(const std::string& file, const std::string& hash, size_t sz) { // check hash matches what we expected - ChildInfoList::iterator it = findIndexChild(file); + auto it = findIndexChild(file); if (it == children.end()) { SG_LOG(SG_TERRASYNC, SG_WARN, "updated file but not found in dir:" << _relativePath << " " << file); } else { - SGPath fpath(absolutePath()); - fpath.append(file); - if (it->hash != hash) { // we don't erase the file on a hash mismatch, becuase if we're syncing during the // middle of a server-side update, the downloaded file may actually become valid. _repository->failedToUpdateChild(_relativePath, HTTPRepository::REPO_ERROR_CHECKSUM); } else { - _repository->updatedFileContents(fpath, hash); + _repository->updatedFileContents(it->path, hash); _repository->totalDownloaded += sz; } // of hash matches } // of found in child list @@ -539,8 +533,8 @@ private: continue; } - children.push_back(ChildInfo(typeData == "f" ? ChildInfo::FileType : ChildInfo::DirectoryType, tokens[1], tokens[2])); - + children.emplace_back(ChildInfo(typeData == "f" ? ChildInfo::FileType : ChildInfo::DirectoryType, tokens[1], tokens[2])); + children.back().path = absolutePath() / tokens[1]; if (tokens.size() > 3) { children.back().setSize(tokens[3]); } @@ -572,8 +566,7 @@ private: std::string hashForChild(const ChildInfo& child) const { - SGPath p(absolutePath()); - p.append(child.name); + SGPath p(child.path); if (child.type == ChildInfo::DirectoryType) { p.append(".dirindex"); } From 32189b72391c6f255bd5d87151ecbb110a5282fe Mon Sep 17 00:00:00 2001 From: James Turner Date: Sat, 1 Sep 2018 18:08:16 +0100 Subject: [PATCH 3/8] Event-manager: add dump() method for debugging --- simgear/structure/event_mgr.cxx | 16 ++++++++++++++++ simgear/structure/event_mgr.hxx | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/simgear/structure/event_mgr.cxx b/simgear/structure/event_mgr.cxx index 12e56d5d..435b18f8 100644 --- a/simgear/structure/event_mgr.cxx +++ b/simgear/structure/event_mgr.cxx @@ -119,6 +119,14 @@ void SGEventMgr::removeTask(const std::string& name) } } +void SGEventMgr::dump() +{ + SG_LOG(SG_GENERAL, SG_INFO, "EventMgr: sim-time queue:"); + _simQueue.dump(); + SG_LOG(SG_GENERAL, SG_INFO, "EventMgr: real-time queue:"); + _rtQueue.dump(); +} + //////////////////////////////////////////////////////////////////////// // SGTimerQueue // This is the priority queue implementation: @@ -270,3 +278,11 @@ SGTimer* SGTimerQueue::findByName(const std::string& name) const return NULL; } + +void SGTimerQueue::dump() +{ + for (int i=0; i < _numEntries; ++i) { + const auto t = _table[i].timer; + SG_LOG(SG_GENERAL, SG_INFO, "\ttimer:" << t->name << ", interval=" << t->interval); + } +} diff --git a/simgear/structure/event_mgr.hxx b/simgear/structure/event_mgr.hxx index 41dc7b86..eaaec7f0 100644 --- a/simgear/structure/event_mgr.hxx +++ b/simgear/structure/event_mgr.hxx @@ -38,6 +38,8 @@ public: double nextTime() { return -_table[0].pri; } SGTimer* findByName(const std::string& name) const; + + void dump(); private: // The "priority" is stored as a negative time. This allows the // implementation to treat the "top" of the heap as the largest @@ -119,6 +121,8 @@ public: void removeTask(const std::string& name); + + void dump(); private: friend class SGTimer; From f4cad429586c4904746b0b254fea8a92df5cdceb Mon Sep 17 00:00:00 2001 From: James Turner Date: Thu, 13 Sep 2018 23:47:24 +0200 Subject: [PATCH 4/8] Lat-lon parsing: catch exceptions from std::stod The standard library throws exceptions in some cases, catch those and return false. Extend the test coverage for some of the problematic cases. --- simgear/misc/strutils.cxx | 75 ++++++++++++++++++---------------- simgear/misc/strutils_test.cxx | 7 ++++ 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/simgear/misc/strutils.cxx b/simgear/misc/strutils.cxx index b15a73e7..88bf2d21 100644 --- a/simgear/misc/strutils.cxx +++ b/simgear/misc/strutils.cxx @@ -1136,44 +1136,49 @@ bool matchPropPathToTemplate(const std::string& path, const std::string& templat bool parseStringAsLatLonValue(const std::string& s, double& degrees) { - string ss = simplify(s); - auto spacePos = ss.find_first_of(" *"); - - if (spacePos == std::string::npos) { - degrees = std::stod(ss); - } else { - degrees = std::stod(ss.substr(0, spacePos)); + try { + string ss = simplify(s); + auto spacePos = ss.find_first_of(" *"); - double minutes = 0.0, seconds = 0.0; - - // check for minutes marker - auto quotePos = ss.find('\''); - if (quotePos == std::string::npos) { - const auto minutesStr = ss.substr(spacePos+1); - if (!minutesStr.empty()) { - minutes = std::stod(minutesStr); + if (spacePos == std::string::npos) { + degrees = std::stod(ss); + } else { + degrees = std::stod(ss.substr(0, spacePos)); + + double minutes = 0.0, seconds = 0.0; + + // check for minutes marker + auto quotePos = ss.find('\''); + if (quotePos == std::string::npos) { + const auto minutesStr = ss.substr(spacePos+1); + if (!minutesStr.empty()) { + minutes = std::stod(minutesStr); + } + } else { + minutes = std::stod(ss.substr(spacePos+1, quotePos - spacePos)); + const auto secondsStr = ss.substr(quotePos+1); + if (!secondsStr.empty()) { + seconds = std::stod(secondsStr); + } + } + + if ((seconds < 0.0) || (minutes < 0.0)) { + // don't allow sign information in minutes or seconds + return false; + } + + double offset = (minutes / 60.0) + (seconds / 3600.0); + degrees += (degrees >= 0.0) ? offset : -offset; } - } else { - minutes = std::stod(ss.substr(spacePos+1, quotePos - spacePos)); - const auto secondsStr = ss.substr(quotePos+1); - if (!secondsStr.empty()) { - seconds = std::stod(secondsStr); + + // since we simplified, any trailing N/S/E/W must be the last char + const char lastChar = ::toupper(ss.back()); + if ((lastChar == 'W') || (lastChar == 'S')) { + degrees = -degrees; } - } - - if ((seconds < 0.0) || (minutes < 0.0)) { - // don't allow sign information in minutes or seconds - return false; - } - - double offset = (minutes / 60.0) + (seconds / 3600.0); - degrees += (degrees >= 0.0) ? offset : -offset; - } - - // since we simplified, any trailing N/S/E/W must be the last char - const char lastChar = ::toupper(ss.back()); - if ((lastChar == 'W') || (lastChar == 'S')) { - degrees = -degrees; + } catch (std::exception&) { + // std::stdo can throw + return false; } return true; diff --git a/simgear/misc/strutils_test.cxx b/simgear/misc/strutils_test.cxx index 35ac5b79..d9559ad3 100644 --- a/simgear/misc/strutils_test.cxx +++ b/simgear/misc/strutils_test.cxx @@ -676,6 +676,13 @@ void test_parseGeod() SG_VERIFY(strutils::parseStringAsGeod("\t40 30'50\"S, 12 34'56\"W ", &a, true)); SG_CHECK_EQUAL_EP(a.getLongitudeDeg(), -12.58222222); SG_CHECK_EQUAL_EP(a.getLatitudeDeg(), -40.5138888); + + + // malformed inputs + + SG_VERIFY(strutils::parseStringAsGeod("12.345,", &a, true) == false); + double d; + SG_VERIFY(strutils::parseStringAsLatLonValue("", d) == false); } void test_formatGeod() From 0494af48a332d81344ce83ffdb2f9edab49485c2 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer Date: Fri, 21 Sep 2018 17:18:46 +0200 Subject: [PATCH 5/8] new version: 2018.3.1 --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index ddab0701..38bf3783 100644 --- a/version +++ b/version @@ -1 +1 @@ -2018.3.0 +2018.3.1 From 6d89cc6c1defb7f752ba4af5d9c65a7e307ae717 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer Date: Fri, 21 Sep 2018 17:18:46 +0200 Subject: [PATCH 6/8] new version: 2018.4.0 --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index 38bf3783..5c8cec8e 100644 --- a/version +++ b/version @@ -1 +1 @@ -2018.3.1 +2018.4.0 From 05da3db2edadb630f2a8e85d049ef7654dedca69 Mon Sep 17 00:00:00 2001 From: James Turner Date: Mon, 24 Sep 2018 14:54:20 +0100 Subject: [PATCH 7/8] Fix a debug message left in the terrasync code --- simgear/io/HTTPRepository.cxx | 3 --- 1 file changed, 3 deletions(-) diff --git a/simgear/io/HTTPRepository.cxx b/simgear/io/HTTPRepository.cxx index a2e009ba..bfa426a6 100644 --- a/simgear/io/HTTPRepository.cxx +++ b/simgear/io/HTTPRepository.cxx @@ -1049,9 +1049,6 @@ HTTPRepository::failure() const entry.lengthBytes = strtol(sizeData.c_str(), NULL, 10); hashes.push_back(entry); } - - SG_LOG(SG_TERRASYNC, SG_INFO, "restored hashes:" << hashes.size()); - } class DirectoryWithPath From 69e20a39317d9d1b7500bf3a5e11af3e5c6d4298 Mon Sep 17 00:00:00 2001 From: Scott Giese Date: Sat, 29 Sep 2018 18:41:00 -0500 Subject: [PATCH 8/8] Bug Fix #1922 Wrong retun type --- simgear/io/sg_binobj.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simgear/io/sg_binobj.cxx b/simgear/io/sg_binobj.cxx index 3fe3591f..82f1b458 100644 --- a/simgear/io/sg_binobj.cxx +++ b/simgear/io/sg_binobj.cxx @@ -160,7 +160,7 @@ public: } } - float readInt() + int32_t readInt() { unsigned int* p = reinterpret_cast(ptr + offset); if ( sgIsBigEndian() ) {