summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2016-01-04 17:48:34 -0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2016-01-04 17:55:37 -0800
commit3bfa8de2f7022370f6ab497a378be51018b49f35 (patch)
tree6d8373300f8a3efa4343916caaad500d6a7d9501
parent72ce77a5ee5127c374a56d3de741b808432b6ce5 (diff)
downloadsubsurface-3bfa8de2f7022370f6ab497a378be51018b49f35.tar.gz
Cloud storage: fix potential crash when avoiding reloading dive list
If we loaded the dive list from cache and then try to figure out if the remote repository had anything different, we were being super stupid if the SHA was identical... we had already cleared the dive list by the time we decided that we didn't need to load things. Granted, the model was still populated (oops), but the backend data structure was cleared and accesses to it (e.g., when drawing the profile) would cause things to crash. The helper function duplicates some code, but trying to not duplicate the code made things even harder to read. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--qt-mobile/qmlmanager.cpp11
-rw-r--r--subsurface-core/dive.h1
-rw-r--r--subsurface-core/file.c27
3 files changed, 32 insertions, 7 deletions
diff --git a/qt-mobile/qmlmanager.cpp b/qt-mobile/qmlmanager.cpp
index aebc65f92..90293e8bf 100644
--- a/qt-mobile/qmlmanager.cpp
+++ b/qt-mobile/qmlmanager.cpp
@@ -267,18 +267,16 @@ void QMLManager::loadDivesWithValidCredentials()
setStartPageText(tr("Cloud storage error: %1").arg(errorString));
return;
}
- clear_dive_file_data();
-
QByteArray fileNamePrt = QFile::encodeName(url);
- QString savedSHA(saved_git_id);
- int error = parse_file(fileNamePrt.data());
- if (savedSHA == saved_git_id) {
+ if (check_git_sha(fileNamePrt.data()) == 0) {
qDebug() << "local cache was current, no need to modify dive list";
appendTextToLog("Cloud sync shows local cache was current");
return;
}
- qDebug() << "had" << savedSHA << "got" << saved_git_id << ", so let's reload";
+ clear_dive_file_data();
+ DiveListModel::instance()->clear();
+ int error = parse_file(fileNamePrt.data());
if (!error) {
report_error("filename is now %s", fileNamePrt.data());
const char *error_string = get_error_string();
@@ -296,7 +294,6 @@ void QMLManager::loadDivesWithValidCredentials()
int i;
struct dive *d;
- DiveListModel::instance()->clear();
for_each_dive(i, d) {
DiveListModel::instance()->addDive(d);
}
diff --git a/subsurface-core/dive.h b/subsurface-core/dive.h
index ff7dbd2be..e96806d23 100644
--- a/subsurface-core/dive.h
+++ b/subsurface-core/dive.h
@@ -660,6 +660,7 @@ extern int parse_cobalt_buffer(sqlite3 *handle, const char *url, const char *buf
extern int parse_divinglog_buffer(sqlite3 *handle, const char *url, const char *buf, int size, struct dive_table *table);
extern int parse_dlf_buffer(unsigned char *buffer, size_t size);
+extern int check_git_sha(const char *filename);
extern int parse_file(const char *filename);
extern int parse_csv_file(const char *filename, char **params, int pnr, const char *csvtemplate);
extern int parse_seabear_csv_file(const char *filename, char **params, int pnr, const char *csvtemplate);
diff --git a/subsurface-core/file.c b/subsurface-core/file.c
index 62b38eddb..644956dbd 100644
--- a/subsurface-core/file.c
+++ b/subsurface-core/file.c
@@ -432,6 +432,33 @@ static int parse_file_buffer(const char *filename, struct memblock *mem)
return parse_xml_buffer(filename, mem->buffer, mem->size, &dive_table, NULL);
}
+int check_git_sha(const char *filename)
+{
+ struct git_repository *git;
+ const char *branch = NULL;
+
+ git = is_git_repository(filename, &branch, NULL, false);
+ if (prefs.cloud_git_url &&
+ strstr(filename, prefs.cloud_git_url)
+ && git == dummy_git_repository)
+ /* opening the cloud storage repository failed for some reason,
+ * so we don't know if there is additional data in the remote */
+ return 1;
+
+ /* if this is a git repository, do we already have this exact state loaded ?
+ * get the SHA and compare with what we currently have */
+ if (git && git != dummy_git_repository) {
+ const char *sha = get_sha(git, branch);
+ if (!same_string(sha, "") &&
+ same_string(sha, saved_git_id) &&
+ !unsaved_changes()) {
+ fprintf(stderr, "already have loaded SHA %s - don't load again\n", sha);
+ return 0;
+ }
+ }
+ return 1;
+}
+
int parse_file(const char *filename)
{
struct git_repository *git;