]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
tool_cb_prg: make the carriage return fit for wide progress bars
authorDaniel Stenberg <daniel@haxx.se>
Mon, 27 Nov 2023 14:31:00 +0000 (15:31 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 27 Nov 2023 18:16:05 +0000 (19:16 +0100)
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

src/tool_cb_prg.c

index 636097a4f4070d3b0831483365b877f97a297eed..ef47b42da01d611b35832bee00d236360ad1a121 100644 (file)
@@ -38,6 +38,8 @@
 
 #include "memdebug.h" /* keep this as LAST include */
 
+#define MAX_BARLENGTH 256
+
 #ifdef HAVE_TERMIOS_H
 #  include <termios.h>
 #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