summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2014-09-29 10:39:40 -0400
committerEdward Thomson <ethomson@edwardthomson.com>2014-09-29 10:39:40 -0400
commit89602a1a23a0c2db315cbde4faff3bab2d02a51c (patch)
treee65fd729ae078e115d45f814fdb95d98fdc303a5
parentffe34a7cdc413d5ee92eea9de0e98d0cf8f91e3e (diff)
parent0478b7f4725405bf43dee341d235ef5b5fc44046 (diff)
downloadlibgit2-89602a1a23a0c2db315cbde4faff3bab2d02a51c.tar.gz
Merge pull request #2584 from jacquesg/pool-alignment
Pool/Index data is not aligned
-rw-r--r--src/cc-compat.h8
-rw-r--r--src/diff_patch.c1
-rw-r--r--src/index.c53
-rw-r--r--src/pack.c2
-rw-r--r--src/pool.c2
-rw-r--r--tests/merge/merge_helpers.c2
-rw-r--r--tests/odb/foreach.c2
-rw-r--r--tests/pack/packbuilder.c2
8 files changed, 43 insertions, 29 deletions
diff --git a/src/cc-compat.h b/src/cc-compat.h
index e73cb6de8..0b66d8ba1 100644
--- a/src/cc-compat.h
+++ b/src/cc-compat.h
@@ -35,6 +35,14 @@
# define GIT_TYPEOF(x)
#endif
+#if defined(__GNUC__)
+# define GIT_ALIGN(x,size) x __attribute__ ((aligned(size)))
+#elif defined(_MSC_VER)
+# define GIT_ALIGN(x,size) __declspec(align(size)) x
+#else
+# define GIT_ALIGN(x,size) x
+#endif
+
#define GIT_UNUSED(x) ((void)(x))
/* Define the printf format specifer to use for size_t output */
diff --git a/src/diff_patch.c b/src/diff_patch.c
index 38d5f4257..4e0672aa1 100644
--- a/src/diff_patch.c
+++ b/src/diff_patch.c
@@ -274,6 +274,7 @@ int git_diff_foreach(
return error;
memset(&xo, 0, sizeof(xo));
+ memset(&patch, 0, sizeof(patch));
diff_output_init(
&xo.output, &diff->opts, file_cb, hunk_cb, data_cb, payload);
git_xdiff_init(&xo, &diff->opts);
diff --git a/src/index.c b/src/index.c
index b63a0bec6..8b757f269 100644
--- a/src/index.c
+++ b/src/index.c
@@ -1767,35 +1767,42 @@ static size_t read_entry(
git_index_entry **out, const void *buffer, size_t buffer_size)
{
size_t path_length, entry_size;
- uint16_t flags_raw;
const char *path_ptr;
- const struct entry_short *source = buffer;
+ struct entry_short source;
git_index_entry entry = {{0}};
if (INDEX_FOOTER_SIZE + minimal_entry_size > buffer_size)
return 0;
- entry.ctime.seconds = (git_time_t)ntohl(source->ctime.seconds);
- entry.ctime.nanoseconds = ntohl(source->ctime.nanoseconds);
- entry.mtime.seconds = (git_time_t)ntohl(source->mtime.seconds);
- entry.mtime.nanoseconds = ntohl(source->mtime.nanoseconds);
- entry.dev = ntohl(source->dev);
- entry.ino = ntohl(source->ino);
- entry.mode = ntohl(source->mode);
- entry.uid = ntohl(source->uid);
- entry.gid = ntohl(source->gid);
- entry.file_size = ntohl(source->file_size);
- git_oid_cpy(&entry.id, &source->oid);
- entry.flags = ntohs(source->flags);
+ /* buffer is not guaranteed to be aligned */
+ memcpy(&source, buffer, sizeof(struct entry_short));
+
+ entry.ctime.seconds = (git_time_t)ntohl(source.ctime.seconds);
+ entry.ctime.nanoseconds = ntohl(source.ctime.nanoseconds);
+ entry.mtime.seconds = (git_time_t)ntohl(source.mtime.seconds);
+ entry.mtime.nanoseconds = ntohl(source.mtime.nanoseconds);
+ entry.dev = ntohl(source.dev);
+ entry.ino = ntohl(source.ino);
+ entry.mode = ntohl(source.mode);
+ entry.uid = ntohl(source.uid);
+ entry.gid = ntohl(source.gid);
+ entry.file_size = ntohl(source.file_size);
+ git_oid_cpy(&entry.id, &source.oid);
+ entry.flags = ntohs(source.flags);
if (entry.flags & GIT_IDXENTRY_EXTENDED) {
- const struct entry_long *source_l = (const struct entry_long *)source;
- path_ptr = source_l->path;
+ uint16_t flags_raw;
+ size_t flags_offset;
- flags_raw = ntohs(source_l->flags_extended);
- memcpy(&entry.flags_extended, &flags_raw, 2);
+ flags_offset = offsetof(struct entry_long, flags_extended);
+ memcpy(&flags_raw, (const char *) buffer + flags_offset,
+ sizeof(flags_raw));
+ flags_raw = ntohs(flags_raw);
+
+ memcpy(&entry.flags_extended, &flags_raw, sizeof(flags_raw));
+ path_ptr = (const char *) buffer + offsetof(struct entry_long, path);
} else
- path_ptr = source->path;
+ path_ptr = (const char *) buffer + offsetof(struct entry_short, path);
path_length = entry.flags & GIT_IDXENTRY_NAMEMASK;
@@ -1846,14 +1853,12 @@ static int read_header(struct index_header *dest, const void *buffer)
static size_t read_extension(git_index *index, const char *buffer, size_t buffer_size)
{
- const struct index_extension *source;
struct index_extension dest;
size_t total_size;
- source = (const struct index_extension *)(buffer);
-
- memcpy(dest.signature, source->signature, 4);
- dest.extension_size = ntohl(source->extension_size);
+ /* buffer is not guaranteed to be aligned */
+ memcpy(&dest, buffer, sizeof(struct index_extension));
+ dest.extension_size = ntohl(dest.extension_size);
total_size = dest.extension_size + sizeof(struct index_extension);
diff --git a/src/pack.c b/src/pack.c
index 7c1cfe03e..516e0f3ca 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -620,7 +620,7 @@ int git_packfile_unpack(
struct pack_chain_elem *elem = NULL, *stack;
git_pack_cache_entry *cached = NULL;
struct pack_chain_elem small_stack[SMALL_STACK_SIZE];
- size_t stack_size, elem_pos;
+ size_t stack_size = 0, elem_pos;
git_otype base_type;
/*
diff --git a/src/pool.c b/src/pool.c
index a516ff9eb..30555273e 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -7,7 +7,7 @@ struct git_pool_page {
git_pool_page *next;
uint32_t size;
uint32_t avail;
- char data[GIT_FLEX_ARRAY];
+ GIT_ALIGN(char data[GIT_FLEX_ARRAY], 8);
};
struct pool_freelist {
diff --git a/tests/merge/merge_helpers.c b/tests/merge/merge_helpers.c
index 154985f11..e3e703943 100644
--- a/tests/merge/merge_helpers.c
+++ b/tests/merge/merge_helpers.c
@@ -327,7 +327,7 @@ int merge_test_reuc(git_index *index, const struct merge_reuc_entry expected[],
int dircount(void *payload, git_buf *pathbuf)
{
- int *entries = payload;
+ size_t *entries = payload;
size_t len = git_buf_len(pathbuf);
if (len < 5 || strcmp(pathbuf->ptr + (git_buf_len(pathbuf) - 5), "/.git") != 0)
diff --git a/tests/odb/foreach.c b/tests/odb/foreach.c
index 56daf7574..75448a2f7 100644
--- a/tests/odb/foreach.c
+++ b/tests/odb/foreach.c
@@ -87,7 +87,7 @@ void test_odb_foreach__files_in_objects_dir(void)
git_repository *repo;
git_odb *odb;
git_buf buf = GIT_BUF_INIT;
- size_t nobj = 0;
+ int nobj = 0;
cl_fixture_sandbox("testrepo.git");
cl_git_pass(git_repository_open(&repo, "testrepo.git"));
diff --git a/tests/pack/packbuilder.c b/tests/pack/packbuilder.c
index 12273ec85..29f3e2d64 100644
--- a/tests/pack/packbuilder.c
+++ b/tests/pack/packbuilder.c
@@ -47,7 +47,7 @@ void test_pack_packbuilder__cleanup(void)
git_indexer_free(_indexer);
_indexer = NULL;
- p_chdir("..");
+ cl_git_pass(p_chdir(".."));
cl_git_sandbox_cleanup();
_repo = NULL;
}