Skip to content

Commit 1410962

Browse files
committed
odb: improve error handling in read_prefix_1
The read_prefix_1 function has several return statements springled throughout the code. As we have to free memory upon getting an error, the free code has to be repeated at every single retrun -- which it is not, so we have a memory leak here. Refactor the code to use the typical `goto out` pattern, which will free data when an error has occurred. While we're at it, we can also improve the error message thrown when multiple ambiguous prefixes are found. It will now include the colliding prefixes.
1 parent 35079f5 commit 1410962

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

src/odb.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,9 +1099,9 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
10991099
const git_oid *key, size_t len, bool only_refreshed)
11001100
{
11011101
size_t i;
1102-
int error = GIT_ENOTFOUND;
1102+
int error;
11031103
git_oid found_full_oid = {{0}};
1104-
git_rawobj raw;
1104+
git_rawobj raw = {0};
11051105
void *data = NULL;
11061106
bool found = false;
11071107
git_odb_object *object;
@@ -1120,14 +1120,22 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
11201120
continue;
11211121

11221122
if (error)
1123-
return error;
1123+
goto out;
11241124

11251125
git__free(data);
11261126
data = raw.data;
11271127

11281128
if (found && git_oid__cmp(&full_oid, &found_full_oid)) {
1129-
git__free(raw.data);
1130-
return git_odb__error_ambiguous("multiple matches for prefix");
1129+
git_buf buf = GIT_BUF_INIT;
1130+
1131+
git_buf_printf(&buf, "multiple matches for prefix: %s",
1132+
git_oid_tostr_s(&full_oid));
1133+
git_buf_printf(&buf, " %s",
1134+
git_oid_tostr_s(&found_full_oid));
1135+
1136+
error = git_odb__error_ambiguous(buf.ptr);
1137+
git_buf_free(&buf);
1138+
goto out;
11311139
}
11321140

11331141
found_full_oid = full_oid;
@@ -1139,10 +1147,15 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
11391147
return GIT_ENOTFOUND;
11401148

11411149
if ((object = odb_object__alloc(&found_full_oid, &raw)) == NULL)
1142-
return -1;
1150+
goto out;
11431151

11441152
*out = git_cache_store_raw(odb_cache(db), object);
1145-
return 0;
1153+
1154+
out:
1155+
if (error)
1156+
git__free(raw.data);
1157+
1158+
return error;
11461159
}
11471160

11481161
int git_odb_read_prefix(

0 commit comments

Comments
 (0)