index: Cleanup tree parsing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
diff --git a/src/index.c b/src/index.c
index b49ed19..d3590da 100644
--- a/src/index.c
+++ b/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) {
error = GIT_EOBJCORRUPTED;
- goto exit;
+ goto cleanup;
}
/* NUL-terminated tree name */
tree->name = git__strdup(name_start);
if (tree->name == NULL) {
error = GIT_ENOMEM;
- goto exit;
+ goto cleanup;
}
if (++buffer >= buffer_end) {
error = GIT_EOBJCORRUPTED;
- goto exit;
+ goto cleanup;
}
/* Blank-terminated ASCII decimal number of entries in this tree */
- if (git__strtol32(&count, buffer, &buffer, 10) < GIT_SUCCESS ||
- count < -1) {
+ if (git__strtol32(&count, buffer, &buffer, 10) < GIT_SUCCESS || count < -1) {
error = GIT_EOBJCORRUPTED;
- goto exit;
+ goto cleanup;
}
/* Invalidated TREE. Free the tree but report success */
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 */
- tree = NULL;
- error = GIT_SUCCESS;
- goto exit;
+ return GIT_SUCCESS;
}
tree->entries = (size_t)count;
if (*buffer != ' ' || ++buffer >= buffer_end) {
error = GIT_EOBJCORRUPTED;
- goto exit;
+ goto cleanup;
}
/* Number of children of the tree, newline-terminated */
if (git__strtol32(&count, buffer, &buffer, 10) < GIT_SUCCESS ||
count < 0) {
error = GIT_EOBJCORRUPTED;
- goto exit;
+ goto cleanup;
}
tree->children_count = (size_t)count;
if (*buffer != '\n' || ++buffer >= buffer_end) {
error = GIT_EOBJCORRUPTED;
- goto exit;
+ goto cleanup;
}
/* 160-bit SHA-1 for this tree and it's children */
if (buffer + GIT_OID_RAWSZ > buffer_end) {
error = GIT_EOBJCORRUPTED;
- goto exit;
+ goto cleanup;
}
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 *));
if (tree->children == NULL)
- goto exit;
+ goto cleanup;
for (i = 0; i < tree->children_count; ++i) {
err = read_tree_internal(&tree->children[i], &buffer, buffer_end, tree);
if (err < GIT_SUCCESS)
- goto exit;
+ goto cleanup;
}
}
- exit:
*buffer_in = buffer;
- if (error < GIT_SUCCESS) {
- free_tree(tree);
- } else {
- *out = tree;
- }
+ *out = tree;
+ return GIT_SUCCESS;
+
+ cleanup:
+ free_tree(tree);
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);
- 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)