git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] Handle the errors from chdir in set_work_tree

From
Junio C Hamano <gitster@pobox.com>
Date
Aug 2, 2007, 21:58 UTC
Message-ID
<7v8x8ttx7y.fsf@assigned-by-dhcp.cox.net>
In-Reply-To
<81b0412b0708020827p174515b7tc05fefde77f7d7c4@mail.gmail.com>
"Alex Riesen" <raa.lkml@gmail.com> writes:
Show 15 quoted lines
> These I haven't seen yet. Wouldn't like such a surprise though.
> ...
> @@ -220,8 +220,10 @@ const char *set_work_tree(const char *dir)
>  		if (!is_absolute_path(dir))
>  			set_git_dir(make_absolute_path(dir));
>  		dir = dir_buffer;
> -		chdir(dir);
> -		strcat(rel, "/");
> +		if (chdir(dir))
> +			rel = NULL;
> +		else
> +			strcat(rel, "/");
>  		inside_git_dir = 0;
>  	} else {
>  		rel = NULL;
Shouldn't it die() instead, though?
Consolidating two of your patches, would this be Ok?

-- >8 -- 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.

---
 setup.c |   22 ++++++++++++++--------
 1 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/setup.c b/setup.c
index 3653092..4945eb3 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;
Previous: Johannes SchindelinNext: Johannes Schindelin
Message 3 of 6 in “Handle the errors from chdir in set_work_tree”
  1. Handle the errors from chdir in set_work_treeAlex Riesen, Aug 2, 2007
  2. Johannes SchindelinAug 2, 2007
  3. Junio C HamanoAug 2, 2007
  4. Johannes SchindelinAug 2, 2007
  5. Alex RiesenAug 2, 2007
  6. Junio C HamanoAug 2, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.