Skip to content

Commit ac45d99

Browse files
ebiedermgitster
authored andcommitted
object-file-convert: don't leak when converting tag objects
Upon close examination I discovered that while brian's code to convert tag objects was functionally correct, it leaked memory. Rearrange the code so that all error checking happens before any memory is allocated. Add code to release the temporary strbufs the code uses. The code pretty much assumes the tag object ends with a newline, so add an explict test to verify that is the case. Signed-off-by: Eric W. Biederman <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c8762c3 commit ac45d99

File tree

1 file changed

+25
-20
lines changed

1 file changed

+25
-20
lines changed

object-file-convert.c

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -90,44 +90,49 @@ static int convert_tag_object(struct strbuf *out,
9090
const struct git_hash_algo *to,
9191
const char *buffer, size_t size)
9292
{
93-
struct strbuf payload = STRBUF_INIT, temp = STRBUF_INIT, oursig = STRBUF_INIT, othersig = STRBUF_INIT;
93+
struct strbuf payload = STRBUF_INIT, oursig = STRBUF_INIT, othersig = STRBUF_INIT;
94+
const int entry_len = from->hexsz + 7;
9495
size_t payload_size;
9596
struct object_id oid, mapped_oid;
9697
const char *p;
9798

98-
/* Add some slop for longer signature header in the new algorithm. */
99-
strbuf_grow(out, size + 7);
99+
/* Consume the object line */
100+
if ((entry_len >= size) ||
101+
memcmp(buffer, "object ", 7) || buffer[entry_len] != '\n')
102+
return error("bogus tag object");
103+
if (parse_oid_hex_algop(buffer + 7, &oid, &p, from) < 0)
104+
return error("bad tag object ID");
105+
if (repo_oid_to_algop(the_repository, &oid, to, &mapped_oid))
106+
return error("unable to map tree %s in tag object",
107+
oid_to_hex(&oid));
108+
size -= ((p + 1) - buffer);
109+
buffer = p + 1;
100110

101111
/* Is there a signature for our algorithm? */
102112
payload_size = parse_signed_buffer(buffer, size);
103-
strbuf_add(&payload, buffer, payload_size);
104113
if (payload_size != size) {
105114
/* Yes, there is. */
106115
strbuf_add(&oursig, buffer + payload_size, size - payload_size);
107116
}
108-
/* Now, is there a signature for the other algorithm? */
109-
if (parse_buffer_signed_by_header(payload.buf, payload.len, &temp, &othersig, to)) {
110-
/* Yes, there is. */
111-
strbuf_swap(&payload, &temp);
112-
strbuf_release(&temp);
113-
}
114117

118+
/* Now, is there a signature for the other algorithm? */
119+
parse_buffer_signed_by_header(buffer, payload_size, &payload, &othersig, to);
115120
/*
116121
* Our payload is now in payload and we may have up to two signatrures
117122
* in oursig and othersig.
118123
*/
119-
if (strncmp(payload.buf, "object ", 7) || payload.buf[from->hexsz + 7] != '\n')
120-
return error("bogus tag object");
121-
if (parse_oid_hex_algop(payload.buf + 7, &oid, &p, from) < 0)
122-
return error("bad tag object ID");
123-
if (repo_oid_to_algop(the_repository, &oid, to, &mapped_oid))
124-
return error("unable to map tree %s in tag object",
125-
oid_to_hex(&oid));
126-
strbuf_addf(out, "object %s", oid_to_hex(&mapped_oid));
127-
strbuf_add(out, p, payload.len - (p - payload.buf));
128-
strbuf_addbuf(out, &othersig);
124+
125+
/* Add some slop for longer signature header in the new algorithm. */
126+
strbuf_grow(out, (7 + to->hexsz + 1) + size + 7);
127+
strbuf_addf(out, "object %s\n", oid_to_hex(&mapped_oid));
128+
strbuf_addbuf(out, &payload);
129129
if (oursig.len)
130130
add_header_signature(out, &oursig, from);
131+
strbuf_addbuf(out, &othersig);
132+
133+
strbuf_release(&payload);
134+
strbuf_release(&othersig);
135+
strbuf_release(&oursig);
131136
return 0;
132137
}
133138

0 commit comments

Comments
 (0)