From 6c957c3d880c069bb843cc58fdcebb9fc344727e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 27 May 2016 11:28:22 +0200 Subject: [PATCH] gpg: Keep current and total of PROGESS status lines small enough. * g10/progress.c (progress_filter): Factor status wrote out to... (write_status_progress): New. Scale values down. -- GnuPG-bug-id: 2368 Signed-off-by: Werner Koch --- g10/progress.c | 60 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/g10/progress.c b/g10/progress.c index 21810a45b..a1027b8d3 100644 --- a/g10/progress.c +++ b/g10/progress.c @@ -71,6 +71,49 @@ release_progress_context (progress_filter_context_t *pfx) } +static void +write_status_progress (const char *what, + unsigned long current, unsigned long total) +{ + char buffer[50]; + + /* Although we use an unsigned long for the values, 32 bit + * applications using GPGME will use an "int" and thus are limited + * in the total size which can be represented. On Windows, where + * sizeof(int)==sizeof(long), this is even worse and will lead to an + * integer overflow for all files larger than 2 GiB. Although, the + * allowed value range of TOTAL and CURRENT is nowhere specified, we + * better protect applications from the need to handle negative + * values. The common usage pattern of the progress information is + * to display how many percent of the operation has been done and + * thus scaling CURRENT and TOTAL down before they get to large, + * should not have a noticeable effect except for rounding + * imprecision. */ + if (total) + { + if (current > total) + current = total; + + while (total > 1024*1024) + { + total /= 1024; + current /= 1024; + } + } + else + { + while (current > 1024*1024) + { + current /= 1024; + } + } + + snprintf (buffer, sizeof buffer, "%.20s ? %lu %lu", + what? what : "?", current, total); + write_status_text (STATUS_PROGRESS, buffer); +} + + /**************** * The filter is used to report progress to the user. */ @@ -83,17 +126,11 @@ progress_filter (void *opaque, int control, if (control == IOBUFCTRL_INIT) { - char buffer[50]; - pfx->last = 0; pfx->offset = 0; pfx->last_time = make_timestamp (); - sprintf (buffer, "%.20s ? %lu %lu", - pfx->what? pfx->what : "?", - pfx->offset, - pfx->total); - write_status_text (STATUS_PROGRESS, buffer); + write_status_progress (pfx->what, pfx->offset, pfx->total); } else if (control == IOBUFCTRL_UNDERFLOW) { @@ -113,14 +150,7 @@ progress_filter (void *opaque, int control, if ((len == -1 && pfx->offset != pfx->last) || timestamp - pfx->last_time > 0) { - char buffer[50]; - - sprintf (buffer, "%.20s ? %lu %lu", - pfx->what? pfx->what : "?", - pfx->offset, - pfx->total); - write_status_text (STATUS_PROGRESS, buffer); - + write_status_progress (pfx->what, pfx->offset, pfx->total); pfx->last = pfx->offset; pfx->last_time = timestamp; }