core: turn a few string helpers into C++

get_changes_made(), subsurface_user_agent() and normalize_cloud_name()
are only called from C++.

Avoids having to manually free the returned value and is therefore
more robust against leaks.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-02-27 23:10:09 +01:00 committed by Michael Keller
parent 924b23ed56
commit f1012283a0
4 changed files with 18 additions and 27 deletions

View file

@ -136,16 +136,15 @@ extern "C" char *get_local_dir(const char *url, const char *branch)
// That's trivial with QString operations and painful to do right in plain C, so // 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 // let's be lazy and call a C++ helper function
// just remember to free the string we get back // just remember to free the string we get back
const char *remote = normalize_cloud_name(url); std::string remote = normalize_cloud_name(url);
// That zero-byte update is so that we don't get hash // That zero-byte update is so that we don't get hash
// collisions for "repo1 branch" vs "repo 1branch". // collisions for "repo1 branch" vs "repo 1branch".
SHA1_Init(&ctx); SHA1_Init(&ctx);
SHA1_Update(&ctx, remote, strlen(remote)); SHA1_Update(&ctx, remote.c_str(), remote.size());
SHA1_Update(&ctx, "", 1); SHA1_Update(&ctx, "", 1);
SHA1_Update(&ctx, branch, strlen(branch)); SHA1_Update(&ctx, branch, strlen(branch));
SHA1_Final(hash, &ctx); SHA1_Final(hash, &ctx);
free((void *)remote);
return format_string("%s/cloudstorage/%02x%02x%02x%02x%02x%02x%02x%02x", return format_string("%s/cloudstorage/%02x%02x%02x%02x%02x%02x%02x%02x",
system_default_directory(), system_default_directory(),
hash[0], hash[1], hash[2], hash[3], hash[0], hash[1], hash[2], hash[3],
@ -432,9 +431,8 @@ static int try_to_git_merge(struct git_info *info, git_reference **local_p, git_
goto write_error; goto write_error;
if (get_authorship(info->repo, &author) < 0) if (get_authorship(info->repo, &author) < 0)
goto write_error; goto write_error;
const char *user_agent = subsurface_user_agent(); std::string user_agent = subsurface_user_agent();
put_format(&msg, "Automatic merge\n\nCreated by %s\n", user_agent); put_format(&msg, "Automatic merge\n\nCreated by %s\n", user_agent.c_str());
free((void *)user_agent);
if (git_commit_create_v(&commit_oid, info->repo, NULL, author, author, NULL, mb_cstring(&msg), merged_tree, 2, local_commit, remote_commit)) if (git_commit_create_v(&commit_oid, info->repo, NULL, author, author, NULL, mb_cstring(&msg), merged_tree, 2, local_commit, remote_commit))
goto write_error; goto write_error;
if (git_commit_lookup(&commit, info->repo, &commit_oid)) if (git_commit_lookup(&commit, info->repo, &commit_oid))

View file

@ -434,11 +434,9 @@ QString getUserAgent()
} }
extern "C" const char *subsurface_user_agent() std::string subsurface_user_agent()
{ {
static QString uA = getUserAgent(); return getUserAgent().toStdString();
return copy_qstring(uA);
} }
QString getUiLanguage() QString getUiLanguage()
@ -1396,13 +1394,13 @@ extern "C" char *cloud_url()
return copy_qstring(filename); return copy_qstring(filename);
} }
extern "C" const char *normalize_cloud_name(const char *remote_in) std::string normalize_cloud_name(const char *remote_in)
{ {
// replace ssrf-cloud-XX.subsurface... names with cloud.subsurface... names // replace ssrf-cloud-XX.subsurface... names with cloud.subsurface... names
// that trailing '/' is to match old code // that trailing '/' is to match old code
QString ri(remote_in); QString ri(remote_in);
ri.replace(QRegularExpression(CLOUD_HOST_PATTERN), CLOUD_HOST_GENERIC "/"); ri.replace(QRegularExpression(CLOUD_HOST_PATTERN), CLOUD_HOST_GENERIC "/");
return strdup(ri.toUtf8().constData()); return ri.toStdString();
} }
extern "C" bool getProxyString(char **buffer) extern "C" bool getProxyString(char **buffer)
@ -1627,12 +1625,10 @@ void uiNotification(const QString &msg)
// function to call to get changes for a git commit // function to call to get changes for a git commit
QString (*changesCallback)() = nullptr; QString (*changesCallback)() = nullptr;
extern "C" char *get_changes_made() std::string get_changes_made()
{ {
if (changesCallback != nullptr) return changesCallback != nullptr ? changesCallback().toStdString()
return copy_qstring(changesCallback()); : std::string();
else
return nullptr;
} }
// Generate a cylinder-renumber map for use when the n-th cylinder // Generate a cylinder-renumber map for use when the n-th cylinder

