diff options
author | Russell Belfer <arrbee@arrbee.com> | 2011-11-17 15:10:27 -0800 |
---|---|---|
committer | Vicent Marti <tanoku@gmail.com> | 2011-11-22 01:53:56 +0100 |
commit | b762e576c6d0118664320f50be2e5810dbed4c15 (patch) | |
tree | 2c244a57ca5167386856c573336093744464daa6 /src | |
parent | 1d09a1c88ddde32bf9b6b5ab6a9feab2ecdaa6ff (diff) | |
download | libgit2-b762e576c6d0118664320f50be2e5810dbed4c15.tar.gz |
filebuf: add GIT_FILEBUF_INIT and protect multiple opens and cleanups
Update all stack allocations of git_filebuf to use GIT_FILEBUF_INIT
and make git_filebuf_open and git_filebuf_cleanup safe to be called
multiple times on the same buffer.
Signed-off-by: Vicent Marti <tanoku@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/config_file.c | 2 | ||||
-rw-r--r-- | src/fetch.c | 2 | ||||
-rw-r--r-- | src/filebuf.c | 22 | ||||
-rw-r--r-- | src/filebuf.h | 15 | ||||
-rw-r--r-- | src/index.c | 2 | ||||
-rw-r--r-- | src/odb_loose.c | 2 | ||||
-rw-r--r-- | src/reflog.c | 2 | ||||
-rw-r--r-- | src/refs.c | 4 |
8 files changed, 39 insertions, 12 deletions
diff --git a/src/config_file.c b/src/config_file.c index aec29d4e2..87a430759 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -877,7 +877,7 @@ static int config_write(diskfile_backend *cfg, cvar_t *var) int section_matches = 0, last_section_matched = 0; char *current_section = NULL; char *var_name, *var_value, *data_start; - git_filebuf file; + git_filebuf file = GIT_FILEBUF_INIT; const char *pre_end = NULL, *post_start = NULL; /* We need to read in our own config file */ diff --git a/src/fetch.c b/src/fetch.c index af7dbaffd..a42732925 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -138,7 +138,7 @@ int git_fetch_download_pack(char **out, git_remote *remote) int git_fetch__download_pack(char **out, const char *buffered, size_t buffered_size, GIT_SOCKET fd, git_repository *repo) { - git_filebuf file; + git_filebuf file = GIT_FILEBUF_INIT; int error; char buff[1024], path[GIT_PATH_MAX]; static const char suff[] = "/objects/pack/pack-received"; diff --git a/src/filebuf.c b/src/filebuf.c index 199418032..6600bfa4b 100644 --- a/src/filebuf.c +++ b/src/filebuf.c @@ -66,13 +66,22 @@ void git_filebuf_cleanup(git_filebuf *file) if (file->digest) git_hash_free_ctx(file->digest); - git__free(file->buffer); - git__free(file->z_buf); + if (file->buffer) + git__free(file->buffer); - deflateEnd(&file->zs); + /* use the presence of z_buf to decide if we need to deflateEnd */ + if (file->z_buf) { + git__free(file->z_buf); + deflateEnd(&file->zs); + } - git__free(file->path_original); - git__free(file->path_lock); + if (file->path_original) + git__free(file->path_original); + if (file->path_lock) + git__free(file->path_lock); + + memset(file, 0x0, sizeof(git_filebuf)); + file->fd = -1; } GIT_INLINE(int) flush_buffer(git_filebuf *file) @@ -137,6 +146,9 @@ int git_filebuf_open(git_filebuf *file, const char *path, int flags) assert(file && path); + if (file->buffer) + return git__throw(GIT_EINVALIDARGS, "Tried to reopen an open filebuf"); + memset(file, 0x0, sizeof(git_filebuf)); file->buf_size = WRITE_BUFFER_SIZE; diff --git a/src/filebuf.h b/src/filebuf.h index d08505e8d..6c283bc5c 100644 --- a/src/filebuf.h +++ b/src/filebuf.h @@ -44,6 +44,21 @@ struct git_filebuf { typedef struct git_filebuf git_filebuf; +#define GIT_FILEBUF_INIT {0} + +/* The git_filebuf object lifecycle is: + * - Allocate git_filebuf, preferably using GIT_FILEBUF_INIT. + * - Call git_filebuf_open() to initialize the filebuf for use. + * - Make as many calls to git_filebuf_write(), git_filebuf_printf(), + * git_filebuf_reserve() as you like. + * - While you are writing, you may call git_filebuf_hash() to get + * the hash of all you have written so far. + * - To close the git_filebuf, you may call git_filebuf_commit() or + * git_filebuf_commit_at() to save the file, or + * git_filebuf_cleanup() to abandon the file. All of these will + * clear the git_filebuf object. + */ + int git_filebuf_write(git_filebuf *lock, const void *buff, size_t len); int git_filebuf_reserve(git_filebuf *file, void **buff, size_t len); int git_filebuf_printf(git_filebuf *file, const char *format, ...) GIT_FORMAT_PRINTF(2, 3); diff --git a/src/index.c b/src/index.c index 1a9745a2c..aad117164 100644 --- a/src/index.c +++ b/src/index.c @@ -248,7 +248,7 @@ int git_index_read(git_index *index) int git_index_write(git_index *index) { - git_filebuf file; + git_filebuf file = GIT_FILEBUF_INIT; struct stat indexst; int error; diff --git a/src/odb_loose.c b/src/odb_loose.c index 57a0b0a8e..f1789e071 100644 --- a/src/odb_loose.c +++ b/src/odb_loose.c @@ -769,7 +769,7 @@ static int loose_backend__write(git_oid *oid, git_odb_backend *_backend, const v { int error, header_len; char final_path[GIT_PATH_MAX], header[64]; - git_filebuf fbuf; + git_filebuf fbuf = GIT_FILEBUF_INIT; loose_backend *backend; backend = (loose_backend *)_backend; diff --git a/src/reflog.c b/src/reflog.c index e0fa7a060..c136987b1 100644 --- a/src/reflog.c +++ b/src/reflog.c @@ -41,7 +41,7 @@ static int reflog_write(const char *log_path, const char *oid_old, { int error; git_buf log = GIT_BUF_INIT; - git_filebuf fbuf; + git_filebuf fbuf = GIT_FILEBUF_INIT; assert(log_path && oid_old && oid_new && committer); diff --git a/src/refs.c b/src/refs.c index 569efbf78..5a297a516 100644 --- a/src/refs.c +++ b/src/refs.c @@ -285,7 +285,7 @@ cleanup: static int loose_write(git_reference *ref) { - git_filebuf file; + git_filebuf file = GIT_FILEBUF_INIT; char ref_path[GIT_PATH_MAX]; int error; struct stat st; @@ -744,7 +744,7 @@ static int packed_sort(const void *a, const void *b) */ static int packed_write(git_repository *repo) { - git_filebuf pack_file; + git_filebuf pack_file = GIT_FILEBUF_INIT; int error; unsigned int i; char pack_file_path[GIT_PATH_MAX]; |