Commit f4e2aca2 by Vicent Marti

index: Fix issues in the unmerged entries API

parent 7b134cfe
...@@ -98,14 +98,14 @@ typedef struct git_index_entry { ...@@ -98,14 +98,14 @@ typedef struct git_index_entry {
unsigned short flags; unsigned short flags;
unsigned short flags_extended; unsigned short flags_extended;
char *path; const char *path;
} git_index_entry; } git_index_entry;
/** Representation of an unmerged file entry in the index. */ /** Representation of an unmerged file entry in the index. */
typedef struct git_index_entry_unmerged { typedef struct git_index_entry_unmerged {
unsigned int mode[3]; unsigned int mode[3];
git_oid oid[3]; git_oid oid[3];
char *path; const char *path;
} git_index_entry_unmerged; } git_index_entry_unmerged;
/** /**
...@@ -256,6 +256,8 @@ GIT_EXTERN(int) git_index_remove(git_index *index, int position); ...@@ -256,6 +256,8 @@ GIT_EXTERN(int) git_index_remove(git_index *index, int position);
* This entry can be modified, and the changes will be written * This entry can be modified, and the changes will be written
* back to disk on the next write() call. * back to disk on the next write() call.
* *
* The entry should not be freed by the caller.
*
* @param index an existing index object * @param index an existing index object
* @param n the position of the entry * @param n the position of the entry
* @return a pointer to the entry; NULL if out of bounds * @return a pointer to the entry; NULL if out of bounds
...@@ -276,17 +278,19 @@ GIT_EXTERN(unsigned int) git_index_entrycount(git_index *index); ...@@ -276,17 +278,19 @@ GIT_EXTERN(unsigned int) git_index_entrycount(git_index *index);
* @param index an existing index object * @param index an existing index object
* @return integer of count of current unmerged entries * @return integer of count of current unmerged entries
*/ */
GIT_EXTERN(unsigned int) git_index_unmerged_entrycount(git_index *index); GIT_EXTERN(unsigned int) git_index_entrycount_unmerged(git_index *index);
/** /**
* Get an unmerged entry from the index. * Get an unmerged entry from the index.
* *
* @param entry the pointer to the new unmerged entry * The returned entry is read-only and should not be modified
* of freed by the caller.
*
* @param index an existing index object * @param index an existing index object
* @param path path to search * @param path path to search
* @return 0 on success, otherwise an error code * @return the unmerged entry; NULL if not found
*/ */
GIT_EXTERN(int) git_index_get_unmerged(git_index_entry_unmerged **entry, git_index *index, const char *path); GIT_EXTERN(const git_index_entry_unmerged *) git_index_get_unmerged(git_index *index, const char *path);
/** @} */ /** @} */
......
...@@ -100,7 +100,6 @@ static int read_header(struct index_header *dest, const void *buffer); ...@@ -100,7 +100,6 @@ static int read_header(struct index_header *dest, const void *buffer);
static int read_tree(git_index *index, const char *buffer, size_t buffer_size); static int read_tree(git_index *index, const char *buffer, size_t buffer_size);
static git_index_tree *read_tree_internal(const char **, const char *, git_index_tree *); static git_index_tree *read_tree_internal(const char **, const char *, git_index_tree *);
static int read_unmerged_internal(git_index *, const char **, size_t buffer_size);
static int parse_index(git_index *index, const char *buffer, size_t buffer_size); static int parse_index(git_index *index, const char *buffer, size_t buffer_size);
static int is_index_extended(git_index *index); static int is_index_extended(git_index *index);
...@@ -160,7 +159,6 @@ static int index_initialize(git_index **index_out, git_repository *owner, const ...@@ -160,7 +159,6 @@ static int index_initialize(git_index **index_out, git_repository *owner, const
index->repository = owner; index->repository = owner;
git_vector_init(&index->entries, 32, index_cmp); git_vector_init(&index->entries, 32, index_cmp);
git_vector_init(&index->unmerged, 32, unmerged_cmp);
/* Check if index file is stored on disk already */ /* Check if index file is stored on disk already */
if (gitfo_exists(index->index_file_path) == 0) if (gitfo_exists(index->index_file_path) == 0)
...@@ -219,7 +217,7 @@ void git_index_clear(git_index *index) ...@@ -219,7 +217,7 @@ void git_index_clear(git_index *index)
for (i = 0; i < index->entries.length; ++i) { for (i = 0; i < index->entries.length; ++i) {
git_index_entry *e; git_index_entry *e;
e = git_vector_get(&index->entries, i); e = git_vector_get(&index->entries, i);
free(e->path); free((char *)e->path);
free(e); free(e);
} }
...@@ -303,13 +301,9 @@ unsigned int git_index_entrycount(git_index *index) ...@@ -303,13 +301,9 @@ unsigned int git_index_entrycount(git_index *index)
return index->entries.length; return index->entries.length;
} }
unsigned int git_index_unmerged_entrycount(git_index *index) unsigned int git_index_entrycount_unmerged(git_index *index)
{ {
assert(index); assert(index);
if (!&index->unmerged)
return 0;
return index->unmerged.length; return index->unmerged.length;
} }
...@@ -373,7 +367,7 @@ static int index_insert(git_index *index, const git_index_entry *source_entry, i ...@@ -373,7 +367,7 @@ static int index_insert(git_index *index, const git_index_entry *source_entry, i
} else { } else {
git_index_entry **entry_array = (git_index_entry **)index->entries.contents; git_index_entry **entry_array = (git_index_entry **)index->entries.contents;
free(entry_array[position]->path); free((char *)entry_array[position]->path);
free(entry_array[position]); free(entry_array[position]);
entry_array[position] = entry; entry_array[position] = entry;
...@@ -470,19 +464,18 @@ int git_index_find(git_index *index, const char *path) ...@@ -470,19 +464,18 @@ int git_index_find(git_index *index, const char *path)
return git_vector_bsearch2(&index->entries, index_srch, path); return git_vector_bsearch2(&index->entries, index_srch, path);
} }
int git_index_get_unmerged(git_index_entry_unmerged **entry, git_index *index, const char *path) const git_index_entry_unmerged *git_index_get_unmerged(git_index *index, const char *path)
{ {
int pos; int pos;
assert(index); assert(index && path);
if ((pos = git_vector_bsearch2(&index->unmerged, unmerged_srch, path)) < GIT_SUCCESS) if (!index->unmerged.length)
return pos; return NULL;
if ((*entry = git_vector_get(&index->unmerged, pos)) == NULL) { if ((pos = git_vector_bsearch2(&index->unmerged, unmerged_srch, path)) < GIT_SUCCESS)
return GIT_ENOTFOUND; return NULL;
}
return GIT_SUCCESS; return git_vector_get(&index->unmerged, pos);
} }
...@@ -568,43 +561,43 @@ static int read_tree(git_index *index, const char *buffer, size_t buffer_size) ...@@ -568,43 +561,43 @@ static int read_tree(git_index *index, const char *buffer, size_t buffer_size)
return (index->tree != NULL && buffer == buffer_end) ? GIT_SUCCESS : GIT_EOBJCORRUPTED; return (index->tree != NULL && buffer == buffer_end) ? GIT_SUCCESS : GIT_EOBJCORRUPTED;
} }
static int read_unmerged_internal( static int read_unmerged(git_index *index, const char *buffer, size_t size)
git_index *index, const char **buffer_in, size_t buffer_size)
{ {
const char *buffer, *endptr; const char *endptr;
size_t size, len; size_t len;
int i; int i;
size = buffer_size; git_vector_init(&index->unmerged, 16, unmerged_cmp);
while (size) { while (size) {
git_index_entry_unmerged *lost; git_index_entry_unmerged *lost;
buffer = *buffer_in;
len = strlen(buffer) + 1; len = strlen(buffer) + 1;
if (size <= len) if (size <= len)
return GIT_ERROR; return GIT_ERROR;
if ((lost = git__malloc(sizeof(git_index_entry_unmerged))) == NULL) if ((lost = git__malloc(sizeof(git_index_entry_unmerged))) == NULL)
return GIT_ERROR; return GIT_ENOMEM;
if ((lost->path = git__malloc(strlen(buffer))) == NULL)
return GIT_ERROR;
strcpy(lost->path, buffer);
if (git_vector_insert(&index->unmerged, lost) < GIT_SUCCESS) if (git_vector_insert(&index->unmerged, lost) < GIT_SUCCESS)
return GIT_ERROR; return GIT_ERROR;
lost->path = git__strdup(buffer);
if (!lost->path)
return GIT_ENOMEM;
size -= len; size -= len;
buffer += len; buffer += len;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
if (git__strtol32((long int *) &lost->mode[i], buffer, &endptr, 8) < GIT_SUCCESS || !endptr || endptr == buffer || *endptr) if (git__strtol32((long int *) &lost->mode[i], buffer, &endptr, 8) < GIT_SUCCESS ||
!endptr || endptr == buffer || *endptr)
return GIT_ERROR; return GIT_ERROR;
len = (endptr + 1) - (char *) buffer; len = (endptr + 1) - (char *) buffer;
if (size <= len) if (size <= len)
return GIT_ERROR; return GIT_ERROR;
size -= len; size -= len;
buffer += len; buffer += len;
} }
...@@ -614,22 +607,16 @@ static int read_unmerged_internal( ...@@ -614,22 +607,16 @@ static int read_unmerged_internal(
continue; continue;
if (size < 20) if (size < 20)
return GIT_ERROR; return GIT_ERROR;
git_oid_mkraw(&lost->oid[i], (unsigned char *) buffer); git_oid_mkraw(&lost->oid[i], (unsigned char *) buffer);
size -= 20; size -= 20;
buffer += 20; buffer += 20;
} }
} }
*buffer_in = buffer;
return GIT_SUCCESS; return GIT_SUCCESS;
} }
static int read_unmerged(git_index *index, const char *buffer, size_t buffer_size)
{
read_unmerged_internal(index, &buffer, buffer_size);
return (&index->unmerged != NULL) ? GIT_SUCCESS : GIT_EOBJCORRUPTED;
}
static size_t read_entry(git_index_entry *dest, const void *buffer, size_t buffer_size) static size_t read_entry(git_index_entry *dest, const void *buffer, size_t buffer_size)
{ {
size_t path_length, entry_size; size_t path_length, entry_size;
...@@ -732,17 +719,14 @@ static size_t read_extension(git_index *index, const char *buffer, size_t buffer ...@@ -732,17 +719,14 @@ static size_t read_extension(git_index *index, const char *buffer, size_t buffer
if (dest.signature[0] >= 'A' && dest.signature[0] <= 'Z') { if (dest.signature[0] >= 'A' && dest.signature[0] <= 'Z') {
/* tree cache */ /* tree cache */
if (memcmp(dest.signature, INDEX_EXT_TREECACHE_SIG, 4) == 0) { if (memcmp(dest.signature, INDEX_EXT_TREECACHE_SIG, 4) == 0) {
if (read_tree(index, buffer + 8, dest.extension_size) < GIT_SUCCESS) if (read_tree(index, buffer + 8, dest.extension_size) < GIT_SUCCESS)
return 0; return 0;
} else if (memcmp(dest.signature, INDEX_EXT_UNMERGED_SIG, 4) == 0) { } else if (memcmp(dest.signature, INDEX_EXT_UNMERGED_SIG, 4) == 0) {
if (read_unmerged(index, buffer + 8, dest.extension_size) < GIT_SUCCESS) if (read_unmerged(index, buffer + 8, dest.extension_size) < GIT_SUCCESS)
return 0; return 0;
} else {
;
} }
/* else, unsupported extension. We cannot parse this, but we can skip
* it by returning `total_size */
} else { } else {
/* we cannot handle non-ignorable extensions; /* we cannot handle non-ignorable extensions;
* in fact they aren't even defined in the standard */ * in fact they aren't even defined in the standard */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment