summaryrefslogtreecommitdiff
path: root/setup.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2007-08-02 15:10:56 -0700
committerJunio C Hamano <gitster@pobox.com>2007-08-02 17:26:26 -0700
commit6490a3383f1d0d96c122069e510ef1af1d019fbb (patch)
tree2f53fc4f0484afc619dea3b589d5eb9cdc228b4a /setup.c
parent29093c28a21d75500e9388ad103b9af9a0bab1ae (diff)
downloadgit-6490a3383f1d0d96c122069e510ef1af1d019fbb.tar.gz
Fix work-tree related breakages
In set_work_tree(), variable rel needs to be reinitialized to NULL on every call (it should not be static). Make sure the incoming dir variable is not too long before copying to the temporary buffer, and make sure chdir to the resulting directory succeeds. This was spotted and fixed by Alex and Johannes in a handful patch exchanges. Here is the final version. Signed-off-by: Junio C Hamano <gitster@pobox.com> Acked-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Diffstat (limited to 'setup.c')
-rw-r--r--setup.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/setup.c b/setup.c
index 3653092ab6..4945eb3134 100644
--- a/setup.c
+++ b/setup.c
@@ -201,26 +201,32 @@ int is_inside_work_tree(void)
*/
const char *set_work_tree(const char *dir)
{
- char dir_buffer[PATH_MAX];
- static char buffer[PATH_MAX + 1], *rel = NULL;
- int len, postfix_len = strlen(DEFAULT_GIT_DIR_ENVIRONMENT) + 1;
+ char dir_buffer[PATH_MAX], *rel = NULL;
+ static char buffer[PATH_MAX + 1];
+ int len, suffix_len = strlen(DEFAULT_GIT_DIR_ENVIRONMENT) + 1;
/* strip the variable 'dir' of the postfix "/.git" if it has it */
len = strlen(dir);
- if (len > postfix_len && !strcmp(dir + len - postfix_len,
- "/" DEFAULT_GIT_DIR_ENVIRONMENT)) {
- strncpy(dir_buffer, dir, len - postfix_len);
+ if (len > suffix_len &&
+ !strcmp(dir + len - suffix_len, "/" DEFAULT_GIT_DIR_ENVIRONMENT)) {
+ if ((len - suffix_len) >= sizeof(dir_buffer))
+ die("directory name too long");
+ memcpy(dir_buffer, dir, len - suffix_len);
+ dir_buffer[len - suffix_len] = '\0';
/* are we inside the default work tree? */
rel = get_relative_cwd(buffer, sizeof(buffer), dir_buffer);
}
+
/* if rel is set, the cwd is _not_ the current working tree */
if (rel && *rel) {
if (!is_absolute_path(dir))
set_git_dir(make_absolute_path(dir));
dir = dir_buffer;
- chdir(dir);
- strcat(rel, "/");
+ if (chdir(dir))
+ die("cannot chdir to %s: %s", dir, strerror(errno));
+ else
+ strcat(rel, "/");
inside_git_dir = 0;
} else {
rel = NULL;