Commit ec50b23acc5a9f00f597fa877ad09cad56cb1204

Edward Thomson 2015-11-03T17:02:07

filebuf: detect directories in our way When creating a filebuf, detect a directory that exists in our target file location. This prevents a failure later, when we try to move the lock file to the destination.

diff --git a/src/filebuf.c b/src/filebuf.c
index 2bbc210..17efe87 100644
--- a/src/filebuf.c
+++ b/src/filebuf.c
@@ -357,6 +357,12 @@ int git_filebuf_open(git_filebuf *file, const char *path, int flags, mode_t mode
 		memcpy(file->path_lock, file->path_original, path_len);
 		memcpy(file->path_lock + path_len, GIT_FILELOCK_EXTENSION, GIT_FILELOCK_EXTLENGTH);
 
+		if (git_path_isdir(file->path_original)) {
+			giterr_set(GITERR_FILESYSTEM, "path '%s' is a directory", file->path_original);
+			error = GIT_EDIRECTORY;
+			goto cleanup;
+		}
+
 		/* open the file for locking */
 		if ((error = lock_file(file, flags, mode)) < 0)
 			goto cleanup;
diff --git a/tests/core/filebuf.c b/tests/core/filebuf.c
index 915e3cc..93aaed7 100644
--- a/tests/core/filebuf.c
+++ b/tests/core/filebuf.c
@@ -230,3 +230,12 @@ void test_core_filebuf__hidden_file(void)
 	git_filebuf_cleanup(&file);
 #endif
 }
+
+void test_core_filebuf__detects_directory(void)
+{
+	git_filebuf file = GIT_FILEBUF_INIT, fail = GIT_FILEBUF_INIT;
+
+	cl_must_pass(p_mkdir("foo", 0777));
+	cl_git_fail_with(GIT_EDIRECTORY, git_filebuf_open(&file, "foo", 0, 0666));
+	cl_must_pass(p_rmdir("foo"));
+}