summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2017-05-22 12:53:44 +0200
committerPatrick Steinhardt <ps@pks.im>2017-06-06 09:33:53 +0200
commit8a5e7aaecf7ce48dfab805debfc92458ab1112c5 (patch)
tree8ee94a40b5dd461ff31ae001697cd6b3df545570
parentdd0aa811dd329f5040c70f7aac514b3757eb2453 (diff)
downloadlibgit2-8a5e7aaecf7ce48dfab805debfc92458ab1112c5.tar.gz
varint: fix computation for remaining buffer space
When encoding varints to a buffer, we want to remain sure that the required buffer space does not exceed what is actually available. Our current check does not do the right thing, though, in that it does not honor that our `pos` variable counts the position down instead of up. As such, we will require too much memory for small varints and not enough memory for big varints. Fix the issue by correctly calculating the required size as `(sizeof(varint) - pos)`. Add a test which failed before.
-rw-r--r--src/varint.c2
-rw-r--r--tests/core/encoding.c3
2 files changed, 4 insertions, 1 deletions
diff --git a/src/varint.c b/src/varint.c
index 2f868607c..beac8c709 100644
--- a/src/varint.c
+++ b/src/varint.c
@@ -36,7 +36,7 @@ int git_encode_varint(unsigned char *buf, size_t bufsize, uintmax_t value)
while (value >>= 7)
varint[--pos] = 128 | (--value & 127);
if (buf) {
- if (bufsize < pos)
+ if (bufsize < (sizeof(varint) - pos))
return -1;
memcpy(buf, varint + pos, sizeof(varint) - pos);
}
diff --git a/tests/core/encoding.c b/tests/core/encoding.c
index 7d91720f4..a677afe2e 100644
--- a/tests/core/encoding.c
+++ b/tests/core/encoding.c
@@ -29,6 +29,9 @@ void test_core_encoding__encode(void)
cl_assert(git_encode_varint(buf, 100, 65) == 1);
cl_assert(buf[0] == 'A');
+ cl_assert(git_encode_varint(buf, 1, 1) == 1);
+ cl_assert(!memcmp(buf, "\x01", 1));
+
cl_assert(git_encode_varint(buf, 100, 267869656) == 4);
cl_assert(!memcmp(buf, "\xfe\xdc\xbaX", 4));