Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/git2/remote.h2
-rw-r--r--src/index.c89
-rw-r--r--src/tree.c61
-rw-r--r--tests/t09-tree.c5
4 files changed, 94 insertions, 63 deletions
diff --git a/include/git2/remote.h b/include/git2/remote.h
index fc05867c7..7775070d8 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -87,7 +87,7 @@ GIT_EXTERN(const git_refspec *) git_remote_fetchspec(struct git_remote *remote);
* @return a pointer to the push refspec or NULL if it doesn't exist
*/
-GIT_EXTERN(const git_refspec *) git_remote_fetchspec(struct git_remote *remote);
+GIT_EXTERN(const git_refspec *) git_remote_pushspec(struct git_remote *remote);
/**
* Open a connection to a remote
diff --git a/src/index.c b/src/index.c
index af98cdc4b..2fa9c1922 100644
--- a/src/index.c
+++ b/src/index.c
@@ -103,42 +103,39 @@ static int read_tree_internal(git_index_tree **, const char **, const char *, gi
static int parse_index(git_index *index, const char *buffer, size_t buffer_size);
static int is_index_extended(git_index *index);
-static void sort_index(git_index *index);
static int write_index(git_index *index, git_filebuf *file);
-int index_srch(const void *key, const void *array_member)
+static int index_srch(const void *key, const void *array_member)
{
- const char *filename = (const char *)key;
- const git_index_entry *entry = (const git_index_entry *)(array_member);
+ const git_index_entry *entry = array_member;
- return strcmp(filename, entry->path);
+ return strcmp(key, entry->path);
}
-int index_cmp(const void *a, const void *b)
+static int index_cmp(const void *a, const void *b)
{
- const git_index_entry *entry_a = (const git_index_entry *)(a);
- const git_index_entry *entry_b = (const git_index_entry *)(b);
+ const git_index_entry *entry_a = a;
+ const git_index_entry *entry_b = b;
return strcmp(entry_a->path, entry_b->path);
}
-int unmerged_srch(const void *key, const void *array_member)
+static int unmerged_srch(const void *key, const void *array_member)
{
- const char *path = (const char *) key;
- const git_index_entry_unmerged *entry = (const git_index_entry_unmerged *)(array_member);
+ const git_index_entry_unmerged *entry = array_member;
- return strcmp(path, entry->path);
+ return strcmp(key, entry->path);
}
-int unmerged_cmp(const void *a, const void *b)
+static int unmerged_cmp(const void *a, const void *b)
{
- const git_index_entry_unmerged *info_a = (const git_index_entry_unmerged *)(a);
- const git_index_entry_unmerged *info_b = (const git_index_entry_unmerged *)(b);
+ const git_index_entry_unmerged *info_a = a;
+ const git_index_entry_unmerged *info_b = b;
return strcmp(info_a->path, info_b->path);
}
-unsigned int index_create_mode(unsigned int mode)
+static unsigned int index_create_mode(unsigned int mode)
{
if (S_ISLNK(mode))
return S_IFLNK;
@@ -179,7 +176,6 @@ static int index_initialize(git_index **index_out, git_repository *owner, const
int git_index_open(git_index **index_out, const char *index_path)
{
- assert(index_out && index_path);
return index_initialize(index_out, NULL, index_path);
}
@@ -188,8 +184,6 @@ int git_index_open(git_index **index_out, const char *index_path)
*/
int git_repository_index(git_index **index_out, git_repository *repo)
{
- assert(index_out && repo);
-
if (repo->is_bare)
return git__throw(GIT_EBAREINDEX, "Failed to open index. Repository is bare");
@@ -202,8 +196,6 @@ void git_index_free(git_index *index)
return;
git_index_clear(index);
- git_vector_free(&index->entries);
- git_vector_free(&index->unmerged);
free(index->index_file_path);
free(index);
@@ -298,7 +290,7 @@ int git_index_write(git_index *index)
struct stat indexst;
int error;
- sort_index(index);
+ git_vector_sort(&index->entries);
if ((error = git_filebuf_open(&file, index->index_file_path, GIT_FILEBUF_HASH_CONTENTS)) < GIT_SUCCESS)
return git__rethrow(error, "Failed to write index");
@@ -333,14 +325,8 @@ unsigned int git_index_entrycount_unmerged(git_index *index)
git_index_entry *git_index_get(git_index *index, unsigned int n)
{
- assert(index);
- sort_index(index);
- return git_vector_get(&index->entries, n);
-}
-
-static void sort_index(git_index *index)
-{
git_vector_sort(&index->entries);
+ return git_vector_get(&index->entries, n);
}
static int index_insert(git_index *index, const git_index_entry *source_entry, int replace)
@@ -450,7 +436,7 @@ static int index_init_entry(git_index_entry *entry, git_index *index, const char
return git__rethrow(error, "Failed to initialize index entry");
entry->flags |= (stage << GIT_IDXENTRY_STAGESHIFT);
- entry->path = (char *)rel_path; /* do not duplicate; index_insert already does this */
+ entry->path = rel_path; /* do not duplicate; index_insert already does this */
return GIT_SUCCESS;
}
@@ -489,14 +475,12 @@ int git_index_append2(git_index *index, const git_index_entry *source_entry)
int git_index_remove(git_index *index, int position)
{
- assert(index);
- sort_index(index);
+ git_vector_sort(&index->entries);
return git_vector_remove(&index->entries, (unsigned int)position);
}
int git_index_find(git_index *index, const char *path)
{
- sort_index(index);
return git_vector_bsearch2(&index->entries, index_srch, path);
}
@@ -575,7 +559,7 @@ static int read_tree_internal(git_index_tree **out,
return GIT_SUCCESS;
}
- tree->entries = (size_t)count;
+ tree->entries = count;
if (*buffer != ' ' || ++buffer >= buffer_end) {
error = GIT_EOBJCORRUPTED;
@@ -589,7 +573,7 @@ static int read_tree_internal(git_index_tree **out,
goto cleanup;
}
- tree->children_count = (size_t)count;
+ tree->children_count = count;
if (*buffer != '\n' || ++buffer >= buffer_end) {
error = GIT_EOBJCORRUPTED;
@@ -673,11 +657,15 @@ static int read_unmerged(git_index *index, const char *buffer, size_t size)
buffer += len;
for (i = 0; i < 3; i++) {
- if (git__strtol32((long int *) &lost->mode[i], buffer, &endptr, 8) < GIT_SUCCESS ||
- !endptr || endptr == buffer || *endptr)
+ long tmp;
+
+ if (git__strtol32(&tmp, buffer, &endptr, 8) < GIT_SUCCESS ||
+ !endptr || endptr == buffer || *endptr || tmp > UINT_MAX)
return GIT_ERROR;
- len = (endptr + 1) - (char *) buffer;
+ lost->mode[i] = tmp;
+
+ len = (endptr + 1) - buffer;
if (size <= len)
return git__throw(GIT_ERROR, "Failed to read unmerged entries");
@@ -704,15 +692,13 @@ static size_t read_entry(git_index_entry *dest, const void *buffer, size_t buffe
size_t path_length, entry_size;
uint16_t flags_raw;
const char *path_ptr;
- const struct entry_short *source;
+ const struct entry_short *source = buffer;
if (INDEX_FOOTER_SIZE + minimal_entry_size > buffer_size)
return 0;
memset(dest, 0x0, sizeof(git_index_entry));
- source = (const struct entry_short *)(buffer);
-
dest->ctime.seconds = (git_time_t)ntohl(source->ctime.seconds);
dest->ctime.nanoseconds = ntohl(source->ctime.nanoseconds);
dest->mtime.seconds = (git_time_t)ntohl(source->mtime.seconds);
@@ -765,8 +751,7 @@ static size_t read_entry(git_index_entry *dest, const void *buffer, size_t buffe
static int read_header(struct index_header *dest, const void *buffer)
{
- const struct index_header *source;
- source = (const struct index_header *)(buffer);
+ const struct index_header *source = buffer;
dest->signature = ntohl(source->signature);
if (dest->signature != INDEX_HEADER_SIG)
@@ -836,7 +821,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
/* Precalculate the SHA1 of the files's contents -- we'll match it to
* the provided SHA1 in the footer */
- git_hash_buf(&checksum_calculated, (const void *)buffer, buffer_size - INDEX_FOOTER_SIZE);
+ git_hash_buf(&checksum_calculated, buffer, buffer_size - INDEX_FOOTER_SIZE);
/* Parse header */
if (read_header(&header, buffer) < GIT_SUCCESS)
@@ -936,8 +921,18 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry)
memset(ondisk, 0x0, disk_size);
- ondisk->ctime.seconds = htonl((unsigned long)entry->ctime.seconds);
- ondisk->mtime.seconds = htonl((unsigned long)entry->mtime.seconds);
+ /**
+ * Yes, we have to truncate.
+ *
+ * The on-disk format for Index entries clearly defines
+ * the time and size fields to be 4 bytes each -- so even if
+ * we store these values with 8 bytes on-memory, they must
+ * be truncated to 4 bytes before writing to disk.
+ *
+ * In 2038 I will be either too dead or too rich to care about this
+ */
+ ondisk->ctime.seconds = htonl((uint32_t)entry->ctime.seconds);
+ ondisk->mtime.seconds = htonl((uint32_t)entry->mtime.seconds);
ondisk->ctime.nanoseconds = htonl(entry->ctime.nanoseconds);
ondisk->mtime.nanoseconds = htonl(entry->mtime.nanoseconds);
ondisk->dev = htonl(entry->dev);
@@ -945,7 +940,7 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry)
ondisk->mode = htonl(entry->mode);
ondisk->uid = htonl(entry->uid);
ondisk->gid = htonl(entry->gid);
- ondisk->file_size = htonl((unsigned long)entry->file_size);
+ ondisk->file_size = htonl((uint32_t)entry->file_size);
git_oid_cpy(&ondisk->oid, &entry->oid);
diff --git a/src/tree.c b/src/tree.c
index ad9643f69..975d36a70 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -37,29 +37,48 @@ static int valid_attributes(const int attributes) {
return attributes >= 0 && attributes <= MAX_FILEMODE;
}
+struct tree_key_search {
+ const char *filename;
+ size_t filename_len;
+};
+
int entry_search_cmp(const void *key, const void *array_member)
{
- const char *filename = (const char *)key;
+ struct tree_key_search *ksearch = (struct tree_key_search *)key;
const git_tree_entry *entry = (const git_tree_entry *)(array_member);
- return strcmp(filename, entry->filename);
-}
+ int result =
+ git_futils_cmp_path(
+ ksearch->filename, ksearch->filename_len, entry->attr & 040000,
+ entry->filename, entry->filename_len, entry->attr & 040000);
-#if 0
-static int valid_attributes(const int attributes) {
- return attributes >= 0 && attributes <= MAX_FILEMODE;
+ return result ? result : ((int)ksearch->filename_len - (int)entry->filename_len);
}
-#endif
int entry_sort_cmp(const void *a, const void *b)
{
const git_tree_entry *entry_a = (const git_tree_entry *)(a);
const git_tree_entry *entry_b = (const git_tree_entry *)(b);
- return git_futils_cmp_path(entry_a->filename, strlen(entry_a->filename),
- entry_a->attr & 040000,
- entry_b->filename, strlen(entry_b->filename),
- entry_b->attr & 040000);
+ return git_futils_cmp_path(
+ entry_a->filename, entry_a->filename_len, entry_a->attr & 040000,
+ entry_b->filename, entry_b->filename_len, entry_b->attr & 040000);
+}
+
+static int build_ksearch(struct tree_key_search *ksearch, const char *path)
+{
+ size_t len = strlen(path);
+
+ if (len && path[len - 1] == '/')
+ len--;
+
+ if (len == 0 || memchr(path, '/', len) != NULL)
+ return GIT_ERROR;
+
+ ksearch->filename = path;
+ ksearch->filename_len = len;
+
+ return GIT_SUCCESS;
}
void git_tree__free(git_tree *tree)
@@ -121,10 +140,14 @@ int git_tree_entry_2object(git_object **object_out, git_repository *repo, const
const git_tree_entry *git_tree_entry_byname(git_tree *tree, const char *filename)
{
int idx;
+ struct tree_key_search ksearch;
assert(tree && filename);
- idx = git_vector_bsearch2(&tree->entries, entry_search_cmp, filename);
+ if (build_ksearch(&ksearch, filename) < GIT_SUCCESS)
+ return NULL;
+
+ idx = git_vector_bsearch2(&tree->entries, entry_search_cmp, &ksearch);
if (idx == GIT_ENOTFOUND)
return NULL;
@@ -351,13 +374,17 @@ int git_treebuilder_insert(git_tree_entry **entry_out, git_treebuilder *bld, con
{
git_tree_entry *entry;
int pos;
+ struct tree_key_search ksearch;
assert(bld && id && filename);
if (!valid_attributes(attributes))
- return git__throw(GIT_ERROR, "Failed to insert entry. Invalid atrributes");
+ return git__throw(GIT_ERROR, "Failed to insert entry. Invalid attributes");
+
+ if (build_ksearch(&ksearch, filename) < GIT_SUCCESS)
+ return git__throw(GIT_ERROR, "Failed to insert entry. Invalid filename '%s'", filename);
- if ((pos = git_vector_bsearch2(&bld->entries, entry_search_cmp, filename)) != GIT_ENOTFOUND) {
+ if ((pos = git_vector_bsearch2(&bld->entries, entry_search_cmp, &ksearch)) != GIT_ENOTFOUND) {
entry = git_vector_get(&bld->entries, pos);
if (entry->removed) {
entry->removed = 0;
@@ -392,11 +419,15 @@ const git_tree_entry *git_treebuilder_get(git_treebuilder *bld, const char *file
{
int idx;
git_tree_entry *entry;
+ struct tree_key_search ksearch;
assert(bld && filename);
+ if (build_ksearch(&ksearch, filename) < GIT_SUCCESS)
+ return NULL;
+
sort_entries(bld);
- idx = git_vector_bsearch2(&bld->entries, entry_search_cmp, filename);
+ idx = git_vector_bsearch2(&bld->entries, entry_search_cmp, &ksearch);
if (idx == GIT_ENOTFOUND)
return NULL;
diff --git a/tests/t09-tree.c b/tests/t09-tree.c
index 640deab00..be21e4e33 100644
--- a/tests/t09-tree.c
+++ b/tests/t09-tree.c
@@ -150,6 +150,11 @@ BEGIN_TEST(write2, "write a tree from a memory")
//create a second tree from first tree using `git_treebuilder_insert` on REPOSITORY_FOLDER.
must_pass(git_tree_lookup(&tree, repo, &id));
must_pass(git_treebuilder_create(&builder, tree));
+
+ must_fail(git_treebuilder_insert(NULL, builder, "", &bid, 0100644));
+ must_fail(git_treebuilder_insert(NULL, builder, "/", &bid, 0100644));
+ must_fail(git_treebuilder_insert(NULL, builder, "folder/new.txt", &bid, 0100644));
+
must_pass(git_treebuilder_insert(NULL,builder,"new.txt",&bid,0100644));
must_pass(git_treebuilder_write(&rid,repo,builder));