mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-30 22:24:56 +00:00
index: Fix issues in the unmerged entries API
This commit is contained in:
parent
7b134cfebe
commit
f4e2aca29c
@ -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);
|
|||||||
* 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);
|
|||||||
* @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);
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
68
src/index.c
68
src/index.c
@ -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
|
|||||||
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)
|
|||||||
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)
|
|||||||
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
|
|||||||
} 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)
|
|||||||
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 (!index->unmerged.length)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if ((pos = git_vector_bsearch2(&index->unmerged, unmerged_srch, path)) < GIT_SUCCESS)
|
if ((pos = git_vector_bsearch2(&index->unmerged, unmerged_srch, path)) < GIT_SUCCESS)
|
||||||
return pos;
|
return NULL;
|
||||||
|
|
||||||
if ((*entry = git_vector_get(&index->unmerged, pos)) == NULL) {
|
return git_vector_get(&index->unmerged, pos);
|
||||||
return GIT_ENOTFOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GIT_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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(
|
|||||||
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
|
|||||||
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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user