add_packed_git: convert strcpy into xsnprintf
We have the path "foo.idx", and we create a buffer big
enough to hold "foo.pack" and "foo.keep", and then strcpy
straight into it. This isn't a bug (we have enough space),
but it's very hard to tell from the strcpy that this is so.
Let's instead use strip_suffix to take off the ".idx",
record the size of our allocation, and use xsnprintf to make
sure we don't violate our assumptions.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff --git a/sha1_file.c b/sha1_file.c
index f106091..592226e 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1146,11 +1146,12 @@
release_pack_memory(size);
}
-struct packed_git *add_packed_git(const char *path, int path_len, int local)
+struct packed_git *add_packed_git(const char *path, size_t path_len, int local)
{
static int have_set_try_to_free_routine;
struct stat st;
- struct packed_git *p = alloc_packed_git(path_len + 2);
+ size_t alloc;
+ struct packed_git *p;
if (!have_set_try_to_free_routine) {
have_set_try_to_free_routine = 1;
@@ -1161,18 +1162,22 @@
* Make sure a corresponding .pack file exists and that
* the index looks sane.
*/
- path_len -= strlen(".idx");
- if (path_len < 1) {
- free(p);
+ if (!strip_suffix_mem(path, &path_len, ".idx"))
return NULL;
- }
+
+ /*
+ * ".pack" is long enough to hold any suffix we're adding (and
+ * the use xsnprintf double-checks that)
+ */
+ alloc = path_len + strlen(".pack") + 1;
+ p = alloc_packed_git(alloc);
memcpy(p->pack_name, path, path_len);
- strcpy(p->pack_name + path_len, ".keep");
+ xsnprintf(p->pack_name + path_len, alloc - path_len, ".keep");
if (!access(p->pack_name, F_OK))
p->pack_keep = 1;
- strcpy(p->pack_name + path_len, ".pack");
+ xsnprintf(p->pack_name + path_len, alloc - path_len, ".pack");
if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) {
free(p);
return NULL;