From: Daniel Stenberg Date: Mon, 27 Nov 2023 14:31:00 +0000 (+0100) Subject: tool_cb_prg: make the carriage return fit for wide progress bars X-Git-Tag: curl-8_5_0~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e6bf2001c79f242b9a4ea61fbbdbc99a3ebd1d82;p=thirdparty%2Fcurl.git tool_cb_prg: make the carriage return fit for wide progress bars When the progress bar was made max width (256 columns), the fly() function attempted to generate its output buffer too long so that the trailing carriage return would not fit and then the output would show wrongly. The fly function is called when the expected total transfer is unknown, which could be one or more progress calls before the actual progress meter get shown when the expected transfer size is provided. This new take also replaces the msnprintf() call with a much simpler memset() for speed. Reported-by: Tim Hill Fixes #12407 Closes #12415 --- diff --git a/src/tool_cb_prg.c b/src/tool_cb_prg.c index 636097a4f4..ef47b42da0 100644 --- a/src/tool_cb_prg.c +++ b/src/tool_cb_prg.c @@ -38,6 +38,8 @@ #include "memdebug.h" /* keep this as LAST include */ +#define MAX_BARLENGTH 256 + #ifdef HAVE_TERMIOS_H # include #elif defined(HAVE_TERMIO_H) @@ -78,11 +80,16 @@ static const unsigned int sinus[] = { static void fly(struct ProgressData *bar, bool moved) { - char buf[256]; + char buf[MAX_BARLENGTH + 2]; int pos; int check = bar->width - 2; - msnprintf(buf, sizeof(buf), "%*s\r", bar->width-1, " "); + /* bar->width is range checked when assigned */ + DEBUGASSERT(bar->width <= MAX_BARLENGTH); + memset(buf, ' ', bar->width); + buf[bar->width] = '\r'; + buf[bar->width + 1] = '\0'; + memcpy(&buf[bar->bar], "-=O=-", 5); pos = sinus[bar->tick%200] / (1000000 / check); @@ -114,8 +121,6 @@ static void fly(struct ProgressData *bar, bool moved) ** callback for CURLOPT_XFERINFOFUNCTION */ -#define MAX_BARLENGTH 256 - #if (SIZEOF_CURL_OFF_T < 8) #error "too small curl_off_t" #else