Skip to content

Commit 6490a33

Browse files
committed
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>
1 parent 29093c2 commit 6490a33

File tree

1 file changed

+14
-8
lines changed

1 file changed

+14
-8
lines changed

setup.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -201,26 +201,32 @@ int is_inside_work_tree(void)
201201
*/
202202
const char *set_work_tree(const char *dir)
203203
{
204-
char dir_buffer[PATH_MAX];
205-
static char buffer[PATH_MAX + 1], *rel = NULL;
206-
int len, postfix_len = strlen(DEFAULT_GIT_DIR_ENVIRONMENT) + 1;
204+
char dir_buffer[PATH_MAX], *rel = NULL;
205+
static char buffer[PATH_MAX + 1];
206+
int len, suffix_len = strlen(DEFAULT_GIT_DIR_ENVIRONMENT) + 1;
207207

208208
/* strip the variable 'dir' of the postfix "/.git" if it has it */
209209
len = strlen(dir);
210-
if (len > postfix_len && !strcmp(dir + len - postfix_len,
211-
"/" DEFAULT_GIT_DIR_ENVIRONMENT)) {
212-
strncpy(dir_buffer, dir, len - postfix_len);
210+
if (len > suffix_len &&
211+
!strcmp(dir + len - suffix_len, "/" DEFAULT_GIT_DIR_ENVIRONMENT)) {
212+
if ((len - suffix_len) >= sizeof(dir_buffer))
213+
die("directory name too long");
214+
memcpy(dir_buffer, dir, len - suffix_len);
215+
dir_buffer[len - suffix_len] = '\0';
213216

214217
/* are we inside the default work tree? */
215218
rel = get_relative_cwd(buffer, sizeof(buffer), dir_buffer);
216219
}
220+
217221
/* if rel is set, the cwd is _not_ the current working tree */
218222
if (rel && *rel) {
219223
if (!is_absolute_path(dir))
220224
set_git_dir(make_absolute_path(dir));
221225
dir = dir_buffer;
222-
chdir(dir);
223-
strcat(rel, "/");
226+
if (chdir(dir))
227+
die("cannot chdir to %s: %s", dir, strerror(errno));
228+
else
229+
strcat(rel, "/");
224230
inside_git_dir = 0;
225231
} else {
226232
rel = NULL;

0 commit comments

Comments
 (0)