From b060df91e75dd44a914b3f0c3d185ed2c24eae78 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Wed, 28 Feb 2024 06:36:48 +0100 Subject: [PATCH] core: convert save-xml.c to C++ This includes using the C++ version of membuffer. There appears to not have been a leak, because the buffer is freed in flush_buffer(), but usage was somewhat inconsistent and hard to follow. Also, convert some string handling to std::string to avoid free() madness. Signed-off-by: Berthold Stoeger --- Subsurface-mobile.pro | 2 +- core/CMakeLists.txt | 2 +- core/{save-xml.c => save-xml.cpp} | 72 ++++++++++++------------------- 3 files changed, 30 insertions(+), 46 deletions(-) rename core/{save-xml.c => save-xml.cpp} (94%) diff --git a/Subsurface-mobile.pro b/Subsurface-mobile.pro index e8d43bfbf..7572f5bec 100644 --- a/Subsurface-mobile.pro +++ b/Subsurface-mobile.pro @@ -82,7 +82,7 @@ SOURCES += subsurface-mobile-main.cpp \ core/datatrak.c \ core/ostctools.c \ core/planner.c \ - core/save-xml.c \ + core/save-xml.cpp \ core/cochran.c \ core/deco.c \ core/divesite.c \ diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index fbc9c8013..abc51ec23 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -159,7 +159,7 @@ set(SUBSURFACE_CORE_LIB_SRCS save-html.c save-html.h save-profiledata.c - save-xml.c + save-xml.cpp selection.cpp selection.h sha1.c diff --git a/core/save-xml.c b/core/save-xml.cpp similarity index 94% rename from core/save-xml.c rename to core/save-xml.cpp index 56466b853..b70c52587 100644 --- a/core/save-xml.c +++ b/core/save-xml.cpp @@ -54,7 +54,6 @@ static void quote(struct membuffer *b, const char *text, int is_attribute) static void show_utf8(struct membuffer *b, const char *text, const char *pre, const char *post, int is_attribute) { int len; - char *cleaned; if (!text) return; @@ -69,27 +68,25 @@ static void show_utf8(struct membuffer *b, const char *text, const char *pre, co return; while (len && isascii(text[len - 1]) && isspace(text[len - 1])) len--; - cleaned = strndup(text, len); + std::string cleaned(text, len); put_string(b, pre); - quote(b, cleaned, is_attribute); + quote(b, cleaned.c_str(), is_attribute); put_string(b, post); - free(cleaned); } -static void blankout(char *c) +static void blankout(std::string &s) { - while(*c) { - switch (*c) { + for(char &c: s) { + switch (c) { case 'A'...'Z': - *c = 'X'; + c = 'X'; break; case 'a'...'z': - *c = 'x'; + c = 'x'; break; default: ; } - ++c; } } @@ -97,12 +94,11 @@ static void show_utf8_blanked(struct membuffer *b, const char *text, const char { if (!text) return; - char *copy = strdup(text); + std::string copy(text); if (anonymize) blankout(copy); - show_utf8(b, copy, pre, post, is_attribute); - free(copy); + show_utf8(b, copy.c_str(), pre, post, is_attribute); } static void save_depths(struct membuffer *b, struct divecomputer *dc) @@ -432,7 +428,7 @@ static void save_samples(struct membuffer *b, struct dive *dive, struct divecomp int nr; int o2sensor; struct sample *s; - struct sample dummy = { .bearing.degrees = -1, .ndl.seconds = -1 }; + struct sample dummy; /* Set up default pressure sensor indices */ o2sensor = legacy_format_o2pressures(dive, dc); @@ -464,9 +460,9 @@ static void save_dc(struct membuffer *b, struct dive *dive, struct divecomputer if (dc->duration.seconds && dc->duration.seconds != dive->dc.duration.seconds) put_duration(b, dc->duration, " duration='", " min'"); if (dc->divemode != OC) { - for (enum divemode_t i = 0; i < NUM_DIVEMODE; i++) - if (dc->divemode == i) - show_utf8(b, divemode_text[i], " dctype='", "'", 1); + int i = (int)dc->divemode; + if (i >= 0 && i < NUM_DIVEMODE) + show_utf8(b, divemode_text[i], " dctype='", "'", 1); if (dc->no_o2sensors) put_format(b," no_o2sensors='%d'", dc->no_o2sensors); } @@ -502,7 +498,7 @@ static void save_picture(struct membuffer *b, struct picture *pic) put_string(b, "/>\n"); } -void save_one_dive_to_mb(struct membuffer *b, struct dive *dive, bool anonymize) +extern "C" void save_one_dive_to_mb(struct membuffer *b, struct dive *dive, bool anonymize) { struct divecomputer *dc; pressure_t surface_pressure = un_fixup_surface_pressure(dive); @@ -561,9 +557,9 @@ void save_one_dive_to_mb(struct membuffer *b, struct dive *dive, bool anonymize) put_format(b, "\n"); } -int save_dive(FILE *f, struct dive *dive, bool anonymize) +extern "C" int save_dive(FILE *f, struct dive *dive, bool anonymize) { - struct membuffer buf = { 0 }; + struct membufferpp buf; save_one_dive_to_mb(&buf, dive, anonymize); flush_buffer(&buf, f); @@ -634,7 +630,7 @@ static void save_one_fingerprint(struct membuffer *b, int i) free(data); } -int save_dives(const char *filename) +extern "C" int save_dives(const char *filename) { return save_dives_logic(filename, false, false); } @@ -780,8 +776,7 @@ static void save_dives_buffer(struct membuffer *b, bool select_only, bool anonym static void save_backup(const char *name, const char *ext, const char *new_ext) { int len = strlen(name); - int a = strlen(ext), b = strlen(new_ext); - char *newname; + int a = strlen(ext); /* len up to and including the final '.' */ len -= a; @@ -793,20 +788,15 @@ static void save_backup(const char *name, const char *ext, const char *new_ext) if (strncasecmp(name + len, ext, a)) return; - newname = malloc(len + b + 1); - if (!newname) - return; - - memcpy(newname, name, len); - memcpy(newname + len, new_ext, b + 1); + std::string newname(name, len); + newname += new_ext; /* * Ignore errors. Maybe we can't create the backup file, * maybe no old file existed. Regardless, we'll write the * new file. */ - (void) subsurface_rename(name, newname); - free(newname); + (void) subsurface_rename(name, newname.c_str()); } static void try_to_backup(const char *filename) @@ -820,11 +810,8 @@ static void try_to_backup(const char *filename) int elen = strlen(extension[i]); if (strcasecmp(filename + flen - elen, extension[i]) == 0) { if (last_xml_version < DATAFORMAT_VERSION) { - int se_len = strlen(extension[i]) + 5; - char *special_ext = malloc(se_len); - snprintf(special_ext, se_len, "%s.v%d", extension[i], last_xml_version); - save_backup(filename, extension[i], special_ext); - free(special_ext); + std::string special_ext = std::string(extension[i]) + ".v" + std::to_string(last_xml_version); + save_backup(filename, extension[i], special_ext.c_str()); } else { save_backup(filename, extension[i], "bak"); } @@ -834,9 +821,9 @@ static void try_to_backup(const char *filename) } } -int save_dives_logic(const char *filename, const bool select_only, bool anonymize) +extern "C" int save_dives_logic(const char *filename, const bool select_only, bool anonymize) { - struct membuffer buf = { 0 }; + struct membufferpp buf; struct git_info info; FILE *f; int error = 0; @@ -863,7 +850,6 @@ int save_dives_logic(const char *filename, const bool select_only, bool anonymiz if (error) report_error(translate("gettextFromC", "Failed to save dives to %s (%s)"), filename, strerror(errno)); - free_buffer(&buf); return error; } @@ -880,7 +866,7 @@ int export_dives_xslt(const char *filename, const bool selected, const int units static int export_dives_xslt_doit(const char *filename, struct xml_params *params, bool selected, int units, const char *export_xslt, bool anonymize) { FILE *f; - struct membuffer buf = { 0 }; + struct membufferpp buf; xmlDoc *doc; xsltStylesheetPtr xslt = NULL; xmlDoc *transformed; @@ -901,7 +887,6 @@ static int export_dives_xslt_doit(const char *filename, struct xml_params *param * the XML into a character buffer. */ doc = xmlReadMemory(buf.buffer, buf.len, "divelog", NULL, XML_PARSE_HUGE | XML_PARSE_RECOVER); - free_buffer(&buf); if (!doc) return report_error("Failed to read XML memory"); @@ -961,9 +946,9 @@ static void save_dive_sites_buffer(struct membuffer *b, const struct dive_site * put_format(b, "\n"); } -int save_dive_sites_logic(const char *filename, const struct dive_site *sites[], int nr_sites, bool anonymize) +extern "C" int save_dive_sites_logic(const char *filename, const struct dive_site *sites[], int nr_sites, bool anonymize) { - struct membuffer buf = { 0 }; + struct membufferpp buf; FILE *f; int error = 0; @@ -983,6 +968,5 @@ int save_dive_sites_logic(const char *filename, const struct dive_site *sites[], if (error) report_error(translate("gettextFromC", "Failed to save divesites to %s (%s)"), filename, strerror(errno)); - free_buffer(&buf); return error; }