summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin-add.c12
-rw-r--r--builtin-update-index.c5
-rw-r--r--dir.c6
-rwxr-xr-xt/t0055-beyond-symlinks.sh25
4 files changed, 45 insertions, 3 deletions
diff --git a/builtin-add.c b/builtin-add.c
index fc3f96eaef..81b64d7b9d 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -153,6 +153,16 @@ static const char **validate_pathspec(int argc, const char **argv, const char *p
{
const char **pathspec = get_pathspec(prefix, argv);
+ if (pathspec) {
+ const char **p;
+ for (p = pathspec; *p; p++) {
+ if (has_symlink_leading_path(strlen(*p), *p)) {
+ int len = prefix ? strlen(prefix) : 0;
+ die("'%s' is beyond a symbolic link", *p + len);
+ }
+ }
+ }
+
return pathspec;
}
@@ -278,7 +288,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
fprintf(stderr, "Maybe you wanted to say 'git add .'?\n");
return 0;
}
- pathspec = get_pathspec(prefix, argv);
+ pathspec = validate_pathspec(argc, argv, prefix);
/*
* If we are adding new files, we need to scan the working
diff --git a/builtin-update-index.c b/builtin-update-index.c
index 38eb53ccba..434cb8e4a0 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -194,6 +194,10 @@ static int process_path(const char *path)
int len;
struct stat st;
+ len = strlen(path);
+ if (has_symlink_leading_path(len, path))
+ return error("'%s' is beyond a symbolic link", path);
+
/*
* First things first: get the stat information, to decide
* what to do about the pathname!
@@ -201,7 +205,6 @@ static int process_path(const char *path)
if (lstat(path, &st) < 0)
return process_lstat_error(path, errno);
- len = strlen(path);
if (S_ISDIR(st.st_mode))
return process_directory(path, len, &st);
diff --git a/dir.c b/dir.c
index 109e05b013..92452eb5ef 100644
--- a/dir.c
+++ b/dir.c
@@ -727,8 +727,12 @@ static void free_simplify(struct path_simplify *simplify)
int read_directory(struct dir_struct *dir, const char *path, const char *base, int baselen, const char **pathspec)
{
- struct path_simplify *simplify = create_simplify(pathspec);
+ struct path_simplify *simplify;
+ if (has_symlink_leading_path(strlen(path), path))
+ return dir->nr;
+
+ simplify = create_simplify(pathspec);
read_directory_recursive(dir, path, base, baselen, 0, simplify);
free_simplify(simplify);
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
diff --git a/t/t0055-beyond-symlinks.sh b/t/t0055-beyond-symlinks.sh
new file mode 100755
index 0000000000..b29c37a5a4
--- /dev/null
+++ b/t/t0055-beyond-symlinks.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+test_description='update-index and add refuse to add beyond symlinks'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ >a &&
+ mkdir b &&
+ ln -s b c &&
+ >c/d &&
+ git update-index --add a b/d
+'
+
+test_expect_success 'update-index --add beyond symlinks' '
+ test_must_fail git update-index --add c/d &&
+ ! ( git ls-files | grep c/d )
+'
+
+test_expect_success 'add beyond symlinks' '
+ test_must_fail git add c/d &&
+ ! ( git ls-files | grep c/d )
+'
+
+test_done