diff options
author | Patrick Steinhardt <ps@pks.im> | 2017-05-19 14:06:15 +0200 |
---|---|---|
committer | Patrick Steinhardt <ps@pks.im> | 2017-06-06 09:38:44 +0200 |
commit | 064a60e96fc0ac134c9cba7b99bd31e1afbef886 (patch) | |
tree | 4561fc8e306ada8d4356e1d4517748675fc1c738 | |
parent | c71dff7e8a1bde298972c10901802608bd4cbb55 (diff) | |
download | libgit2-064a60e96fc0ac134c9cba7b99bd31e1afbef886.tar.gz |
index: verify we have enough space left when writing index entries
In our code writing index entries, we carry around a `disk_size`
representing how much memory we have in total and pass this value to
`git_encode_varint` to do bounds checks. This does not make much sense,
as at the time when passing on this variable it is already out of date.
Fix this by subtracting used memory from `disk_size` as we go along.
Furthermore, assert we've actually got enough space left to do the final
path memcpy.
-rw-r--r-- | src/index.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/src/index.c b/src/index.c index 860adaf12..c29e90fb0 100644 --- a/src/index.c +++ b/src/index.c @@ -2655,15 +2655,34 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha ondisk_ext->flags_extended = htons(entry->flags_extended & GIT_IDXENTRY_EXTENDED_FLAGS); path = ondisk_ext->path; - } - else + disk_size -= offsetof(struct entry_long, path); + } else { path = ondisk->path; + disk_size -= offsetof(struct entry_short, path); + } if (last) { - path += git_encode_varint((unsigned char *) path, + varint_len = git_encode_varint((unsigned char *) path, disk_size, same_len); + assert(varint_len > 0); + path += varint_len; + disk_size -= varint_len; + + /* + * If using path compression, we are not allowed + * to have additional trailing NULs. + */ + assert(disk_size == path_len + 1); + } else { + /* + * If no path compression is used, we do have + * NULs as padding. As such, simply assert that + * we have enough space left to write the path. + */ + assert(disk_size > path_len); } - memcpy(path, path_start, path_len); + + memcpy(path, path_start, path_len + 1); return 0; } |