1
0
mirror of https://github.com/moparisthebest/curl synced 2024-08-13 17:03:50 -04:00

progress_cb: avoid buffer overflow

The progress bar output function would blindly use the terminal width
without bounds checking. When using a very wide terminal that caused a
buffer overflow and segfault.

We now limit the max bar with to 255 columns, and I simplified the code
to avoid an extra snprintf and buffer.

Bug: http://curl.haxx.se/bug/view.cgi?id=3435710
Reported by: Alexey Zakhlestin
This commit is contained in:
Daniel Stenberg 2011-11-09 22:50:36 +01:00
parent 082e8a3b03
commit 10120e6ab5

View File

@ -36,6 +36,8 @@
** callback for CURLOPT_PROGRESSFUNCTION ** callback for CURLOPT_PROGRESSFUNCTION
*/ */
#define MAX_BARLENGTH 256
int tool_progress_cb(void *clientp, int tool_progress_cb(void *clientp,
double dltotal, double dlnow, double dltotal, double dlnow,
double ultotal, double ulnow) double ultotal, double ulnow)
@ -43,8 +45,7 @@ int tool_progress_cb(void *clientp,
/* The original progress-bar source code was written for curl by Lars Aas, /* The original progress-bar source code was written for curl by Lars Aas,
and this new edition inherits some of his concepts. */ and this new edition inherits some of his concepts. */
char line[256]; char line[MAX_BARLENGTH+1];
char outline[256];
char format[40]; char format[40];
double frac; double frac;
double percent; double percent;
@ -82,12 +83,13 @@ int tool_progress_cb(void *clientp,
percent = frac * 100.0f; percent = frac * 100.0f;
barwidth = bar->width - 7; barwidth = bar->width - 7;
num = (int) (((double)barwidth) * frac); num = (int) (((double)barwidth) * frac);
if(num > MAX_BARLENGTH)
num = MAX_BARLENGTH;
for(i = 0; i < num; i++) for(i = 0; i < num; i++)
line[i] = '#'; line[i] = '#';
line[i] = '\0'; line[i] = '\0';
snprintf(format, sizeof(format), "%%-%ds %%5.1f%%%%", barwidth); snprintf(format, sizeof(format), "\r%%-%ds %%5.1f%%%%", barwidth);
snprintf(outline, sizeof(outline), format, line, percent); fprintf(bar->out, format, line, percent);
fprintf(bar->out, "\r%s", outline);
} }
fflush(bar->out); fflush(bar->out);
bar->prev = point; bar->prev = point;