summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRussell Belfer <arrbee@arrbee.com>2011-11-17 15:10:27 -0800
committerVicent Marti <tanoku@gmail.com>2011-11-22 01:53:56 +0100
commitb762e576c6d0118664320f50be2e5810dbed4c15 (patch)
tree2c244a57ca5167386856c573336093744464daa6 /src
parent1d09a1c88ddde32bf9b6b5ab6a9feab2ecdaa6ff (diff)
downloadlibgit2-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.c2
-rw-r--r--src/fetch.c2
-rw-r--r--src/filebuf.c22
-rw-r--r--src/filebuf.h15
-rw-r--r--src/index.c2
-rw-r--r--src/odb_loose.c2
-rw-r--r--src/reflog.c2
-rw-r--r--src/refs.c4
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];