On Tue, Sep 15, 2015 at 11:47 AM, Jeff King <[email protected]> wrote:
> When we want to convert "foo.pack" to "foo.idx", we do it by
> duplicating the original string and then munging the bytes
> in place. Let's use strip_suffix and xstrfmt instead, which
> has several advantages:
>
> 1. It's more clear what the intent is.
>
> 2. It does not implicitly rely on the fact that
> strlen(".idx") <= strlen(".pack") to avoid an overflow.
>
> 3. We communicate the assumption that the input file ends
> with ".pack" (and get a run-time check that this is so).
>
> 4. We drop calls to strcpy, which makes auditing the code
> base easier.
>
> Likewise, we can do this to convert ".pack" to ".bitmap",
> avoiding some manual memory computation.
>
> Signed-off-by: Jeff King <[email protected]>
> ---
> diff --git a/http.c b/http.c
> index 7b02259..e0ff876 100644
> --- a/http.c
> +++ b/http.c
> @@ -1511,6 +1511,7 @@ int finish_http_pack_request(struct http_pack_request
> *preq)
> struct packed_git **lst;
> struct packed_git *p = preq->target;
> char *tmp_idx;
> + size_t len;
> struct child_process ip = CHILD_PROCESS_INIT;
> const char *ip_argv[8];
>
> @@ -1524,9 +1525,9 @@ int finish_http_pack_request(struct http_pack_request
> *preq)
> lst = &((*lst)->next);
> *lst = (*lst)->next;
>
> - tmp_idx = xstrdup(preq->tmpfile);
> - strcpy(tmp_idx + strlen(tmp_idx) - strlen(".pack.temp"),
> - ".idx.temp");
> + if (!strip_suffix(preq->tmpfile, ".pack.temp", &len))
> + die("BUG: pack tmpfile does not end in .pack.temp?");
> + tmp_idx = xstrfmt("%.*s.idx.temp", (int)len, preq->tmpfile);
These instances of repeated replacement code may argue in favor of a
general purpose replace_suffix() function:
char *replace_suffix(const char *s, const char *old, const char *new)
{
size_t n;
if (!strip_suffix(s, old, &n))
die("BUG: '%s' does not end with '%s', s, old);
return xstrfmt("%.*s%s", (int)n, s, new);
}
or something.
> ip_argv[0] = "index-pack";
> ip_argv[1] = "-o";
> diff --git a/pack-bitmap.c b/pack-bitmap.c
> index 637770a..7dfcb34 100644
> --- a/pack-bitmap.c
> +++ b/pack-bitmap.c
> @@ -252,16 +252,11 @@ static int load_bitmap_entries_v1(struct bitmap_index
> *index)
>
> static char *pack_bitmap_filename(struct packed_git *p)
> {
> - char *idx_name;
> - int len;
> -
> - len = strlen(p->pack_name) - strlen(".pack");
> - idx_name = xmalloc(len + strlen(".bitmap") + 1);
> -
> - memcpy(idx_name, p->pack_name, len);
> - memcpy(idx_name + len, ".bitmap", strlen(".bitmap") + 1);
> + size_t len;
>
> - return idx_name;
> + if (!strip_suffix(p->pack_name, ".pack", &len))
> + die("BUG: pack_name does not end in .pack");
> + return xstrfmt("%.*s.bitmap", (int)len, p->pack_name);
> }
>
> static int open_pack_bitmap_1(struct packed_git *packfile)
> diff --git a/sha1_file.c b/sha1_file.c
> index 28352a5..88996f0 100644
> --- a/sha1_file.c
> +++ b/sha1_file.c
> @@ -671,13 +671,15 @@ static int check_packed_git_idx(const char *path,
> struct packed_git *p)
> int open_pack_index(struct packed_git *p)
> {
> char *idx_name;
> + size_t len;
> int ret;
>
> if (p->index_data)
> return 0;
>
> - idx_name = xstrdup(p->pack_name);
> - strcpy(idx_name + strlen(idx_name) - strlen(".pack"), ".idx");
> + if (!strip_suffix(p->pack_name, ".pack", &len))
> + die("BUG: pack_name does not end in .pack");
> + idx_name = xstrfmt("%.*s.idx", (int)len, p->pack_name);
> ret = check_packed_git_idx(idx_name, p);
> free(idx_name);
> return ret;
> --
> 2.6.0.rc2.408.ga2926b9
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html