From a4834e198d55d50a44d6f80e2137777b64652ce7 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Wed, 14 Mar 2018 07:50:04 +0100 Subject: [PATCH] Cleanup: fix "unsave" snprintf()s in plannernotes.c The planner notes were constructed using a sequence of len += snprintf(buf, buflen - len, ...); calls. This will fail once len > buflen, because the second parameter of snprintf is unsigned. Note that snprintf returns the number of bytes that would have been written if it weren't truncated. Fix this by using membuffer with put_format()/put_string() and asprintf_loc(). Fixes #1155. Signed-off-by: Berthold Stoeger --- core/plannernotes.c | 241 ++++++++++++++++++++------------------------ 1 file changed, 107 insertions(+), 134 deletions(-) diff --git a/core/plannernotes.c b/core/plannernotes.c index e05f27738..eb6dc018f 100644 --- a/core/plannernotes.c +++ b/core/plannernotes.c @@ -18,6 +18,7 @@ #include "qthelper.h" #include "format.h" #include "version.h" +#include "membuffer.h" static int diveplan_duration(struct diveplan *diveplan) { @@ -41,28 +42,21 @@ static int diveplan_duration(struct diveplan *diveplan) * 5) Pointers to gas mixes in the gas change: gas-from and gas-to. * Returns: The size of the output buffer that has been used after the new results have been added. */ -static int add_icd_entry(char *icdbuffer, unsigned int maxsize, struct icd_data *icdvalues, bool printheader, int time_seconds, int ambientpressure_mbar, struct gasmix *gas_from, struct gasmix *gas_to) +static void add_icd_entry(struct membuffer *b, struct icd_data *icdvalues, bool printheader, int time_seconds, int ambientpressure_mbar, struct gasmix *gas_from, struct gasmix *gas_to) { - int len = 0; if (printheader) { // Create a table description and a table header if no icd data have been written yet. - len = snprintf(icdbuffer + len, maxsize - len, "
%s:", - translate("gettextFromC","Isobaric counterdiffusion information")); - len += snprintf(icdbuffer + len, maxsize - len, "", - translate("gettextFromC", "runtime")); - len += snprintf(icdbuffer + len, maxsize - len, "", - translate("gettextFromC", "gaschange")); - len += snprintf(icdbuffer + len, maxsize - len, "", - translate("gettextFromC", "ΔHe")); - len += snprintf(icdbuffer + len, maxsize - len, "", - translate("gettextFromC", "ΔN₂")); - len += snprintf(icdbuffer + len, maxsize - len, "", - translate("gettextFromC", "max ΔN₂")); + put_format(b, "
%s:", translate("gettextFromC","Isobaric counterdiffusion information")); + put_format(b, "
%s%s%s%s%s
", translate("gettextFromC", "runtime")); + put_format(b, "", translate("gettextFromC", "gaschange")); + put_format(b, "", translate("gettextFromC", "ΔHe")); + put_format(b, "", translate("gettextFromC", "ΔN₂")); + put_format(b, "", translate("gettextFromC", "max ΔN₂")); } // Add one entry to the icd table: - len += snprintf_loc(icdbuffer + len, maxsize - len, + put_format_loc(b, "" "" "" "" @@ -74,21 +68,14 @@ static int add_icd_entry(char *icdbuffer, unsigned int maxsize, struct icd_data ambientpressure_mbar * icdvalues->dHe / 1e6f, translate("gettextFromC", "bar"), ((5 * icdvalues->dN2) > -icdvalues->dHe) ? "red" : "#383838", ambientpressure_mbar * icdvalues->dN2 / 1e6f, translate("gettextFromC", "bar"), ambientpressure_mbar * -icdvalues->dHe / 5e6f, translate("gettextFromC", "bar")); - return len; } void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_disclaimer, int error) { - const unsigned int sz_buffer = 2000000; - const unsigned int sz_temp = 100000; - const unsigned int sz_icdbuf = 10000; - char *buffer = (char *)malloc(sz_buffer); - char *temp = (char *)malloc(sz_temp); - char *icdbuffer = (char *)malloc(sz_icdbuf); + struct membuffer buf = { 0 }; + struct membuffer icdbuf = { 0 }; const char *deco, *segmentsymbol; - static char buf[1000]; - int len, lastdepth = 0, lasttime = 0, lastsetpoint = -1, newdepth = 0, lastprintdepth = 0, lastprintsetpoint = -1; - int icdlen = 0; + int lastdepth = 0, lasttime = 0, lastsetpoint = -1, newdepth = 0, lastprintdepth = 0, lastprintsetpoint = -1; struct gasmix lastprintgasmix = {{ -1 }, { -1 }}; struct divedatapoint *dp = diveplan->dp; bool plan_verbatim = prefs.verbatim_plan; @@ -102,6 +89,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d struct divedatapoint *nextdp = NULL; struct divedatapoint *lastbottomdp = NULL; struct icd_data icdvalues; + char *temp; if (decoMode() == VPMB) { deco = translate("gettextFromC", "VPM-B"); @@ -109,36 +97,34 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d deco = translate("gettextFromC", "BUHLMANN"); } - snprintf(buf, sizeof(buf), translate("gettextFromC", "DISCLAIMER / WARNING: THIS IS A NEW IMPLEMENTATION OF THE %s " - "ALGORITHM AND A DIVE PLANNER IMPLEMENTATION BASED ON THAT WHICH HAS " - "RECEIVED ONLY A LIMITED AMOUNT OF TESTING. WE STRONGLY RECOMMEND NOT TO " - "PLAN DIVES SIMPLY BASED ON THE RESULTS GIVEN HERE."), deco); - disclaimer = buf; - if (!dp) - goto finished; + return; if (error) { - snprintf(temp, sz_temp, "%s", - translate("gettextFromC", "Decompression calculation aborted due to excessive time")); - snprintf(buffer, sz_buffer, "%s %s
", - translate("gettextFromC", "Warning:"), temp); - dive->notes = strdup(buffer); + put_format(&buf, "%s %s
", + translate("gettextFromC", "Warning:"), + translate("gettextFromC", "Decompression calculation aborted due to excessive time")); goto finished; } - len = show_disclaimer ? snprintf(buffer, sz_buffer, "
%s
", disclaimer) : 0; + if (show_disclaimer) { + put_string(&buf, "
"); + put_format(&buf, translate("gettextFromC", "DISCLAIMER / WARNING: THIS IS A NEW IMPLEMENTATION OF THE %s " + "ALGORITHM AND A DIVE PLANNER IMPLEMENTATION BASED ON THAT WHICH HAS " + "RECEIVED ONLY A LIMITED AMOUNT OF TESTING. WE STRONGLY RECOMMEND NOT TO " + "PLAN DIVES SIMPLY BASED ON THE RESULTS GIVEN HERE."), deco); + put_string(&buf, "
"); + } if (diveplan->surface_interval < 0) { - len += snprintf(buffer + len, sz_buffer - len, "
%s (%s) %s
", + put_format(&buf, "
%s (%s) %s
", translate("gettextFromC", "Subsurface"), subsurface_canonical_version(), translate("gettextFromC", "dive plan
(overlapping dives detected)")); - dive->notes = strdup(buffer); goto finished; } else if (diveplan->surface_interval >= 48 * 60 *60) { char *current_date = get_current_date(); - len += snprintf(buffer + len, sz_buffer - len, "
%s (%s) %s %s
", + put_format(&buf, "
%s (%s) %s %s
", translate("gettextFromC", "Subsurface"), subsurface_canonical_version(), translate("gettextFromC", "dive plan
created on"), @@ -146,7 +132,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d free(current_date); } else { char *current_date = get_current_date(); - len += snprintf_loc(buffer + len, sz_buffer - len, "
%s (%s) %s %d:%02d) %s %s
", + put_format_loc(&buf, "
%s (%s) %s %d:%02d) %s %s
", translate("gettextFromC", "Subsurface"), subsurface_canonical_version(), translate("gettextFromC", "dive plan
(surface interval "), @@ -157,23 +143,19 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d } if (prefs.display_variations && decoMode() != RECREATIONAL) - len += snprintf_loc(buffer + len, sz_buffer - len, translate("gettextFromC", "Runtime: %dmin%s"), + put_format_loc(&buf, translate("gettextFromC", "Runtime: %dmin%s"), diveplan_duration(diveplan), "VARIATIONS
"); else - len += snprintf_loc(buffer + len, sz_buffer - len, translate("gettextFromC", "Runtime: %dmin
"), + put_format_loc(&buf, translate("gettextFromC", "Runtime: %dmin
"), diveplan_duration(diveplan)); if (!plan_verbatim) { - len += snprintf(buffer + len, sz_buffer - len, "
%s%s%s%s%s
%3d%s%s➙", (time_seconds + 30) / 60, translate("gettextFromC", "min"), gasname(gas_from)); - len += snprintf_loc(icdbuffer + len, maxsize - len, + put_format_loc(b, "%s%+5.1f%%%+5.1f%%%+5.1f%%
", - translate("gettextFromC", "depth")); + put_format(&buf, "
%s
", translate("gettextFromC", "depth")); if (plan_display_duration) - len += snprintf(buffer + len, sz_buffer - len, "", - translate("gettextFromC", "duration")); + put_format(&buf, "", translate("gettextFromC", "duration")); if (plan_display_runtime) - len += snprintf(buffer + len, sz_buffer - len, "", - translate("gettextFromC", "runtime")); - len += snprintf(buffer + len, sz_buffer - len, - "", + put_format(&buf, "", translate("gettextFromC", "runtime")); + put_format(&buf, "", translate("gettextFromC", "gas")); } @@ -211,7 +193,6 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d if (dp->entered && !nextdp->entered) lastbottomdp = dp; - len = strlen(buffer); if (plan_verbatim) { /* When displaying a verbatim plan, we output a waypoint for every gas change. * Therefore, we do not need to test for difficult cases that mean we need to @@ -222,7 +203,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d if (dp->depth.mm != lastprintdepth) { if (plan_display_transitions || dp->entered || !dp->next || (gaschange_after && dp->next && dp->depth.mm != nextdp->depth.mm)) { if (dp->setpoint) { - snprintf_loc(temp, sz_temp, translate("gettextFromC", "%s to %.*f %s in %d:%02d min - runtime %d:%02u on %s (SP = %.1fbar)"), + put_format_loc(&buf, translate("gettextFromC", "%s to %.*f %s in %d:%02d min - runtime %d:%02u on %s (SP = %.1fbar)"), dp->depth.mm < lastprintdepth ? translate("gettextFromC", "Ascend") : translate("gettextFromC", "Descend"), decimals, depthvalue, depth_unit, FRACTION(dp->time - lasttime, 60), @@ -230,34 +211,35 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d gasname(&gasmix), (double) dp->setpoint / 1000.0); } else { - snprintf_loc(temp, sz_temp, translate("gettextFromC", "%s to %.*f %s in %d:%02d min - runtime %d:%02u on %s"), + put_format_loc(&buf, translate("gettextFromC", "%s to %.*f %s in %d:%02d min - runtime %d:%02u on %s"), dp->depth.mm < lastprintdepth ? translate("gettextFromC", "Ascend") : translate("gettextFromC", "Descend"), decimals, depthvalue, depth_unit, FRACTION(dp->time - lasttime, 60), FRACTION(dp->time, 60), gasname(&gasmix)); } - len += snprintf(buffer + len, sz_buffer - len, "%s
", temp); + + put_string(&buf, "
"); } newdepth = dp->depth.mm; lasttime = dp->time; } else { if ((nextdp && dp->depth.mm != nextdp->depth.mm) || gaschange_after) { if (dp->setpoint) { - snprintf_loc(temp, sz_temp, translate("gettextFromC", "Stay at %.*f %s for %d:%02d min - runtime %d:%02u on %s (SP = %.1fbar)"), + put_format_loc(&buf, translate("gettextFromC", "Stay at %.*f %s for %d:%02d min - runtime %d:%02u on %s (SP = %.1fbar)"), decimals, depthvalue, depth_unit, FRACTION(dp->time - lasttime, 60), FRACTION(dp->time, 60), gasname(&gasmix), (double) dp->setpoint / 1000.0); } else { - snprintf_loc(temp, sz_temp, translate("gettextFromC", "Stay at %.*f %s for %d:%02d min - runtime %d:%02u on %s"), + put_format_loc(&buf, translate("gettextFromC", "Stay at %.*f %s for %d:%02d min - runtime %d:%02u on %s"), decimals, depthvalue, depth_unit, FRACTION(dp->time - lasttime, 60), FRACTION(dp->time, 60), gasname(&gasmix)); } - len += snprintf(buffer + len, sz_buffer - len, "%s
", temp); + put_string(&buf, "
"); newdepth = dp->depth.mm; lasttime = dp->time; } @@ -295,17 +277,20 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d else segmentsymbol = "-"; // minus sign (a.k.a. horizontal line) for deco stop - len += snprintf(buffer + len, sz_buffer - len, "
", segmentsymbol); + put_format(&buf, "", segmentsymbol); - snprintf(temp, sz_temp, translate("gettextFromC", "%3.0f%s"), depthvalue, depth_unit); - len += snprintf(buffer + len, sz_buffer - len, "", temp); + asprintf_loc(&temp, translate("gettextFromC", "%3.0f%s"), depthvalue, depth_unit); + put_format(&buf, "", temp); + free(temp); if (plan_display_duration) { - snprintf(temp, sz_temp, translate("gettextFromC", "%3dmin"), (dp->time - lasttime + 30) / 60); - len += snprintf(buffer + len, sz_buffer - len, "", temp); + asprintf_loc(&temp, translate("gettextFromC", "%3dmin"), (dp->time - lasttime + 30) / 60); + put_format(&buf, "", temp); + free(temp); } if (plan_display_runtime) { - snprintf(temp, sz_temp, translate("gettextFromC", "%3dmin"), (dp->time + 30) / 60); - len += snprintf(buffer + len, sz_buffer - len, "", temp); + asprintf_loc(&temp, translate("gettextFromC", "%3dmin"), (dp->time + 30) / 60); + put_format(&buf, "", temp); + free(temp); } /* Normally a gas change is displayed on the stopping segment, so only display a gas change at the end of @@ -313,17 +298,18 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d */ if ((isascent || dp->entered) && gaschange_after && dp->next && nextdp && (dp->depth.mm != nextdp->depth.mm || nextdp->entered)) { if (dp->setpoint) { - snprintf_loc(temp, sz_temp, translate("gettextFromC", "(SP = %.1fbar)"), (double) nextdp->setpoint / 1000.0); - len += snprintf(buffer + len, sz_buffer - len, "", + asprintf_loc(&temp, translate("gettextFromC", "(SP = %.1fbar)"), nextdp->setpoint / 1000.0); + put_format(&buf, "", gasname(&newgasmix), temp); + free(temp); } else { - len += snprintf(buffer + len, sz_buffer - len, "", + put_format(&buf, "", gasname(&newgasmix)); if (isascent && (get_he(&lastprintgasmix) > 0)) { // For a trimix gas change on ascent, save ICD info if previous cylinder had helium if (isobaric_counterdiffusion(&lastprintgasmix, &newgasmix, &icdvalues)) // Do icd calulations icdwarning = true; if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen.. - icdlen += add_icd_entry(icdbuffer+icdlen, sz_icdbuf-icdlen, &icdvalues, icdtableheader, dp->time, depth_to_mbar(dp->depth.mm, dive), &lastprintgasmix, &newgasmix); // .. then print calculations to buffer. + add_icd_entry(&icdbuf, &icdvalues, icdtableheader, dp->time, depth_to_mbar(dp->depth.mm, dive), &lastprintgasmix, &newgasmix); // .. then print calculations to buffer. icdtableheader = false; } } @@ -334,17 +320,16 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d } else if (gaschange_before) { // If a new gas has been used for this segment, now is the time to show it if (dp->setpoint) { - snprintf_loc(temp, sz_temp, translate("gettextFromC", "(SP = %.1fbar)"), (double) dp->setpoint / 1000.0); - len += snprintf(buffer + len, sz_buffer - len, "", - gasname(&gasmix), temp); + asprintf_loc(&temp, translate("gettextFromC", "(SP = %.1fbar)"), (double) dp->setpoint / 1000.0); + put_format(&buf, "", gasname(&gasmix), temp); + free(temp); } else { - len += snprintf(buffer + len, sz_buffer - len, "", - gasname(&gasmix)); + put_format(&buf, "", gasname(&gasmix)); if (get_he(&lastprintgasmix) > 0) { // For a trimix gas change, save ICD info if previous cylinder had helium if (isobaric_counterdiffusion(&lastprintgasmix, &gasmix, &icdvalues)) // Do icd calculations icdwarning = true; if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen.. - icdlen += add_icd_entry(icdbuffer+icdlen, sz_icdbuf-icdlen, &icdvalues, icdtableheader, lasttime, depth_to_mbar(dp->depth.mm, dive), &lastprintgasmix, &gasmix); // .. then print data to buffer. + add_icd_entry(&icdbuf, &icdvalues, icdtableheader, lasttime, depth_to_mbar(dp->depth.mm, dive), &lastprintgasmix, &gasmix); // .. then print data to buffer. icdtableheader = false; } } @@ -354,9 +339,9 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d lastprintgasmix = gasmix; gaschange_after = false; } else { - len += snprintf(buffer + len, sz_buffer - len, ""); + put_string(&buf, ""); } - len += snprintf(buffer + len, sz_buffer - len, ""); + put_string(&buf, ""); newdepth = dp->depth.mm; lasttime = dp->time; } @@ -366,19 +351,19 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d if (plan_verbatim) { if (lastsetpoint >= 0) { if (nextdp && nextdp->setpoint) { - snprintf_loc(temp, sz_temp, translate("gettextFromC", "Switch gas to %s (SP = %.1fbar)"), gasname(&newgasmix), (double) nextdp->setpoint / 1000.0); + put_format_loc(&buf, translate("gettextFromC", "Switch gas to %s (SP = %.1fbar)"), gasname(&newgasmix), (double) nextdp->setpoint / 1000.0); } else { - snprintf(temp, sz_temp, translate("gettextFromC", "Switch gas to %s"), gasname(&newgasmix)); + put_format(&buf, translate("gettextFromC", "Switch gas to %s"), gasname(&newgasmix)); if ((isascent) && (get_he(&lastprintgasmix) > 0)) { // For a trimix gas change on ascent: if (isobaric_counterdiffusion(&lastprintgasmix, &newgasmix, &icdvalues)) // Do icd calculations icdwarning = true; if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen.. - icdlen += add_icd_entry(icdbuffer+icdlen, sz_icdbuf-icdlen, &icdvalues, icdtableheader, dp->time, depth_to_mbar(dp->depth.mm, dive), &lastprintgasmix, &newgasmix); // ... then print data to buffer. + add_icd_entry(&icdbuf, &icdvalues, icdtableheader, dp->time, depth_to_mbar(dp->depth.mm, dive), &lastprintgasmix, &newgasmix); // ... then print data to buffer. icdtableheader = false; } } } - len += snprintf(buffer + len, sz_buffer - len, "%s
", temp); + put_string(&buf, "
"); } lastprintgasmix = newgasmix; gaschange_after = false; @@ -391,42 +376,36 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d lastentered = dp->entered; } while ((dp = nextdp) != NULL); if (!plan_verbatim) - len += snprintf(buffer + len, sz_buffer - len, "
%s%s%s%s%s
%s%s
%s
%s%s%s%s%s%s%s%s %s%s %s%s%s%s %s%s %s%s%s  

"); + put_string(&buf, "
"); /* Print the CNS and OTU next.*/ dive->cns = 0; dive->maxcns = 0; update_cylinder_related_info(dive); - snprintf(temp, sz_temp, "%s", translate("gettextFromC", "CNS")); - len += snprintf_loc(buffer + len, sz_buffer - len, "
%s: %i%%", temp, dive->cns); - snprintf(temp, sz_temp, "%s", translate("gettextFromC", "OTU")); - len += snprintf_loc(buffer + len, sz_buffer - len, "
%s: %i
", temp, dive->otu); + put_format_loc(&buf, "
%s: %i%%", translate("gettextFromC", "CNS"), dive->cns); + put_format_loc(&buf, "
%s: %i
", translate("gettextFromC", "OTU"), dive->otu); /* Print the settings for the diveplan next. */ + put_string(&buf, "
"); if (decoMode() == BUEHLMANN) { - snprintf_loc(temp, sz_temp, translate("gettextFromC", "Deco model: Bühlmann ZHL-16C with GFLow = %d%% and GFHigh = %d%%"), - diveplan->gflow, diveplan->gfhigh); + put_format_loc(&buf, translate("gettextFromC", "Deco model: Bühlmann ZHL-16C with GFLow = %d%% and GFHigh = %d%%"), diveplan->gflow, diveplan->gfhigh); } else if (decoMode() == VPMB){ - int temp_len; if (diveplan->vpmb_conservatism == 0) - temp_len = snprintf(temp, sz_temp, "%s", translate("gettextFromC", "Deco model: VPM-B at nominal conservatism")); + put_string(&buf, translate("gettextFromC", "Deco model: VPM-B at nominal conservatism")); else - temp_len = snprintf_loc(temp, sz_temp, translate("gettextFromC", "Deco model: VPM-B at +%d conservatism"), diveplan->vpmb_conservatism); + put_format_loc(&buf, translate("gettextFromC", "Deco model: VPM-B at +%d conservatism"), diveplan->vpmb_conservatism); if (diveplan->eff_gflow) - temp_len += snprintf_loc(temp + temp_len, sz_temp - temp_len, translate("gettextFromC", ", effective GF=%d/%d"), diveplan->eff_gflow, - diveplan->eff_gfhigh); - + put_format_loc(&buf, translate("gettextFromC", ", effective GF=%d/%d"), diveplan->eff_gflow, diveplan->eff_gfhigh); } else if (decoMode() == RECREATIONAL){ - snprintf_loc(temp, sz_temp, translate("gettextFromC", "Deco model: Recreational mode based on Bühlmann ZHL-16B with GFLow = %d%% and GFHigh = %d%%"), + put_format_loc(&buf, translate("gettextFromC", "Deco model: Recreational mode based on Bühlmann ZHL-16B with GFLow = %d%% and GFHigh = %d%%"), diveplan->gflow, diveplan->gfhigh); } - len += snprintf(buffer + len, sz_buffer - len, "
%s
",temp); + put_string(&buf, "
"); const char *depth_unit; int altitude = (int) get_depth_units((int) (log(1013.0 / diveplan->surface_pressure) * 7800000), NULL, &depth_unit); - len += snprintf_loc(buffer + len, sz_buffer - len, translate("gettextFromC", "ATM pressure: %dmbar (%d%s)
"), - diveplan->surface_pressure, altitude, depth_unit); + put_format_loc(&buf, translate("gettextFromC", "ATM pressure: %dmbar (%d%s)
"), diveplan->surface_pressure, altitude, depth_unit); /* Get SAC values and units for printing it in gas consumption */ double bottomsacvalue, decosacvalue; @@ -441,11 +420,12 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d /* Print the gas consumption next.*/ if (dive->dc.divemode == CCR) - snprintf(temp, sz_temp, "%s", translate("gettextFromC", "Gas consumption (CCR legs excluded):")); + temp = strdup(translate("gettextFromC", "Gas consumption (CCR legs excluded):")); else - snprintf_loc(temp, sz_temp, "%s %.*f|%.*f%s/min):", translate("gettextFromC", "Gas consumption (based on SAC"), + asprintf_loc(&temp, "%s %.*f|%.*f%s/min):", translate("gettextFromC", "Gas consumption (based on SAC"), sacdecimals, bottomsacvalue, sacdecimals, decosacvalue, sacunit); - len += snprintf(buffer + len, sz_buffer - len, "
%s
", temp); + put_format(&buf, "
%s
", temp); + free(temp); /* Print gas consumption: This loop covers all cylinders */ for (int gasidx = 0; gasidx < MAX_CYLINDERS; gasidx++) { @@ -521,36 +501,38 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d } /* Print the gas consumption for every cylinder here to temp buffer. */ if (lrint(volume) > 0) { - snprintf_loc(temp, sz_temp, translate("gettextFromC", "%.0f%s/%.0f%s of %s (%.0f%s/%.0f%s in planned ascent)"), + asprintf_loc(&temp, translate("gettextFromC", "%.0f%s/%.0f%s of %s (%.0f%s/%.0f%s in planned ascent)"), volume, unit, pressure, pressure_unit, gasname(&cyl->gasmix), deco_volume, unit, deco_pressure, pressure_unit); } else { - snprintf_loc(temp, sz_temp, translate("gettextFromC", "%.0f%s/%.0f%s of %s"), + asprintf_loc(&temp, translate("gettextFromC", "%.0f%s/%.0f%s of %s"), volume, unit, pressure, pressure_unit, gasname(&cyl->gasmix)); } } else { if (lrint(volume) > 0) { - snprintf_loc(temp, sz_temp, translate("gettextFromC", "%.0f%s of %s (%.0f%s during planned ascent)"), + asprintf_loc(&temp, translate("gettextFromC", "%.0f%s of %s (%.0f%s during planned ascent)"), volume, unit, gasname(&cyl->gasmix), deco_volume, unit); } else { - snprintf_loc(temp, sz_temp, translate("gettextFromC", "%.0f%s of %s"), + asprintf_loc(&temp, translate("gettextFromC", "%.0f%s of %s"), volume, unit, gasname(&cyl->gasmix)); } } /* Gas consumption: Now finally print all strings to output */ - len += snprintf(buffer + len, sz_buffer - len, "%s%s%s
", temp, warning, mingas); + put_format(&buf, "%s%s%s
", temp, warning, mingas); + free(temp); } /* For trimix OC dives, if an icd table header and icd data were printed to buffer, then add the ICD table here */ if (!icdtableheader && prefs.show_icd) { - icdlen += snprintf(icdbuffer + icdlen, sz_icdbuf - icdlen,""); // End the ICD table - len += snprintf(buffer + len, sz_buffer - len, "%s", icdbuffer); // ..and add it to the html buffer + put_string(&icdbuf, ""); // End the ICD table + put_string(&buf, icdbuf.buffer); // ..and add it to the html buffer if (icdwarning) { // If necessary, add warning - len += snprintf(buffer + len, sz_buffer - len, "%s %s", + put_format(&buf, "%s %s", translate("gettextFromC", "Warning:"), translate("gettextFromC", "Isobaric counterdiffusion conditions exceeded")); } - len += snprintf(buffer + len, sz_buffer - len, "
"); + put_string(&buf, "
"); } + free_buffer(&icdbuf); /* Print warnings for pO2 */ dp = diveplan->dp; @@ -566,40 +548,31 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d const char *depth_unit; int decimals; double depth_value = get_depth_units(dp->depth.mm, &decimals, &depth_unit); - len = strlen(buffer); if (!o2warning_exist) - len += snprintf(buffer + len, sz_buffer - len, "
"); + put_string(&buf, "
"); o2warning_exist = true; - snprintf_loc(temp, sz_temp, - translate("gettextFromC", "high pO₂ value %.2f at %d:%02u with gas %s at depth %.*f %s"), - pressures.o2, FRACTION(dp->time, 60), gasname(gasmix), decimals, depth_value, depth_unit); - len += snprintf(buffer + len, sz_buffer - len, "%s %s
", - translate("gettextFromC", "Warning:"), temp); + asprintf_loc(&temp, translate("gettextFromC", "high pO₂ value %.2f at %d:%02u with gas %s at depth %.*f %s"), + pressures.o2, FRACTION(dp->time, 60), gasname(gasmix), decimals, depth_value, depth_unit); + put_format(&buf, "%s %s
", translate("gettextFromC", "Warning:"), temp); + free(temp); } else if (pressures.o2 < 0.16) { const char *depth_unit; int decimals; double depth_value = get_depth_units(dp->depth.mm, &decimals, &depth_unit); - len = strlen(buffer); if (!o2warning_exist) - len += snprintf(buffer + len, sz_buffer - len, "
"); + put_string(&buf, "
"); o2warning_exist = true; - snprintf_loc(temp, sz_temp, - translate("gettextFromC", "low pO₂ value %.2f at %d:%02u with gas %s at depth %.*f %s"), - pressures.o2, FRACTION(dp->time, 60), gasname(gasmix), decimals, depth_value, depth_unit); - len += snprintf(buffer + len, sz_buffer - len, "%s %s
", - translate("gettextFromC", "Warning:"), temp); - + asprintf_loc(&temp, translate("gettextFromC", "low pO₂ value %.2f at %d:%02u with gas %s at depth %.*f %s"), + pressures.o2, FRACTION(dp->time, 60), gasname(gasmix), decimals, depth_value, depth_unit); + put_format(&buf, "%s %s
", translate("gettextFromC", "Warning:"), temp); + free(temp); } } dp = dp->next; } } - snprintf(buffer + len, sz_buffer - len, "
"); - dive->notes = strdup(buffer); - + put_string(&buf, "
"); finished: - free((void *)buffer); - free((void *)temp); - free((void *)icdbuffer); - + mb_cstring(&buf); + dive->notes = detach_buffer(&buf); }