summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2019-12-04 21:21:20 (GMT)
committerJohannes Schindelin <johannes.schindelin@gmx.de>2019-12-06 15:29:15 (GMT)
commit14af7ed5a9c9c0ff2ea347bf54ed2af4b0e10cc2 (patch)
treed8127060ce208c40c4f5dd67a412171154e362c6 /t
parent268fbcd172cdb306e8a3e7143cc16677c963d6cd (diff)
parenta5ab8d03173458b76b8452efd90a7173f490c132 (diff)
downloadgit-14af7ed5a9c9c0ff2ea347bf54ed2af4b0e10cc2.zip
git-14af7ed5a9c9c0ff2ea347bf54ed2af4b0e10cc2.tar.gz
git-14af7ed5a9c9c0ff2ea347bf54ed2af4b0e10cc2.tar.bz2
Sync with 2.17.3
* maint-2.17: (32 commits) Git 2.17.3 Git 2.16.6 test-drop-caches: use `has_dos_drive_prefix()` Git 2.15.4 Git 2.14.6 mingw: handle `subst`-ed "DOS drives" mingw: refuse to access paths with trailing spaces or periods mingw: refuse to access paths with illegal characters unpack-trees: let merged_entry() pass through do_add_entry()'s errors quote-stress-test: offer to test quoting arguments for MSYS2 sh t6130/t9350: prepare for stringent Win32 path validation quote-stress-test: allow skipping some trials quote-stress-test: accept arguments to test via the command-line tests: add a helper to stress test argument quoting mingw: fix quoting of arguments Disallow dubiously-nested submodule git directories protect_ntfs: turn on NTFS protection by default path: also guard `.gitmodules` against NTFS Alternate Data Streams is_ntfs_dotgit(): speed it up mingw: disallow backslash characters in tree objects' file names ...
Diffstat (limited to 't')
-rw-r--r--t/helper/test-drop-caches.c13
-rw-r--r--t/helper/test-path-utils.c113
-rw-r--r--t/helper/test-run-command.c138
-rwxr-xr-xt/t0060-path-utils.sh32
-rwxr-xr-xt/t1014-read-tree-confusing.sh1
-rwxr-xr-xt/t1450-fsck.sh1
-rwxr-xr-xt/t6130-pathspec-noglob.sh1
-rwxr-xr-xt/t7406-submodule-update.sh28
-rwxr-xr-xt/t7415-submodule-names.sh56
-rwxr-xr-xt/t7416-submodule-dash-url.sh14
-rwxr-xr-xt/t7417-submodule-path-url.sh17
-rwxr-xr-xt/t9300-fast-import.sh58
-rwxr-xr-xt/t9350-fast-export.sh3
13 files changed, 446 insertions, 29 deletions
diff --git a/t/helper/test-drop-caches.c b/t/helper/test-drop-caches.c
index d6bcfdd..7b42784 100644
--- a/t/helper/test-drop-caches.c
+++ b/t/helper/test-drop-caches.c
@@ -8,18 +8,21 @@ static int cmd_sync(void)
{
char Buffer[MAX_PATH];
DWORD dwRet;
- char szVolumeAccessPath[] = "\\\\.\\X:";
+ char szVolumeAccessPath[] = "\\\\.\\XXXX:";
HANDLE hVolWrite;
- int success = 0;
+ int success = 0, dos_drive_prefix;
dwRet = GetCurrentDirectory(MAX_PATH, Buffer);
if ((0 == dwRet) || (dwRet > MAX_PATH))
return error("Error getting current directory");
- if ((Buffer[0] < 'A') || (Buffer[0] > 'Z'))
- return error("Invalid drive letter '%c'", Buffer[0]);
+ dos_drive_prefix = has_dos_drive_prefix(Buffer);
+ if (!dos_drive_prefix)
+ return error("'%s': invalid drive letter", Buffer);
+
+ memcpy(szVolumeAccessPath, Buffer, dos_drive_prefix);
+ szVolumeAccessPath[dos_drive_prefix] = '\0';
- szVolumeAccessPath[4] = Buffer[0];
hVolWrite = CreateFile(szVolumeAccessPath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (INVALID_HANDLE_VALUE == hVolWrite)
diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c
index ae091d9..e737a94 100644
--- a/t/helper/test-path-utils.c
+++ b/t/helper/test-path-utils.c
@@ -177,6 +177,99 @@ static int is_dotgitmodules(const char *path)
return is_hfs_dotgitmodules(path) || is_ntfs_dotgitmodules(path);
}
+/*
+ * A very simple, reproducible pseudo-random generator. Copied from
+ * `test-genrandom.c`.
+ */
+static uint64_t my_random_value = 1234;
+
+static uint64_t my_random(void)
+{
+ my_random_value = my_random_value * 1103515245 + 12345;
+ return my_random_value;
+}
+
+/*
+ * A fast approximation of the square root, without requiring math.h.
+ *
+ * It uses Newton's method to approximate the solution of 0 = x^2 - value.
+ */
+static double my_sqrt(double value)
+{
+ const double epsilon = 1e-6;
+ double x = value;
+
+ if (value == 0)
+ return 0;
+
+ for (;;) {
+ double delta = (value / x - x) / 2;
+ if (delta < epsilon && delta > -epsilon)
+ return x + delta;
+ x += delta;
+ }
+}
+
+static int protect_ntfs_hfs_benchmark(int argc, const char **argv)
+{
+ size_t i, j, nr, min_len = 3, max_len = 20;
+ char **names;
+ int repetitions = 15, file_mode = 0100644;
+ uint64_t begin, end;
+ double m[3][2], v[3][2];
+ uint64_t cumul;
+ double cumul2;
+
+ if (argc > 1 && !strcmp(argv[1], "--with-symlink-mode")) {
+ file_mode = 0120000;
+ argc--;
+ argv++;
+ }
+
+ nr = argc > 1 ? strtoul(argv[1], NULL, 0) : 1000000;
+ ALLOC_ARRAY(names, nr);
+
+ if (argc > 2) {
+ min_len = strtoul(argv[2], NULL, 0);
+ if (argc > 3)
+ max_len = strtoul(argv[3], NULL, 0);
+ if (min_len > max_len)
+ die("min_len > max_len");
+ }
+
+ for (i = 0; i < nr; i++) {
+ size_t len = min_len + (my_random() % (max_len + 1 - min_len));
+
+ names[i] = xmallocz(len);
+ while (len > 0)
+ names[i][--len] = (char)(' ' + (my_random() % ('\x7f' - ' ')));
+ }
+
+ for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++)
+ for (protect_hfs = 0; protect_hfs < 2; protect_hfs++) {
+ cumul = 0;
+ cumul2 = 0;
+ for (i = 0; i < repetitions; i++) {
+ begin = getnanotime();
+ for (j = 0; j < nr; j++)
+ verify_path(names[j], file_mode);
+ end = getnanotime();
+ printf("protect_ntfs = %d, protect_hfs = %d: %lfms\n", protect_ntfs, protect_hfs, (end-begin) / (double)1e6);
+ cumul += end - begin;
+ cumul2 += (end - begin) * (end - begin);
+ }
+ m[protect_ntfs][protect_hfs] = cumul / (double)repetitions;
+ v[protect_ntfs][protect_hfs] = my_sqrt(cumul2 / (double)repetitions - m[protect_ntfs][protect_hfs] * m[protect_ntfs][protect_hfs]);
+ printf("mean: %lfms, stddev: %lfms\n", m[protect_ntfs][protect_hfs] / (double)1e6, v[protect_ntfs][protect_hfs] / (double)1e6);
+ }
+
+ for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++)
+ for (protect_hfs = 0; protect_hfs < 2; protect_hfs++)
+ printf("ntfs=%d/hfs=%d: %lf%% slower\n", protect_ntfs, protect_hfs, (m[protect_ntfs][protect_hfs] - m[0][0]) * 100 / m[0][0]);
+
+ return 0;
+}
+
int cmd__path_utils(int argc, const char **argv)
{
if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
@@ -291,6 +384,26 @@ int cmd__path_utils(int argc, const char **argv)
return !!res;
}
+ if (argc > 1 && !strcmp(argv[1], "protect_ntfs_hfs"))
+ return !!protect_ntfs_hfs_benchmark(argc - 1, argv + 1);
+
+ if (argc > 1 && !strcmp(argv[1], "is_valid_path")) {
+ int res = 0, expect = 1, i;
+
+ for (i = 2; i < argc; i++)
+ if (!strcmp("--not", argv[i]))
+ expect = 0;
+ else if (expect != is_valid_path(argv[i]))
+ res = error("'%s' is%s a valid path",
+ argv[i], expect ? " not" : "");
+ else
+ fprintf(stderr,
+ "'%s' is%s a valid path\n",
+ argv[i], expect ? "" : " not");
+
+ return !!res;
+ }
+
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
argv[1] ? argv[1] : "(there was none)");
return 1;
diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c
index 2cc93bb..8579b1f 100644
--- a/t/helper/test-run-command.c
+++ b/t/helper/test-run-command.c
@@ -13,8 +13,8 @@
#include "run-command.h"
#include "argv-array.h"
#include "strbuf.h"
-#include <string.h>
-#include <errno.h>
+#include "gettext.h"
+#include "parse-options.h"
static int number_callbacks;
static int parallel_next(struct child_process *cp,
@@ -50,11 +50,145 @@ static int task_finished(int result,
return 1;
}
+static uint64_t my_random_next = 1234;
+
+static uint64_t my_random(void)
+{
+ uint64_t res = my_random_next;
+ my_random_next = my_random_next * 1103515245 + 12345;
+ return res;
+}
+
+static int quote_stress_test(int argc, const char **argv)
+{
+ /*
+ * We are running a quote-stress test.
+ * spawn a subprocess that runs quote-stress with a
+ * special option that echoes back the arguments that
+ * were passed in.
+ */
+ char special[] = ".?*\\^_\"'`{}()[]<>@~&+:;$%"; // \t\r\n\a";
+ int i, j, k, trials = 100, skip = 0, msys2 = 0;
+ struct strbuf out = STRBUF_INIT;
+ struct argv_array args = ARGV_ARRAY_INIT;
+ struct option options[] = {
+ OPT_INTEGER('n', "trials", &trials, "Number of trials"),
+ OPT_INTEGER('s', "skip", &skip, "Skip <n> trials"),
+ OPT_BOOL('m', "msys2", &msys2, "Test quoting for MSYS2's sh"),
+ OPT_END()
+ };
+ const char * const usage[] = {
+ "test-tool run-command quote-stress-test <options>",
+ NULL
+ };
+
+ argc = parse_options(argc, argv, NULL, options, usage, 0);
+
+ setenv("MSYS_NO_PATHCONV", "1", 0);
+
+ for (i = 0; i < trials; i++) {
+ struct child_process cp = CHILD_PROCESS_INIT;
+ size_t arg_count, arg_offset;
+ int ret = 0;
+
+ argv_array_clear(&args);
+ if (msys2)
+ argv_array_pushl(&args, "sh", "-c",
+ "printf %s\\\\0 \"$@\"", "skip", NULL);
+ else
+ argv_array_pushl(&args, "test-tool", "run-command",
+ "quote-echo", NULL);
+ arg_offset = args.argc;
+
+ if (argc > 0) {
+ trials = 1;
+ arg_count = argc;
+ for (j = 0; j < arg_count; j++)
+ argv_array_push(&args, argv[j]);
+ } else {
+ arg_count = 1 + (my_random() % 5);
+ for (j = 0; j < arg_count; j++) {
+ char buf[20];
+ size_t min_len = 1;
+ size_t arg_len = min_len +
+ (my_random() % (ARRAY_SIZE(buf) - min_len));
+
+ for (k = 0; k < arg_len; k++)
+ buf[k] = special[my_random() %
+ ARRAY_SIZE(special)];
+ buf[arg_len] = '\0';
+
+ argv_array_push(&args, buf);
+ }
+ }
+
+ if (i < skip)
+ continue;
+
+ cp.argv = args.argv;
+ strbuf_reset(&out);
+ if (pipe_command(&cp, NULL, 0, &out, 0, NULL, 0) < 0)
+ return error("Failed to spawn child process");
+
+ for (j = 0, k = 0; j < arg_count; j++) {
+ const char *arg = args.argv[j + arg_offset];
+
+ if (strcmp(arg, out.buf + k))
+ ret = error("incorrectly quoted arg: '%s', "
+ "echoed back as '%s'",
+ arg, out.buf + k);
+ k += strlen(out.buf + k) + 1;
+ }
+
+ if (k != out.len)
+ ret = error("got %d bytes, but consumed only %d",
+ (int)out.len, (int)k);
+
+ if (ret) {
+ fprintf(stderr, "Trial #%d failed. Arguments:\n", i);
+ for (j = 0; j < arg_count; j++)
+ fprintf(stderr, "arg #%d: '%s'\n",
+ (int)j, args.argv[j + arg_offset]);
+
+ strbuf_release(&out);
+ argv_array_clear(&args);
+
+ return ret;
+ }
+
+ if (i && (i % 100) == 0)
+ fprintf(stderr, "Trials completed: %d\n", (int)i);
+ }
+
+ strbuf_release(&out);
+ argv_array_clear(&args);
+
+ return 0;
+}
+
+static int quote_echo(int argc, const char **argv)
+{
+ while (argc > 1) {
+ fwrite(argv[1], strlen(argv[1]), 1, stdout);
+ fputc('\0', stdout);
+ argv++;
+ argc--;
+ }
+
+ return 0;
+}
+
int cmd__run_command(int argc, const char **argv)
{
struct child_process proc = CHILD_PROCESS_INIT;
int jobs;
+ if (argc >= 2 && !strcmp(argv[1], "quote-stress-test"))
+ return !!quote_stress_test(argc - 1, argv + 1);
+
+ if (argc >= 2 && !strcmp(argv[1], "quote-echo"))
+ return !!quote_echo(argc - 1, argv + 1);
+
if (argc < 3)
return 1;
while (!strcmp(argv[1], "env")) {
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 21a8b53..f7ab3d5 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -165,6 +165,15 @@ test_expect_success 'absolute path rejects the empty string' '
test_must_fail test-tool path-utils absolute_path ""
'
+test_expect_success MINGW '<drive-letter>:\\abc is an absolute path' '
+ for letter in : \" C Z 1 รค
+ do
+ path=$letter:\\abc &&
+ absolute="$(test-tool path-utils absolute_path "$path")" &&
+ test "$path" = "$absolute" || return 1
+ done
+'
+
test_expect_success 'real path rejects the empty string' '
test_must_fail test-tool path-utils real_path ""
'
@@ -408,6 +417,9 @@ test_expect_success 'match .gitmodules' '
~1000000 \
~9999999 \
\
+ .gitmodules:\$DATA \
+ "gitmod~4 . :\$DATA" \
+ \
--not \
".gitmodules x" \
".gitmodules .x" \
@@ -432,7 +444,25 @@ test_expect_success 'match .gitmodules' '
\
GI7EB~1 \
GI7EB~01 \
- GI7EB~1X
+ GI7EB~1X \
+ \
+ .gitmodules,:\$DATA
+'
+
+test_expect_success MINGW 'is_valid_path() on Windows' '
+ test-tool path-utils is_valid_path \
+ win32 \
+ "win32 x" \
+ ../hello.txt \
+ C:\\git \
+ \
+ --not \
+ "win32 " \
+ "win32 /x " \
+ "win32." \
+ "win32 . ." \
+ .../hello.txt \
+ colon:test
'
test_done
diff --git a/t/t1014-read-tree-confusing.sh b/t/t1014-read-tree-confusing.sh
index 2f5a25d..da3376b 100755
--- a/t/t1014-read-tree-confusing.sh
+++ b/t/t1014-read-tree-confusing.sh
@@ -49,6 +49,7 @@ git~1
.git.SPACE .git.{space}
.\\\\.GIT\\\\foobar backslashes
.git\\\\foobar backslashes2
+.git...:alternate-stream
EOF
test_expect_success 'utf-8 paths allowed with core.protectHFS off' '
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index 91fd714..561a9b5 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -419,6 +419,7 @@ while read name path pretty; do
(
git init $name-$type &&
cd $name-$type &&
+ git config core.protectNTFS false &&
echo content >file &&
git add file &&
git commit -m base &&
diff --git a/t/t6130-pathspec-noglob.sh b/t/t6130-pathspec-noglob.sh
index 6583532..4129d9f 100755
--- a/t/t6130-pathspec-noglob.sh
+++ b/t/t6130-pathspec-noglob.sh
@@ -10,6 +10,7 @@ test_expect_success 'create commits with glob characters' '
# the name "f*" in the worktree, because it is not allowed
# on Windows (the tests below do not depend on the presence
# of the file in the worktree)
+ git config core.protectNTFS false &&
git update-index --add --cacheinfo 100644 "$(git rev-parse HEAD:foo)" "f*" &&
test_tick &&
git commit -m star &&
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 9e0d317..9a9dff5 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -406,12 +406,26 @@ test_expect_success 'submodule update - command in .git/config' '
)
'
-test_expect_success 'submodule update - command in .gitmodules is ignored' '
+test_expect_success 'submodule update - command in .gitmodules is rejected' '
test_when_finished "git -C super reset --hard HEAD^" &&
git -C super config -f .gitmodules submodule.submodule.update "!false" &&
git -C super commit -a -m "add command to .gitmodules file" &&
git -C super/submodule reset --hard $submodulesha1^ &&
- git -C super submodule update submodule
+ test_must_fail git -C super submodule update submodule
+'
+
+test_expect_success 'fsck detects command in .gitmodules' '
+ git init command-in-gitmodules &&
+ (
+ cd command-in-gitmodules &&
+ git submodule add ../submodule submodule &&
+ test_commit adding-submodule &&
+
+ git config -f .gitmodules submodule.submodule.update "!false" &&
+ git add .gitmodules &&
+ test_commit configuring-update &&
+ test_must_fail git fsck
+ )
'
cat << EOF >expect
@@ -480,6 +494,9 @@ test_expect_success 'recursive submodule update - command in .git/config catches
'
test_expect_success 'submodule init does not copy command into .git/config' '
+ test_when_finished "git -C super update-index --force-remove submodule1" &&
+ test_when_finished git config -f super/.gitmodules \
+ --remove-section submodule.submodule1 &&
(cd super &&
H=$(git ls-files -s submodule | cut -d" " -f2) &&
mkdir submodule1 &&
@@ -487,10 +504,9 @@ test_expect_success 'submodule init does not copy command into .git/config' '
git config -f .gitmodules submodule.submodule1.path submodule1 &&
git config -f .gitmodules submodule.submodule1.url ../submodule &&
git config -f .gitmodules submodule.submodule1.update !false &&
- git submodule init submodule1 &&
- echo "none" >expect &&
- git config submodule.submodule1.update >actual &&
- test_cmp expect actual
+ test_must_fail git submodule init submodule1 &&
+ test_expect_code 1 git config submodule.submodule1.update >actual &&
+ test_must_be_empty actual
)
'
diff --git a/t/t7415-submodule-names.sh b/t/t7415-submodule-names.sh
index b68c5f5..31d1e2d 100755
--- a/t/t7415-submodule-names.sh
+++ b/t/t7415-submodule-names.sh
@@ -176,4 +176,60 @@ test_expect_success 'fsck detects non-blob .gitmodules' '
)
'
+test_expect_success MINGW 'prevent git~1 squatting on Windows' '
+ git init squatting &&
+ (
+ cd squatting &&
+ mkdir a &&
+ touch a/..git &&
+ git add a/..git &&
+ test_tick &&
+ git commit -m initial &&
+
+ modules="$(test_write_lines \
+ "[submodule \"b.\"]" "url = ." "path = c" \
+ "[submodule \"b\"]" "url = ." "path = d\\\\a" |
+ git hash-object -w --stdin)" &&
+ rev="$(git rev-parse --verify HEAD)" &&
+ hash="$(echo x | git hash-object -w --stdin)" &&
+ git -c core.protectNTFS=false update-index --add \
+ --cacheinfo 100644,$modules,.gitmodules \
+ --cacheinfo 160000,$rev,c \
+ --cacheinfo 160000,$rev,d\\a \
+ --cacheinfo 100644,$hash,d./a/x \
+ --cacheinfo 100644,$hash,d./a/..git &&
+ test_tick &&
+ git -c core.protectNTFS=false commit -m "module" &&
+ test_must_fail git show HEAD: 2>err &&
+ test_i18ngrep backslash err
+ ) &&
+ test_must_fail git -c core.protectNTFS=false \
+ clone --recurse-submodules squatting squatting-clone 2>err &&
+ test_i18ngrep -e "directory not empty" -e "not an empty directory" err &&
+ ! grep gitdir squatting-clone/d/a/git~2
+'
+
+test_expect_success 'git dirs of sibling submodules must not be nested' '
+ git init nested &&
+ test_commit -C nested nested &&
+ (
+ cd nested &&
+ cat >.gitmodules <<-EOF &&
+ [submodule "hippo"]
+ url = .
+ path = thing1
+ [submodule "hippo/hooks"]
+ url = .
+ path = thing2
+ EOF
+ git clone . thing1 &&
+ git clone . thing2 &&
+ git add .gitmodules thing1 thing2 &&
+ test_tick &&
+ git commit -m nested
+ ) &&
+ test_must_fail git clone --recurse-submodules nested clone 2>err &&
+ test_i18ngrep "is inside git dir" err
+'
+
test_done
diff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh
index 1cd2c1c..5ba041f 100755
--- a/t/t7416-submodule-dash-url.sh
+++ b/t/t7416-submodule-dash-url.sh
@@ -46,4 +46,18 @@ test_expect_success 'fsck rejects unprotected dash' '
grep gitmodulesUrl err
'
+test_expect_success 'trailing backslash is handled correctly' '
+ git init testmodule &&
+ test_commit -C testmodule c &&
+ git submodule add ./testmodule &&
+ : ensure that the name ends in a double backslash &&
+ sed -e "s|\\(submodule \"testmodule\\)\"|\\1\\\\\\\\\"|" \
+ -e "s|url = .*|url = \" --should-not-be-an-option\"|" \
+ <.gitmodules >.new &&
+ mv .new .gitmodules &&
+ git commit -am "Add testmodule" &&
+ test_must_fail git clone --verbose --recurse-submodules . dolly 2>err &&
+ test_i18ngrep ! "unknown option" err
+'
+
test_done
diff --git a/t/t7417-submodule-path-url.sh b/t/t7417-submodule-path-url.sh
index 756af8c..f7e7e94 100755
--- a/t/t7417-submodule-path-url.sh
+++ b/t/t7417-submodule-path-url.sh
@@ -25,4 +25,21 @@ test_expect_success 'fsck rejects unprotected dash' '
grep gitmodulesPath err
'
+test_expect_success MINGW 'submodule paths disallows trailing spaces' '
+ git init super &&
+ test_must_fail git -C super submodule add ../upstream "sub " &&
+
+ : add "sub", then rename "sub" to "sub ", the hard way &&
+ git -C super submodule add ../upstream sub &&
+ tree=$(git -C super write-tree) &&
+ git -C super ls-tree $tree >tree &&
+ sed "s/sub/sub /" <tree >tree.new &&
+ tree=$(git -C super mktree <tree.new) &&
+ commit=$(echo with space | git -C super commit-tree $tree) &&
+ git -C super update-ref refs/heads/master $commit &&
+
+ test_must_fail git clone --recurse-submodules super dst 2>err &&
+ test_i18ngrep "sub " err
+'
+
test_done
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 9e7f962..c4a06c5 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -2106,12 +2106,27 @@ test_expect_success 'R: abort on receiving feature after data command' '
test_must_fail git fast-import <input
'
+test_expect_success 'R: import-marks features forbidden by default' '
+ >git.marks &&
+ echo "feature import-marks=git.marks" >input &&
+ test_must_fail git fast-import <input &&
+ echo "feature import-marks-if-exists=git.marks" >input &&
+ test_must_fail git fast-import <input
+'
+
test_expect_success 'R: only one import-marks feature allowed per stream' '
+ >git.marks &&
+ >git2.marks &&
cat >input <<-EOF &&
feature import-marks=git.marks
feature import-marks=git2.marks
EOF
+ test_must_fail git fast-import --allow-unsafe-features <input
+'
+
+test_expect_success 'R: export-marks feature forbidden by default' '
+ echo "feature export-marks=git.marks" >input &&
test_must_fail git fast-import <input
'
@@ -2125,19 +2140,29 @@ test_expect_success 'R: export-marks feature results in a marks file being creat
EOF
- cat input | git fast-import &&
+ git fast-import --allow-unsafe-features <input &&
grep :1 git.marks
'
test_expect_success 'R: export-marks options can be overridden by commandline options' '
- cat input | git fast-import --export-marks=other.marks &&
- grep :1 other.marks
+ cat >input <<-\EOF &&
+ feature export-marks=feature-sub/git.marks
+ blob
+ mark :1
+ data 3
+ hi
+
+ EOF
+ git fast-import --allow-unsafe-features \
+ --export-marks=cmdline-sub/other.marks <input &&
+ grep :1 cmdline-sub/other.marks &&
+ test_path_is_missing feature-sub
'
test_expect_success 'R: catch typo in marks file name' '
test_must_fail git fast-import --import-marks=nonexistent.marks </dev/null &&
echo "feature import-marks=nonexistent.marks" |
- test_must_fail git fast-import
+ test_must_fail git fast-import --allow-unsafe-features
'
test_expect_success 'R: import and output marks can be the same file' '
@@ -2193,7 +2218,8 @@ test_expect_success 'R: feature import-marks-if-exists' '
rm -f io.marks &&
>expect &&
- git fast-import --export-marks=io.marks <<-\EOF &&
+ git fast-import --export-marks=io.marks \
+ --allow-unsafe-features <<-\EOF &&
feature import-marks-if-exists=not_io.marks
EOF
test_cmp expect io.marks &&
@@ -2204,7 +2230,8 @@ test_expect_success 'R: feature import-marks-if-exists' '
echo ":1 $blob" >expect &&
echo ":2 $blob" >>expect &&
- git fast-import --export-marks=io.marks <<-\EOF &&
+ git fast-import --export-marks=io.marks \
+ --allow-unsafe-features <<-\EOF &&
feature import-marks-if-exists=io.marks
blob
mark :2
@@ -2217,7 +2244,8 @@ test_expect_success 'R: feature import-marks-if-exists' '
echo ":3 $blob" >>expect &&
git fast-import --import-marks=io.marks \
- --export-marks=io.marks <<-\EOF &&
+ --export-marks=io.marks \
+ --allow-unsafe-features <<-\EOF &&
feature import-marks-if-exists=not_io.marks
blob
mark :3
@@ -2230,7 +2258,8 @@ test_expect_success 'R: feature import-marks-if-exists' '
>expect &&
git fast-import --import-marks-if-exists=not_io.marks \
- --export-marks=io.marks <<-\EOF &&
+ --export-marks=io.marks \
+ --allow-unsafe-features <<-\EOF &&
feature import-marks-if-exists=io.marks
EOF
test_cmp expect io.marks
@@ -2242,7 +2271,7 @@ test_expect_success 'R: import to output marks works without any content' '
feature export-marks=marks.new
EOF
- cat input | git fast-import &&
+ git fast-import --allow-unsafe-features <input &&
test_cmp marks.out marks.new
'
@@ -2252,7 +2281,7 @@ test_expect_success 'R: import marks prefers commandline marks file over the str
feature export-marks=marks.new
EOF
- cat input | git fast-import --import-marks=marks.out &&
+ git fast-import --import-marks=marks.out --allow-unsafe-features <input &&
test_cmp marks.out marks.new
'
@@ -2265,7 +2294,8 @@ test_expect_success 'R: multiple --import-marks= should be honoured' '
head -n2 marks.out > one.marks &&
tail -n +3 marks.out > two.marks &&
- git fast-import --import-marks=one.marks --import-marks=two.marks <input &&
+ git fast-import --import-marks=one.marks --import-marks=two.marks \
+ --allow-unsafe-features <input &&
test_cmp marks.out combined.marks
'
@@ -2278,7 +2308,7 @@ test_expect_success 'R: feature relative-marks should be honoured' '
mkdir -p .git/info/fast-import/ &&
cp marks.new .git/info/fast-import/relative.in &&
- git fast-import <input &&
+ git fast-import --allow-unsafe-features <input &&
test_cmp marks.new .git/info/fast-import/relative.out
'
@@ -2290,7 +2320,7 @@ test_expect_success 'R: feature no-relative-marks should be honoured' '
feature export-marks=non-relative.out
EOF
- git fast-import <input &&
+ git fast-import --allow-unsafe-features <input &&
test_cmp marks.new non-relative.out
'
@@ -2560,7 +2590,7 @@ test_expect_success 'R: quiet option results in no stats being output' '
EOF
- cat input | git fast-import 2> output &&
+ git fast-import 2>output <input &&
test_must_be_empty output
'
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index 6a392e8..ef1e018 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -418,9 +418,10 @@ test_expect_success 'directory becomes symlink' '
test_expect_success 'fast-export quotes pathnames' '
git init crazy-paths &&
+ test_config -C crazy-paths core.protectNTFS false &&
(cd crazy-paths &&
blob=$(echo foo | git hash-object -w --stdin) &&
- git update-index --add \
+ git -c core.protectNTFS=false update-index --add \
--cacheinfo 100644 $blob "$(printf "path with\\nnewline")" \
--cacheinfo 100644 $blob "path with \"quote\"" \
--cacheinfo 100644 $blob "path with \\backslash" \