View file

@ -98,6 +98,9 @@ std::vector<int> get_cylinder_map_for_add(int count, int n);
extern QString (*changesCallback)(); extern QString (*changesCallback)();
void uiNotification(const QString &msg); void uiNotification(const QString &msg);
std::string get_changes_made();
std::string subsurface_user_agent();
std::string normalize_cloud_name(const char *remote_in);
#if defined __APPLE__ #if defined __APPLE__
#define TITLE_OR_TEXT(_t, _m) "", _t + "\n" + _m #define TITLE_OR_TEXT(_t, _m) "", _t + "\n" + _m
@ -126,10 +129,8 @@ void copy_image_and_overwrite(const char *cfileName, const char *path, const cha
char *move_away(const char *path); char *move_away(const char *path);
const char *local_file_path(struct picture *picture); const char *local_file_path(struct picture *picture);
char *cloud_url(); char *cloud_url();
const char *normalize_cloud_name(const char *remote_in);
char *hashfile_name_string(); char *hashfile_name_string();
char *picturedir_string(); char *picturedir_string();
const char *subsurface_user_agent();
enum deco_mode decoMode(bool in_planner); enum deco_mode decoMode(bool in_planner);
void parse_seabear_header(const char *filename, struct xml_params *params); void parse_seabear_header(const char *filename, struct xml_params *params);
char *get_current_date(); char *get_current_date();
@ -143,7 +144,6 @@ depth_t string_to_depth(const char *str);
pressure_t string_to_pressure(const char *str); pressure_t string_to_pressure(const char *str);
volume_t string_to_volume(const char *str, pressure_t workp); volume_t string_to_volume(const char *str, pressure_t workp);
fraction_t string_to_fraction(const char *str); fraction_t string_to_fraction(const char *str);
char *get_changes_made();
void emit_reset_signal(); void emit_reset_signal();
extern void report_info(const char *fmt, ...); extern void report_info(const char *fmt, ...);

View file

@ -1143,12 +1143,12 @@ static void create_commit_message(struct membuffer *msg, bool create_empty)
{ {
int nr = divelog.dives->nr; int nr = divelog.dives->nr;
struct dive *dive = get_dive(nr-1); struct dive *dive = get_dive(nr-1);
char* changes_made = get_changes_made(); std::string changes_made = get_changes_made();
if (create_empty) { if (create_empty) {
put_string(msg, "Initial commit to create empty repo.\n\n"); put_string(msg, "Initial commit to create empty repo.\n\n");
} else if (!empty_string(changes_made)) { } else if (!changes_made.empty()) {
put_format(msg, "Changes made: \n\n%s\n", changes_made); put_format(msg, "Changes made: \n\n%s\n", changes_made.c_str());
} else if (dive) { } else if (dive) {
dive_trip_t *trip = dive->divetrip; dive_trip_t *trip = dive->divetrip;
const char *location = get_dive_location(dive) ? : "no location"; const char *location = get_dive_location(dive) ? : "no location";
@ -1170,10 +1170,7 @@ static void create_commit_message(struct membuffer *msg, bool create_empty)
} while ((dc = dc->next) != NULL); } while ((dc = dc->next) != NULL);
put_format(msg, "\n"); put_format(msg, "\n");
} }
const char *user_agent = subsurface_user_agent(); put_format(msg, "Created by %s\n", subsurface_user_agent().c_str());
put_format(msg, "Created by %s\n", user_agent);
free((void *)user_agent);
free(changes_made);
if (verbose) if (verbose)
SSRF_INFO("Commit message:\n\n%s\n", mb_cstring(msg)); SSRF_INFO("Commit message:\n\n%s\n", mb_cstring(msg));
} }