mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-09 13:04:42 +00:00
buffer: don't allow growing borrowed buffers
When we don't own a buffer (asize=0) we currently allow the usage of grow to copy the memory into a buffer we do own. This muddles the meaning of grow, and lets us be a bit cavalier with ownership semantics. Don't allow this any more. Usage of grow should be restricted to buffers which we know own their own memory. If unsure, we must not attempt to modify it.
This commit is contained in:
parent
aacfd03dba
commit
caab22c0d4
12
src/buffer.c
12
src/buffer.c
@ -33,7 +33,7 @@ void git_buf_init(git_buf *buf, size_t initial_size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int git_buf_try_grow(
|
int git_buf_try_grow(
|
||||||
git_buf *buf, size_t target_size, bool mark_oom, bool preserve_external)
|
git_buf *buf, size_t target_size, bool mark_oom)
|
||||||
{
|
{
|
||||||
char *new_ptr;
|
char *new_ptr;
|
||||||
size_t new_size;
|
size_t new_size;
|
||||||
@ -41,6 +41,9 @@ int git_buf_try_grow(
|
|||||||
if (buf->ptr == git_buf__oom)
|
if (buf->ptr == git_buf__oom)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (buf->asize == 0 && buf->size != 0)
|
||||||
|
return GIT_EINVALIDSPEC;
|
||||||
|
|
||||||
if (!target_size)
|
if (!target_size)
|
||||||
target_size = buf->size;
|
target_size = buf->size;
|
||||||
|
|
||||||
@ -82,9 +85,6 @@ int git_buf_try_grow(
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preserve_external && !buf->asize && buf->ptr != NULL && buf->size > 0)
|
|
||||||
memcpy(new_ptr, buf->ptr, min(buf->size, new_size));
|
|
||||||
|
|
||||||
buf->asize = new_size;
|
buf->asize = new_size;
|
||||||
buf->ptr = new_ptr;
|
buf->ptr = new_ptr;
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ int git_buf_try_grow(
|
|||||||
|
|
||||||
int git_buf_grow(git_buf *buffer, size_t target_size)
|
int git_buf_grow(git_buf *buffer, size_t target_size)
|
||||||
{
|
{
|
||||||
return git_buf_try_grow(buffer, target_size, true, true);
|
return git_buf_try_grow(buffer, target_size, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_buf_grow_by(git_buf *buffer, size_t additional_size)
|
int git_buf_grow_by(git_buf *buffer, size_t additional_size)
|
||||||
@ -110,7 +110,7 @@ int git_buf_grow_by(git_buf *buffer, size_t additional_size)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return git_buf_try_grow(buffer, newsize, true, true);
|
return git_buf_try_grow(buffer, newsize, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_buf_free(git_buf *buf)
|
void git_buf_free(git_buf *buf)
|
||||||
|
@ -59,7 +59,7 @@ extern int git_buf_grow_by(git_buf *buffer, size_t additional_size);
|
|||||||
* into the newly allocated buffer.
|
* into the newly allocated buffer.
|
||||||
*/
|
*/
|
||||||
extern int git_buf_try_grow(
|
extern int git_buf_try_grow(
|
||||||
git_buf *buf, size_t target_size, bool mark_oom, bool preserve_external);
|
git_buf *buf, size_t target_size, bool mark_oom);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sanitizes git_buf structures provided from user input. Users of the
|
* Sanitizes git_buf structures provided from user input. Users of the
|
||||||
|
@ -640,7 +640,7 @@ static bool _check_dir_contents(
|
|||||||
/* leave base valid even if we could not make space for subdir */
|
/* leave base valid even if we could not make space for subdir */
|
||||||
if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, dir_size, sub_size) ||
|
if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, dir_size, sub_size) ||
|
||||||
GIT_ADD_SIZET_OVERFLOW(&alloc_size, alloc_size, 2) ||
|
GIT_ADD_SIZET_OVERFLOW(&alloc_size, alloc_size, 2) ||
|
||||||
git_buf_try_grow(dir, alloc_size, false, false) < 0)
|
git_buf_try_grow(dir, alloc_size, false) < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* save excursion */
|
/* save excursion */
|
||||||
@ -847,7 +847,7 @@ int git_path_make_relative(git_buf *path, const char *parent)
|
|||||||
|
|
||||||
/* save the offset as we might realllocate the pointer */
|
/* save the offset as we might realllocate the pointer */
|
||||||
offset = p - path->ptr;
|
offset = p - path->ptr;
|
||||||
if (git_buf_try_grow(path, alloclen, 1, 0) < 0)
|
if (git_buf_try_grow(path, alloclen, 1) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
p = path->ptr + offset;
|
p = path->ptr + offset;
|
||||||
|
|
||||||
|
@ -1153,3 +1153,16 @@ void test_core_buffer__lf_and_crlf_conversions(void)
|
|||||||
git_buf_free(&src);
|
git_buf_free(&src);
|
||||||
git_buf_free(&tgt);
|
git_buf_free(&tgt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_core_buffer__dont_grow_borrowed(void)
|
||||||
|
{
|
||||||
|
const char *somestring = "blah blah";
|
||||||
|
git_buf buf = GIT_BUF_INIT;
|
||||||
|
|
||||||
|
git_buf_attach_notowned(&buf, somestring, strlen(somestring) + 1);
|
||||||
|
cl_assert_equal_p(somestring, buf.ptr);
|
||||||
|
cl_assert_equal_i(0, buf.asize);
|
||||||
|
cl_assert_equal_i(strlen(somestring) + 1, buf.size);
|
||||||
|
|
||||||
|
cl_git_fail_with(GIT_EINVALIDSPEC, git_buf_grow(&buf, 1024));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user