mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-09 20:29:27 +00:00
index: Cleanup tree parsing
This commit is contained in:
parent
a02fc2cd16
commit
786ad84fa9
46
src/index.c
46
src/index.c
@ -503,62 +503,62 @@ static int read_tree_internal(git_index_tree **out,
|
|||||||
|
|
||||||
if ((buffer = memchr(buffer, '\0', buffer_end - buffer)) == NULL) {
|
if ((buffer = memchr(buffer, '\0', buffer_end - buffer)) == NULL) {
|
||||||
error = GIT_EOBJCORRUPTED;
|
error = GIT_EOBJCORRUPTED;
|
||||||
goto exit;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NUL-terminated tree name */
|
/* NUL-terminated tree name */
|
||||||
tree->name = git__strdup(name_start);
|
tree->name = git__strdup(name_start);
|
||||||
if (tree->name == NULL) {
|
if (tree->name == NULL) {
|
||||||
error = GIT_ENOMEM;
|
error = GIT_ENOMEM;
|
||||||
goto exit;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++buffer >= buffer_end) {
|
if (++buffer >= buffer_end) {
|
||||||
error = GIT_EOBJCORRUPTED;
|
error = GIT_EOBJCORRUPTED;
|
||||||
goto exit;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Blank-terminated ASCII decimal number of entries in this tree */
|
/* Blank-terminated ASCII decimal number of entries in this tree */
|
||||||
if (git__strtol32(&count, buffer, &buffer, 10) < GIT_SUCCESS ||
|
if (git__strtol32(&count, buffer, &buffer, 10) < GIT_SUCCESS || count < -1) {
|
||||||
count < -1) {
|
|
||||||
error = GIT_EOBJCORRUPTED;
|
error = GIT_EOBJCORRUPTED;
|
||||||
goto exit;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Invalidated TREE. Free the tree but report success */
|
/* Invalidated TREE. Free the tree but report success */
|
||||||
if (count == -1) {
|
if (count == -1) {
|
||||||
buffer = buffer_end;
|
/* FIXME: return buffer_end or the end position for
|
||||||
|
* this single tree entry */
|
||||||
|
*buffer_in = buffer_end;
|
||||||
|
*out = NULL;
|
||||||
free_tree(tree); /* Needs to be done manually */
|
free_tree(tree); /* Needs to be done manually */
|
||||||
tree = NULL;
|
return GIT_SUCCESS;
|
||||||
error = GIT_SUCCESS;
|
|
||||||
goto exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tree->entries = (size_t)count;
|
tree->entries = (size_t)count;
|
||||||
|
|
||||||
if (*buffer != ' ' || ++buffer >= buffer_end) {
|
if (*buffer != ' ' || ++buffer >= buffer_end) {
|
||||||
error = GIT_EOBJCORRUPTED;
|
error = GIT_EOBJCORRUPTED;
|
||||||
goto exit;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Number of children of the tree, newline-terminated */
|
/* Number of children of the tree, newline-terminated */
|
||||||
if (git__strtol32(&count, buffer, &buffer, 10) < GIT_SUCCESS ||
|
if (git__strtol32(&count, buffer, &buffer, 10) < GIT_SUCCESS ||
|
||||||
count < 0) {
|
count < 0) {
|
||||||
error = GIT_EOBJCORRUPTED;
|
error = GIT_EOBJCORRUPTED;
|
||||||
goto exit;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
tree->children_count = (size_t)count;
|
tree->children_count = (size_t)count;
|
||||||
|
|
||||||
if (*buffer != '\n' || ++buffer >= buffer_end) {
|
if (*buffer != '\n' || ++buffer >= buffer_end) {
|
||||||
error = GIT_EOBJCORRUPTED;
|
error = GIT_EOBJCORRUPTED;
|
||||||
goto exit;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 160-bit SHA-1 for this tree and it's children */
|
/* 160-bit SHA-1 for this tree and it's children */
|
||||||
if (buffer + GIT_OID_RAWSZ > buffer_end) {
|
if (buffer + GIT_OID_RAWSZ > buffer_end) {
|
||||||
error = GIT_EOBJCORRUPTED;
|
error = GIT_EOBJCORRUPTED;
|
||||||
goto exit;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
git_oid_mkraw(&tree->oid, (const unsigned char *)buffer);
|
git_oid_mkraw(&tree->oid, (const unsigned char *)buffer);
|
||||||
@ -571,23 +571,22 @@ static int read_tree_internal(git_index_tree **out,
|
|||||||
|
|
||||||
tree->children = git__malloc(tree->children_count * sizeof(git_index_tree *));
|
tree->children = git__malloc(tree->children_count * sizeof(git_index_tree *));
|
||||||
if (tree->children == NULL)
|
if (tree->children == NULL)
|
||||||
goto exit;
|
goto cleanup;
|
||||||
|
|
||||||
for (i = 0; i < tree->children_count; ++i) {
|
for (i = 0; i < tree->children_count; ++i) {
|
||||||
err = read_tree_internal(&tree->children[i], &buffer, buffer_end, tree);
|
err = read_tree_internal(&tree->children[i], &buffer, buffer_end, tree);
|
||||||
|
|
||||||
if (err < GIT_SUCCESS)
|
if (err < GIT_SUCCESS)
|
||||||
goto exit;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
|
||||||
*buffer_in = buffer;
|
*buffer_in = buffer;
|
||||||
if (error < GIT_SUCCESS) {
|
|
||||||
free_tree(tree);
|
|
||||||
} else {
|
|
||||||
*out = tree;
|
*out = tree;
|
||||||
}
|
return GIT_SUCCESS;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
free_tree(tree);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,7 +597,10 @@ static int read_tree(git_index *index, const char *buffer, size_t buffer_size)
|
|||||||
|
|
||||||
error = read_tree_internal(&index->tree, &buffer, buffer_end, NULL);
|
error = read_tree_internal(&index->tree, &buffer, buffer_end, NULL);
|
||||||
|
|
||||||
return (error == GIT_SUCCESS && buffer == buffer_end) ? GIT_SUCCESS : GIT_EOBJCORRUPTED;
|
if (buffer < buffer_end)
|
||||||
|
return GIT_EOBJCORRUPTED;
|
||||||
|
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_unmerged(git_index *index, const char *buffer, size_t size)
|
static int read_unmerged(git_index *index, const char *buffer, size_t size)
|
||||||
|
Loading…
Reference in New Issue
Block a user