summaryrefslogtreecommitdiff
path: root/t/helper/test-path-utils.c
diff options
context:
space:
mode:
authorLibravatar Johannes Schindelin <johannes.schindelin@gmx.de>2019-09-16 13:26:40 +0200
committerLibravatar Johannes Schindelin <johannes.schindelin@gmx.de>2019-12-05 15:37:07 +0100
commit7f3551dd686e2237490c17946335a675c4f59881 (patch)
tree00b0bb3ed0584501a3638e7eaaf28d29bc792cf6 /t/helper/test-path-utils.c
parentMerge branch 'prevent-name-squatting-on-windows' (diff)
parentpath: also guard `.gitmodules` against NTFS Alternate Data Streams (diff)
downloadtgif-7f3551dd686e2237490c17946335a675c4f59881.tar.xz
Merge branch 'disallow-dotgit-via-ntfs-alternate-data-streams'
This patch series plugs an attack vector we had overlooked in our December 2014 work on `core.protectNTFS`. Essentially, the path `.git::$INDEX_ALLOCATION/config` is interpreted as `.git/config` when NTFS Alternate Data Streams are available (which they are on Windows, and at least on network shares that are SMB-mounted on macOS). Needless to say: we don't want that. In fact, we want to stay on the very safe side and not even special-case the `$INDEX_ALLOCATION` stream type: let's just prevent Git from touching _any_ explicitly specified Alternate Data Stream of `.git`. In essence, we'll prevent Git from tracking, or writing to, any path with a segment of the form `.git:<anything>`. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Diffstat (limited to 't/helper/test-path-utils.c')
-rw-r--r--t/helper/test-path-utils.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c
index 94846550f7..16d8e689c8 100644
--- a/t/helper/test-path-utils.c
+++ b/t/helper/test-path-utils.c
@@ -176,6 +176,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_main(int argc, const char **argv)
{
if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
@@ -290,6 +383,9 @@ int cmd_main(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);
+
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
argv[1] ? argv[1] : "(there was none)");
return 1;