diff options
| author | Russell Belfer <arrbee@arrbee.com> | 2011-11-30 11:27:15 -0800 |
|---|---|---|
| committer | Russell Belfer <arrbee@arrbee.com> | 2011-12-07 23:08:15 -0800 |
| commit | 97769280ba9938ae27f6e06cbd0d5e8a768a86b9 (patch) | |
| tree | 4fe43e99acb55f904f6b586bd7c5158610f9512f /src/indexer.c | |
| parent | a22b14d32dd8d5f06f121aa154d45bac3b10a305 (diff) | |
| download | libgit2-97769280ba9938ae27f6e06cbd0d5e8a768a86b9.tar.gz | |
Use git_buf for path storage instead of stack-based buffers
This converts virtually all of the places that allocate GIT_PATH_MAX
buffers on the stack for manipulating paths to use git_buf objects
instead. The patch is pretty careful not to touch the public API
for libgit2, so there are a few places that still use GIT_PATH_MAX.
This extends and changes some details of the git_buf implementation
to add a couple of extra functions and to make error handling easier.
This includes serious alterations to all the path.c functions, and
several of the fileops.c ones, too. Also, there are a number of new
functions that parallel existing ones except that use a git_buf
instead of a stack-based buffer (such as git_config_find_global_r
that exists alongsize git_config_find_global).
This also modifies the win32 version of p_realpath to allocate whatever
buffer size is needed to accommodate the realpath instead of hardcoding
a GIT_PATH_MAX limit, but that change needs to be tested still.
Diffstat (limited to 'src/indexer.c')
| -rw-r--r-- | src/indexer.c | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/src/indexer.c b/src/indexer.c index a69ab850c..8fdf89d9d 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -151,28 +151,35 @@ cleanup: return error; } -static void index_path(char *path, git_indexer *idx) +static int index_path(git_buf *path, git_indexer *idx) { - char *ptr; const char prefix[] = "pack-", suffix[] = ".idx"; + size_t slash = (size_t)path->size; - ptr = strrchr(path, '/') + 1; + /* search backwards for '/' */ + while (slash > 0 && path->ptr[slash - 1] != '/') + slash--; - memcpy(ptr, prefix, strlen(prefix)); - ptr += strlen(prefix); - git_oid_fmt(ptr, &idx->hash); - ptr += GIT_OID_HEXSZ; - memcpy(ptr, suffix, strlen(suffix) + 1); + if (git_buf_grow(path, slash + 1 + strlen(prefix) + + GIT_OID_HEXSZ + strlen(suffix) + 1) < GIT_SUCCESS) + return GIT_ENOMEM; + + git_buf_truncate(path, slash + 1); + git_buf_puts(path, prefix); + git_oid_fmt(path->ptr + path->size, &idx->hash); + path->size += GIT_OID_HEXSZ; + git_buf_puts(path, suffix); + + return git_buf_lasterror(path); } int git_indexer_write(git_indexer *idx) { git_mwindow *w = NULL; int error; - size_t namelen; unsigned int i, long_offsets = 0, left; struct git_pack_idx_header hdr; - char filename[GIT_PATH_MAX]; + git_buf filename = GIT_BUF_INIT; struct entry *entry; void *packfile_hash; git_oid file_hash; @@ -180,16 +187,23 @@ int git_indexer_write(git_indexer *idx) git_vector_sort(&idx->objects); - namelen = strlen(idx->pack->pack_name); - memcpy(filename, idx->pack->pack_name, namelen); - memcpy(filename + namelen - strlen("pack"), "idx", strlen("idx") + 1); + git_buf_sets(&filename, idx->pack->pack_name); + git_buf_truncate(&filename, filename.size - strlen("pack")); + git_buf_puts(&filename, "idx"); - error = git_filebuf_open(&idx->file, filename, GIT_FILEBUF_HASH_CONTENTS); + if ((error = git_buf_lasterror(&filename)) < GIT_SUCCESS) + goto cleanup; + + error = git_filebuf_open(&idx->file, filename.ptr, GIT_FILEBUF_HASH_CONTENTS); + if (error < GIT_SUCCESS) + goto cleanup; /* Write out the header */ hdr.idx_signature = htonl(PACK_IDX_SIGNATURE); hdr.idx_version = htonl(2); error = git_filebuf_write(&idx->file, &hdr, sizeof(hdr)); + if (error < GIT_SUCCESS) + goto cleanup; /* Write out the fanout table */ for (i = 0; i < 256; ++i) { @@ -270,14 +284,18 @@ int git_indexer_write(git_indexer *idx) goto cleanup; /* Figure out what the final name should be */ - index_path(filename, idx); + error = index_path(&filename, idx); + if (error < GIT_SUCCESS) + goto cleanup; + /* Commit file */ - error = git_filebuf_commit_at(&idx->file, filename, GIT_PACK_FILE_MODE); + error = git_filebuf_commit_at(&idx->file, filename.ptr, GIT_PACK_FILE_MODE); cleanup: git_mwindow_free_all(&idx->pack->mwf); if (error < GIT_SUCCESS) git_filebuf_cleanup(&idx->file); + git_buf_free(&filename); return error; } |
