summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2013-10-24 08:55:35 +0700
committerJunio C Hamano <gitster@pobox.com>2013-10-24 14:58:37 -0700
commitfd356f6aa8bb75ebef56fbc61caf7e02517fa6d3 (patch)
treee2851336dfb92b96bad2201baf9131f64c4704be
parent5f737ac91bd869e65bff401ad1108581ac504e22 (diff)
downloadgit-fd356f6aa8bb75ebef56fbc61caf7e02517fa6d3.tar.gz
entry.c: convert checkout_entry to use strbuf
The old code does not do boundary check so any paths longer than PATH_MAX can cause buffer overflow. Replace it with strbuf to handle paths of arbitrary length. The OS may reject if the path is too long though. But in that case we report the cause (e.g. name too long) and usually move on to checking out the next entry. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--entry.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/entry.c b/entry.c
index acc892f9a6..fbb4863103 100644
--- a/entry.c
+++ b/entry.c
@@ -237,16 +237,19 @@ static int check_path(const char *path, int len, struct stat *st, int skiplen)
int checkout_entry(struct cache_entry *ce,
const struct checkout *state, char *topath)
{
- static char path[PATH_MAX + 1];
+ static struct strbuf path_buf = STRBUF_INIT;
+ char *path;
struct stat st;
- int len = state->base_dir_len;
+ int len;
if (topath)
return write_entry(ce, topath, state, 1);
- memcpy(path, state->base_dir, len);
- strcpy(path + len, ce->name);
- len += ce_namelen(ce);
+ strbuf_reset(&path_buf);
+ strbuf_add(&path_buf, state->base_dir, state->base_dir_len);
+ strbuf_add(&path_buf, ce->name, ce_namelen(ce));
+ path = path_buf.buf;
+ len = path_buf.len;
if (!check_path(path, len, &st, state->base_dir_len)) {
unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);