all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Amritpal Singh <icy.amrit@gmail.com>
To: 63832@debbugs.gnu.org
Subject: bug#63832: fix failed inflation of .el.gz archives due to passing empty buffer to inflate()
Date: Fri, 2 Jun 2023 12:21:07 +0530	[thread overview]
Message-ID: <CAAtEfCFd+EFE-+vjybiGnTPuNaSdK5BuwoUC4Qo8sK6qW3LAhQ@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 3248 bytes --]

Compile emacs with the system's gzip program set to `pigz`.
Run emacs and then `M-x eww RET`

Expected behavior:
Enter URL prompt in mini-buffer

Actual behavior:
hashing failed '/usr/share/emacs/30.0.50/lisp/gnus/gnus.el.gz'

Report:
The bug has been reproduced on emacs version 29.0.91 and HEAD which
seems to be at 30.0.50.
Later, a copy of the aforementioned file was saved somewhere else and
the program was uninstalled. Then emacs was recompiled with system's
gzip program set to GNU gzip and the initial steps were repeated and
the expected behavior was the result.
This lead to believing either that there's a bug with how zlib's
`inflate()` handles archives or emacs code was having an issue with
archives files.

The hashes for gz archives generated with different programs were as follows
> md5sum gnus-gzip.el.gz
edb3d0ffba7f19ff1d4ec3f889609e8a  gnus-gzip.el.gz
> md5sum gnus.el.gz
985deaaec6a5845ac8d6bd9648957b50  gnus.el.gz

And when uncompressing these archives, the resulting file was the same
and the hash for the files was the same (omitted for brevity).

Now after logging some code in $EMACS_REPO/src/decompress.c, it was
learned that in the pigz specific case, `inflate()` was returning
Z_BUF_ERROR(-5) which is an indicator for zstream's either `avail_in`
or `avail_out` fields are 0.

Observing the code in `$EMACS_REPO/src/decompress.c`
L154:
    } while (!stream.avail_out);
only checks stream.avail_out and not stream.avail_in which also might
have been set to 0. A special case here can be constructed where
`avail_in` is 0, and the code keeps looping even though our input
buffer is empty and thus causing a Z_BUF_ERROR. Placing a simple check
for it fixes the bug in pigz's gz archives case and does not cause any
issue with gzip archives.

A patch with a simple fix is attached below

============================

From ffa8e140ed8b093c60f1238bf76935e815e82a21 Mon Sep 17 00:00:00 2001
From: icebarf <sysgrammer@protonmail.com>
Date: Fri, 2 Jun 2023 10:51:21 +0530
Subject: [PATCH] check stream.avail_in as well when looping to inflate gz
 archive

---
 src/decompress.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/decompress.c b/src/decompress.c
index 6ef17db..162f616 100644
--- a/src/decompress.c
+++ b/src/decompress.c
@@ -151,7 +151,7 @@ md5_gz_stream (FILE *source, void *resblock)
     return -1;

       accumulate_and_process_md5 (out, MD5_BLOCKSIZE - stream.avail_out, &ctx);
-    } while (!stream.avail_out);
+    } while (stream.avail_in && !stream.avail_out);

   } while (res != Z_STREAM_END);

-- 
2.40.1

==========

In GNU Emacs 29.0.91 (build 1, x86_64-pc-linux-gnu, GTK+ Version
 3.24.37, cairo version 1.16.0) of 2023-06-02 built on box
System Description: KISS Linux

Configured using:
 'configure --prefix=/usr --enable-link-time-optimization --with-cairo
 --with-gnutls --with-imagemagick --with-modules
 --with-native-compilation --with-pgtk --with-jpeg --with-tiff
 --with-png --with-rsvg --with-webp --without-dbus --without-lcms2
 --without-libsystemd --without-gif --without-gconf --without-gsettings
 --without-m17n-flt --without-selinux --without-x --without-xft
 --without-xaw3d --without-xim --without-xdbe 'CFLAGS=-O2 -pipe
 -march=native -mtune=native''

[-- Attachment #2: 0001-check-stream.avail_in-as-well-when-looping-to-inflat.patch --]
[-- Type: text/x-diff, Size: 734 bytes --]

From ffa8e140ed8b093c60f1238bf76935e815e82a21 Mon Sep 17 00:00:00 2001
From: icebarf <sysgrammer@protonmail.com>
Date: Fri, 2 Jun 2023 10:51:21 +0530
Subject: [PATCH] check stream.avail_in as well when looping to inflate gz
 archive

---
 src/decompress.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/decompress.c b/src/decompress.c
index 6ef17db..162f616 100644
--- a/src/decompress.c
+++ b/src/decompress.c
@@ -151,7 +151,7 @@ md5_gz_stream (FILE *source, void *resblock)
 	return -1;
 
       accumulate_and_process_md5 (out, MD5_BLOCKSIZE - stream.avail_out, &ctx);
-    } while (!stream.avail_out);
+    } while (stream.avail_in && !stream.avail_out);
 
   } while (res != Z_STREAM_END);
 
-- 
2.40.1


             reply	other threads:[~2023-06-02  6:51 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-02  6:51 Amritpal Singh [this message]
2023-06-02 12:04 ` bug#63832: fix failed inflation of .el.gz archives due to passing empty buffer to inflate() Eli Zaretskii
2023-06-08  9:43 ` Eli Zaretskii
2023-08-01  5:41 ` bug#63832: fix failed inflation of .el.gz archives due to passing Ulrich Mueller
2023-08-01 11:11   ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAAtEfCFd+EFE-+vjybiGnTPuNaSdK5BuwoUC4Qo8sK6qW3LAhQ@mail.gmail.com \
    --to=icy.amrit@gmail.com \
    --cc=63832@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.