]> git.ipfire.org Git - thirdparty/git.git/commitdiff
unpack_loose_header(): avoid numeric comparison of zlib status
authorJeff King <peff@peff.net>
Tue, 25 Feb 2025 06:30:56 +0000 (01:30 -0500)
committerJunio C Hamano <gitster@pobox.com>
Tue, 25 Feb 2025 18:24:55 +0000 (10:24 -0800)
When unpacking a loose header, we try to inflate the first 32 bytes.
We'd expect either Z_OK (we filled up the output buffer, but there are
more bytes in the object) or Z_STREAM_END (this is a tiny object whose
header and content fit in the buffer).

We check for that with "if (status < Z_OK)", making the assumption that
all of the errors we'd see have negative values (as Z_OK itself is "0",
and Z_STREAM_END is "1").

But there's at least one case this misses: Z_NEED_DICT is "2". This
isn't something we'd ever expect to see, but if we do see it, we should
consider it an error (since we have no dictionary to load).

Instead, the current code interprets Z_NEED_DICT as success and looks
for the object header's terminating NUL in the bytes we've read. This
will generaly be zero bytes if the dictionary is mentioned at the start
of the stream. So we'll fail to find it and complain "the header is too
long" (ULHR_LONG). But really, the problem is that the object is
malformed, and we should return ULHR_BAD.

This is a minor bug, as we consider both cases to be an error. But it
does mean we print the wrong error message. The test case added in the
previous patch triggers this code, so we can just confirm the error
message we see here.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file.c
t/t1006-cat-file.sh

index 5086633e21289ee312f01fb190cc9374acb01ca3..0bc62b53d3c25a93b2cf5ad029e12cc1f6f15614 100644 (file)
@@ -1273,7 +1273,7 @@ enum unpack_loose_header_result unpack_loose_header(git_zstream *stream,
        obj_read_unlock();
        status = git_inflate(stream, 0);
        obj_read_lock();
-       if (status < Z_OK)
+       if (status != Z_OK && status != Z_STREAM_END)
                return ULHR_BAD;
 
        /*
index 04099f7b4a3a0402f3f430229f5585266fca00e4..609dabd5cf3e182c96a213117789e6b9ff7f4b29 100755 (executable)
@@ -865,6 +865,8 @@ test_expect_success 'object reading handles zlib dictionary' - <<\EOT
        printf '\170\273\017\112\003\143' >$objpath &&
 
        test_must_fail git cat-file blob $blob 2>err &&
+       test_grep ! 'too long' err &&
+       test_grep 'error: unable to unpack' err &&
        test_grep 'error: inflate: needs dictionary' err
 EOT