From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>, "Jeff King" <peff@peff.net>,
"Johannes Schindelin" <Johannes.Schindelin@gmx.de>,
"Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 1/2] config: check if config path is a file before parsing it
Date: Fri, 3 Mar 2017 16:42:51 +0700 [thread overview]
Message-ID: <20170303094252.11706-2-pclouds@gmail.com> (raw)
In-Reply-To: <20170303094252.11706-1-pclouds@gmail.com>
If a directory is given as a config file by accident, we keep open it
as a file. The behavior of fopen() in this case seems to be
undefined.
On Linux, we open a directory as a file ok, then get error (which we
consider eof) on the first read. So the config parser sees this "file"
as empty (i.e. valid config). All is well and we don't complain
anything (but we should).
The situation is slighly different on Windows. I think fopen() returns
NULL. And we get a very unhelpful message:
$ cat >abc <<EOF
[include]
path = /tmp/foo
EOF
$ mkdir /tmp/foo
$ git config --includes --file=abc core.bare
fatal: bad config line 3 in file abc
Opening a directory is wrong in the first place. Avoid it. If caught,
print something better. With this patch, we have
$ git config --includes --file=abc core.bare
error: '/tmp/foo' is not a file
fatal: bad config line 3 in file abc
It's not perfect (line should be 2 instead of 3). But it's definitely
improving.
The new test is only relevant on linux where we blindly open the
directory and consider it an empty file. On Windows, the test should
pass even without this patch.
---
abspath.c | 7 +++++++
cache.h | 1 +
config.c | 9 +++++++++
t/t1300-repo-config.sh | 5 +++++
4 files changed, 22 insertions(+)
diff --git a/abspath.c b/abspath.c
index 2f0c26e0e2..373cc3abb2 100644
--- a/abspath.c
+++ b/abspath.c
@@ -11,6 +11,13 @@ int is_directory(const char *path)
return (!stat(path, &st) && S_ISDIR(st.st_mode));
}
+int is_not_file(const char *path)
+{
+ struct stat st;
+
+ return !stat(path, &st) && !S_ISREG(st.st_mode);
+}
+
/* removes the last path component from 'path' except if 'path' is root */
static void strip_last_component(struct strbuf *path)
{
diff --git a/cache.h b/cache.h
index 80b6372cf7..bdd1402ab9 100644
--- a/cache.h
+++ b/cache.h
@@ -1149,6 +1149,7 @@ static inline int is_absolute_path(const char *path)
return is_dir_sep(path[0]) || has_dos_drive_prefix(path);
}
int is_directory(const char *);
+int is_not_file(const char *);
char *strbuf_realpath(struct strbuf *resolved, const char *path,
int die_on_error);
const char *real_path(const char *path);
diff --git a/config.c b/config.c
index c6b874a7bf..c21c0ce433 100644
--- a/config.c
+++ b/config.c
@@ -13,6 +13,7 @@
#include "hashmap.h"
#include "string-list.h"
#include "utf8.h"
+#include "dir.h"
struct config_source {
struct config_source *prev;
@@ -1212,6 +1213,9 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
int ret = -1;
FILE *f;
+ if (is_not_file(filename))
+ return error(_("'%s' is not a file"), filename);
+
f = fopen(filename, "r");
if (f) {
flockfile(f);
@@ -2451,6 +2455,11 @@ int git_config_rename_section_in_file(const char *config_filename,
goto out;
}
+ if (!S_ISREG(st.st_mode)) {
+ ret = error(_("'%s' is not a file"), config_filename);
+ goto out;
+ }
+
if (chmod(get_lock_file_path(lock), st.st_mode & 07777) < 0) {
ret = error_errno("chmod on %s failed",
get_lock_file_path(lock));
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 052f120216..3683fbb84e 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -1477,4 +1477,9 @@ test_expect_success !MINGW '--show-origin blob ref' '
test_cmp expect output
'
+test_expect_success 'a directory is given as a config file' '
+ mkdir config-dir &&
+ test_must_fail git config --file=config-dir --list
+'
+
test_done
--
2.11.0.157.gd943d85
next prev parent reply other threads:[~2017-03-03 9:52 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-03 9:42 [PATCH 0/2] Improve error messages when opening a directory as file Nguyễn Thái Ngọc Duy
2017-03-03 9:42 ` Nguyễn Thái Ngọc Duy [this message]
2017-03-03 9:53 ` [PATCH 1/2] config: check if config path is a file before parsing it Jeff King
2017-03-03 10:06 ` Duy Nguyen
2017-03-03 10:15 ` Jeff King
2017-03-03 10:29 ` Duy Nguyen
2017-03-03 10:33 ` Jeff King
2017-03-03 10:31 ` Jeff King
2017-03-03 21:05 ` Junio C Hamano
2017-03-03 20:21 ` Ramsay Jones
2017-03-03 9:42 ` [PATCH 2/2] attr.c: check if .gitattributes " Nguyễn Thái Ngọc Duy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170303094252.11706-2-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).