Page MenuHome GnuPG

Kleopatra: Progress indication for large archives wrong
Closed, ResolvedPublic

Description

When decrypting a large archive > 5gb kleopatra shows the progress to be at 100% very early while clearly in the background there still is a gpg process working on the decryption.

Realted is T5478

Event Timeline

aheinecke created this task.

This can be easily reproduced with run-encrypt from gpgme/tests:

$ fallocate -l 1G largefile1G
$ fallocate -l 2G largefile2G
$ fallocate -l 3G largefile3G
$ fallocate -l 4G largefile4G
$ fallocate -l 5G largefile5G
$ ./run-encrypt --progress --loopback largefile1G >/dev/null
progress for '-&11' 0% (0 of 1048576)
progress for '-&11' 0% (64 of 1048576)
progress for '-&11' 6% (66816 of 1048576)
progress for '-&11' 16% (172928 of 1048576)
^C
$ ./run-encrypt --progress --loopback largefile2G >/dev/null
progress for '-&11' 0
progress for '-&11' 65536
progress for '-&11' 56896
progress for '-&11' 155776
progress for '-&11' 249344
^C
$ ./run-encrypt --progress --loopback largefile3G >/dev/null
progress for '-&11' 0
progress for '-&11' 65536
progress for '-&11' 105216
progress for '-&11' 212480
^C
$ ./run-encrypt --progress --loopback largefile4G >/dev/null
progress for '-&11' 0
progress for '-&11' 57856
progress for '-&11' 168768
^C
$ ./run-encrypt --progress --loopback largefile5G >/dev/null
progress for '-&11' 0% (0 of 1048576)
progress for '-&11' 0% (64 of 1048576)
progress for '-&11' 11% (115840 of 1048576)
^C

The progress callback of run-encrypt looks like this:

static void
progress_cb (void *opaque, const char *what, int type, int current, int total)
{
  (void)opaque;
  (void)type;

  if (total)
    fprintf (stderr, "progress for '%s' %u%% (%d of %d)\n",
             nonnull (what),
             (unsigned)(((double)current / total) * 100), current, total);
  else
    fprintf (stderr, "progress for '%s' %d\n", nonnull(what), current);
  fflush (stderr);
}

Conclusion:

  • For the 1G file progress works (current and total seem to be in KiB).
  • For the 2G, 3G, and 4G file total appears to be 0.
  • For the 5G file total is wrong. It seems to be the 32-bit truncated actual size in KiB.

By the way, I see that gpg appears to output an optional unit. This unit does not seem to be passed to the callbacks which makes the values current and total hard to interpret.

Ah, of course, the solution for T2368 does not work for archives. So Kleo would need to stat all files first to get an idea of the size of the tar archive to set a size hint.

I have added some debug output to _gpgme_progress_status_handler. For the 5G file gpg seems to output

-&11 ? 0 1048576 KiB

for PROGRESS. So, the value of total is already wrong in gpg.

Hmm, nope. gpg outputs

[GNUPG:] PROGRESS largefile5G ? 0 5120 MiB

if I run

$ gpg --symmetric --enable-progress-filter --status-fd 1 --output /dev/null largefile5G

Maybe gpgme calls gpg with a wrong file size?

Okay, the problem with run-encrypt (and maybe also Kleopatra if it also uses gpgme_data_... and sets a size hint) is that gpgme_data_seek casts the result of seek(..., 0, SEEK_END) which is of type gpgme_off_t to int to accommodate as tracing macro/function:

return TRACE_SYSRES ((int)offset);

Changing this line to a simple

return offset;

fixes the progress reporting of run-encrypt.

ikloecker moved this task from Restricted Project Column to Restricted Project Column on the Restricted Project board.

The fix in gpgme fixes the progress when encrypting/decrypting large files with Kleopatra. At least, on Linux.

ikloecker moved this task from Restricted Project Column to Restricted Project Column on the Restricted Project board.Aug 3 2021, 2:55 PM