aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2021-04-11 15:26:06 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2021-04-19 12:51:01 -0700
commitcfe20ee5f4f77a3a42ba301bdd69f5585c46184c (patch)
tree54caed8f5dbbef0e557ec2b01a0667b709e76a5d /core
parent7fa031b648fedeaa35eb4da8003cd521cf65c4e3 (diff)
downloadsubsurface-cfe20ee5f4f77a3a42ba301bdd69f5585c46184c.tar.gz
cloudstorage: create consistent local directory names
With the new names for the cloud server we'd get different local cache directory names depending on which server gets used. In order to avoid that, normalize the name before generating the hash that determines the local directory name. Additionally, the old code had an extra '/' in the URL, due to the way the URL was assembled. Again, to match the existing hash for people upgrading from older Subsurface versions, add that to our normalized name as well. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'core')
-rw-r--r--core/git-access.c15
-rw-r--r--core/qthelper.cpp10
-rw-r--r--core/qthelper.h1
3 files changed, 24 insertions, 2 deletions
diff --git a/core/git-access.c b/core/git-access.c
index bd958b517..31ab9f1d8 100644
--- a/core/git-access.c
+++ b/core/git-access.c
@@ -130,11 +130,22 @@ static int push_transfer_progress_cb(unsigned int current, unsigned int total, s
return git_storage_update_progress(buf);
}
-char *get_local_dir(const char *remote, const char *branch)
+char *get_local_dir(const char *remote_in, const char *branch)
{
SHA_CTX ctx;
unsigned char hash[20];
+ // this optimization could in theory lead to odd things happening if the
+ // cloud backend servers ever get out of sync - but when a user switches
+ // between those servers (either because one is down, or because the algorithm
+ // which server to pick changed, or because the user is on a different continent),
+ // then the hash and therefore the local directory would change. To prevent that
+ // from happening, normalize the cloud string to always use the old default name.
+ // That's trivial with QString operations and painful to do right in plain C, so
+ // let's be lazy and call a C++ helper function
+ // just remember to free the string we get back
+ const char *remote = normalize_cloud_name(remote_in);
+
// That zero-byte update is so that we don't get hash
// collisions for "repo1 branch" vs "repo 1branch".
SHA1_Init(&ctx);
@@ -142,7 +153,7 @@ char *get_local_dir(const char *remote, const char *branch)
SHA1_Update(&ctx, "", 1);
SHA1_Update(&ctx, branch, strlen(branch));
SHA1_Final(hash, &ctx);
-
+ free((void *)remote);
return format_string("%s/cloudstorage/%02x%02x%02x%02x%02x%02x%02x%02x",
system_default_directory(),
hash[0], hash[1], hash[2], hash[3],
diff --git a/core/qthelper.cpp b/core/qthelper.cpp
index 6678cc87f..185e46bbc 100644
--- a/core/qthelper.cpp
+++ b/core/qthelper.cpp
@@ -22,6 +22,7 @@
#include "trip.h"
#include "imagedownloader.h"
#include "xmlparams.h"
+#include "core/git-access.h" // for CLOUD_HOST definitions
#include <QFile>
#include <QRegExp>
#include <QDir>
@@ -1455,6 +1456,15 @@ extern "C" char *cloud_url()
return copy_qstring(filename);
}
+extern "C" const char *normalize_cloud_name(const char *remote_in)
+{
+ // replace ssrf-cloud-XX.subsurface... names with cloud.subsurface... names
+ // that trailing '/' is to match old code
+ QString ri(remote_in);
+ ri.replace(QRegularExpression(CLOUD_HOST_PATTERN), CLOUD_HOST_GENERIC "/");
+ return strdup(ri.toUtf8().constData());
+}
+
extern "C" bool getProxyString(char **buffer)
{
if (prefs.proxy_type == QNetworkProxy::HttpProxy) {
diff --git a/core/qthelper.h b/core/qthelper.h
index 135689c69..1fc2e55f3 100644
--- a/core/qthelper.h
+++ b/core/qthelper.h
@@ -147,6 +147,7 @@ void copy_image_and_overwrite(const char *cfileName, const char *path, const cha
char *move_away(const char *path);
const char *local_file_path(struct picture *picture);
char *cloud_url();
+const char *normalize_cloud_name(const char *remote_in);
char *hashfile_name_string();
char *picturedir_string();
const char *subsurface_user_agent();