]> git.ipfire.org Git - thirdparty/git.git/commit
reftable/record: handle overflows when decoding varints
authorPatrick Steinhardt <ps@pks.im>
Mon, 20 Jan 2025 16:17:21 +0000 (17:17 +0100)
committerJunio C Hamano <gitster@pobox.com>
Tue, 21 Jan 2025 22:20:28 +0000 (14:20 -0800)
commit072e3aa3a5c29ca1b68a7aaf570a0a8e7ab67127
treed4f6f9bb3fa5c682076688d2b6defd56a8fe8325
parenta204f92d1cb08f3a0450551b5e6759284bbab12a
reftable/record: handle overflows when decoding varints

The logic to decode varints isn't able to detect integer overflows: as
long as the buffer still has more data available, and as long as the
current byte has its 0x80 bit set, we'll continue to add up these values
to the result. This will eventually cause the `uint64_t` to overflow, at
which point we'll return an invalid result.

Refactor the function so that it is able to detect such overflows. The
implementation is basically copied from Git's own `decode_varint()`,
which already knows to handle overflows. The only adjustment is that we
also take into account the string view's length in order to not overrun
it. The reftable documentation explicitly notes that those two encoding
schemas are supposed to be the same:

    Varint encoding
    ^^^^^^^^^^^^^^^

    Varint encoding is identical to the ofs-delta encoding method used
    within pack files.

    Decoder works as follows:

    ....
    val = buf[ptr] & 0x7f
    while (buf[ptr] & 0x80) {
      ptr++
      val = ((val + 1) << 7) | (buf[ptr] & 0x7f)
    }
    ....

While at it, refactor `put_var_int()` in the same way by copying over
the implementation of `encode_varint()`. While `put_var_int()` doesn't
have an issue with overflows, it generates warnings with -Wsign-compare.
The implementation of `encode_varint()` doesn't, is battle-tested and at
the same time way simpler than what we currently have.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
reftable/record.c
reftable/record.h
t/unit-tests/t-reftable-record.c