idxmap: have `resize` functions return proper error code The currently existing function `git_idxmap_resize` and `git_idxmap_icase_resize` do not return any error codes at all due to their previous implementation making use of a macro. Due to that, it is impossible to see whether the resize operation might have failed due to an out-of-memory situation. Fix this by providing a proper error code. Adjust callers to make use of it.
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 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
diff --git a/src/idxmap.c b/src/idxmap.c
index 3511229..e3fcfb8 100644
--- a/src/idxmap.c
+++ b/src/idxmap.c
@@ -68,6 +68,24 @@ void git_idxmap_icase_clear(git_idxmap_icase *map)
kh_clear(idxicase, map);
}
+int git_idxmap_resize(git_idxmap *map, size_t size)
+{
+ if (kh_resize(idx, map, size) < 0) {
+ git_error_set_oom();
+ return -1;
+ }
+ return 0;
+}
+
+int git_idxmap_icase_resize(git_idxmap_icase *map, size_t size)
+{
+ if (kh_resize(idxicase, map, size) < 0) {
+ git_error_set_oom();
+ return -1;
+ }
+ return 0;
+}
+
void *git_idxmap_get(git_idxmap *map, const git_index_entry *key)
{
size_t idx = git_idxmap_lookup_index(map, key);
@@ -177,16 +195,6 @@ int git_idxmap_icase_has_data(git_idxmap_icase *map, size_t idx)
return kh_exist(map, idx);
}
-void git_idxmap_resize(git_idxmap *map, size_t size)
-{
- kh_resize(idx, map, size);
-}
-
-void git_idxmap_icase_resize(git_idxmap_icase *map, size_t size)
-{
- kh_resize(idxicase, map, size);
-}
-
void git_idxmap_delete_at(git_idxmap *map, size_t idx)
{
kh_del(idx, map, idx);
diff --git a/src/idxmap.h b/src/idxmap.h
index 55d60d5..cf14254 100644
--- a/src/idxmap.h
+++ b/src/idxmap.h
@@ -77,6 +77,26 @@ void git_idxmap_clear(git_idxmap *map);
void git_idxmap_icase_clear(git_idxmap_icase *map);
/**
+ * Resize the map by allocating more memory.
+ *
+ * @param map map that shall be resized
+ * @param size count of entries that the map shall hold
+ * @return `0` if the map was successfully resized, a negative
+ * error code otherwise
+ */
+int git_idxmap_resize(git_idxmap *map, size_t size);
+
+/**
+ * Resize the map by allocating more memory.
+ *
+ * @param map map that shall be resized
+ * @param size count of entries that the map shall hold
+ * @return `0` if the map was successfully resized, a negative
+ * error code otherwise
+ */
+int git_idxmap_icase_resize(git_idxmap_icase *map, size_t size);
+
+/**
* Return value associated with the given key.
*
* @param map map to search key in
@@ -137,9 +157,6 @@ int git_idxmap_icase_valid_index(git_idxmap_icase *map, size_t idx);
int git_idxmap_has_data(git_idxmap *map, size_t idx);
int git_idxmap_icase_has_data(git_idxmap_icase *map, size_t idx);
-void git_idxmap_resize(git_idxmap *map, size_t size);
-void git_idxmap_icase_resize(git_idxmap_icase *map, size_t size);
-
void git_idxmap_delete_at(git_idxmap *map, size_t idx);
void git_idxmap_icase_delete_at(git_idxmap_icase *map, size_t idx);
diff --git a/src/index.c b/src/index.c
index 308b89a..ee8dfd5 100644
--- a/src/index.c
+++ b/src/index.c
@@ -1619,8 +1619,9 @@ int git_index__fill(git_index *index, const git_vector *source_entries)
if (!source_entries->length)
return 0;
- git_vector_size_hint(&index->entries, source_entries->length);
- git_idxmap_resize(index->entries_map, (size_t)(source_entries->length * 1.3));
+ if (git_vector_size_hint(&index->entries, source_entries->length) < 0 ||
+ git_idxmap_resize(index->entries_map, (size_t)(source_entries->length * 1.3)) < 0)
+ return -1;
git_vector_foreach(source_entries, i, source_entry) {
git_index_entry *entry = NULL;
@@ -2608,10 +2609,12 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
assert(!index->entries.length);
- if (index->ignore_case)
- git_idxmap_icase_resize((git_idxmap_icase *) index->entries_map, header.entry_count);
- else
- git_idxmap_resize(index->entries_map, header.entry_count);
+ if (index->ignore_case &&
+ (error = git_idxmap_icase_resize((git_idxmap_icase *) index->entries_map,
+ header.entry_count)) < 0)
+ return error;
+ else if ((error = git_idxmap_resize(index->entries_map, header.entry_count)) < 0)
+ return error;
/* Parse all the entries */
for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) {
@@ -3125,10 +3128,12 @@ int git_index_read_tree(git_index *index, const git_tree *tree)
if ((error = git_tree_walk(tree, GIT_TREEWALK_POST, read_tree_cb, &data)) < 0)
goto cleanup;
- if (index->ignore_case)
- git_idxmap_icase_resize((git_idxmap_icase *) entries_map, entries.length);
- else
- git_idxmap_resize(entries_map, entries.length);
+ if (index->ignore_case &&
+ (error = git_idxmap_icase_resize((git_idxmap_icase *) entries_map,
+ entries.length)) < 0)
+ goto cleanup;
+ else if ((error = git_idxmap_resize(entries_map, entries.length)) < 0)
+ goto cleanup;
git_vector_foreach(&entries, i, e) {
INSERT_IN_MAP_EX(index, entries_map, e, error);
@@ -3185,10 +3190,13 @@ static int git_index_read_iterator(
(error = git_idxmap_new(&new_entries_map)) < 0)
goto done;
- if (index->ignore_case && new_length_hint)
- git_idxmap_icase_resize((git_idxmap_icase *) new_entries_map, new_length_hint);
- else if (new_length_hint)
- git_idxmap_resize(new_entries_map, new_length_hint);
+ if (index->ignore_case && new_length_hint &&
+ (error = git_idxmap_icase_resize((git_idxmap_icase *) new_entries_map,
+ new_length_hint)) < 0)
+ goto done;
+ else if (new_length_hint &&
+ (error = git_idxmap_resize(new_entries_map, new_length_hint)) < 0)
+ goto done;
opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE |
GIT_ITERATOR_INCLUDE_CONFLICTS;