static int inside_git_dir = -1;
static int inside_work_tree = -1;
+static int work_tree_config_is_bogus;
/*
* The input parameter must contain an absolute path, and it must already be
if (initialized)
return;
+
+ if (work_tree_config_is_bogus)
+ die("unable to set up work tree using invalid config");
+
work_tree = get_git_work_tree();
git_dir = get_git_dir();
if (!is_absolute_path(git_dir))
*/
const char *read_gitfile_gently(const char *path, int *return_error_code)
{
+ const int max_file_size = 1 << 20; /* 1MB */
int error_code = 0;
char *buf = NULL;
char *dir = NULL;
error_code = READ_GITFILE_ERR_NOT_A_FILE;
goto cleanup_return;
}
+ if (st.st_size > max_file_size) {
+ error_code = READ_GITFILE_ERR_TOO_LARGE;
+ goto cleanup_return;
+ }
fd = open(path, O_RDONLY);
if (fd < 0) {
error_code = READ_GITFILE_ERR_OPEN_FAILED;
path = real_path(dir);
cleanup_return:
- free(buf);
-
if (return_error_code)
*return_error_code = error_code;
-
- if (error_code) {
- if (return_error_code)
- return NULL;
-
+ else if (error_code) {
switch (error_code) {
case READ_GITFILE_ERR_STAT_FAILED:
case READ_GITFILE_ERR_NOT_A_FILE:
- return NULL;
+ /* non-fatal; follow return path */
+ break;
case READ_GITFILE_ERR_OPEN_FAILED:
die_errno("Error opening '%s'", path);
+ case READ_GITFILE_ERR_TOO_LARGE:
+ die("Too large to be a .git file: '%s'", path);
case READ_GITFILE_ERR_READ_FAILED:
die("Error reading %s", path);
case READ_GITFILE_ERR_INVALID_FORMAT:
}
}
- return path;
+ free(buf);
+ return error_code ? NULL : path;
}
static const char *setup_explicit_git_dir(const char *gitdirenv,
if (work_tree_env)
set_git_work_tree(work_tree_env);
else if (is_bare_repository_cfg > 0) {
- if (git_work_tree_cfg) /* #22.2, #30 */
- die("core.bare and core.worktree do not make sense");
+ if (git_work_tree_cfg) {
+ /* #22.2, #30 */
+ warning("core.bare and core.worktree do not make sense");
+ work_tree_config_is_bogus = 1;
+ }
/* #18, #26 */
set_git_dir(gitdirenv);