Added copydir_recurs() to test_helpers.c Test helper function which recursively copies the content of a directory. This function has been tweaked to prevent stack overflows by reusing the same path buffers on all recursive calls.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
diff --git a/tests/t10-refs.c b/tests/t10-refs.c
index 4d43221..20b05e3 100644
--- a/tests/t10-refs.c
+++ b/tests/t10-refs.c
@@ -297,9 +297,17 @@ END_TEST
BEGIN_TEST("packrefs", create_packfile)
git_repository *repo;
- must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
+ char temp_repo_path[GIT_PATH_MAX];
+
+ must_pass(copydir_recurs(REPOSITORY_FOLDER, TEMP_DIR));
+
+ git__joinpath(temp_repo_path, TEMP_DIR, TEST_REPOSITORY_NAME);
+ must_pass(git_repository_open(&repo, temp_repo_path));
must_pass(git_reference_packall(repo));
+
git_repository_free(repo);
+ must_pass(rmdir_recurs(TEMP_DIR));
+
END_TEST
static int ensure_refname_normalized(int is_oid_ref, const char *input_refname, const char *expected_refname)
diff --git a/tests/test_helpers.c b/tests/test_helpers.c
index 60ef5b5..4805fdc 100644
--- a/tests/test_helpers.c
+++ b/tests/test_helpers.c
@@ -178,19 +178,19 @@ int cmp_files(const char *a, const char *b)
static int remove_filesystem_element_recurs(void *GIT_UNUSED(nil), char *path)
{
- char temp_path[GIT_PATH_MAX];
int error = GIT_SUCCESS;
GIT_UNUSED_ARG(nil);
error = gitfo_isdir(path);
- if (error == GIT_SUCCESS)
- {
- strcpy(temp_path, path);
- error = gitfo_dirent(temp_path, sizeof(temp_path), remove_filesystem_element_recurs, NULL);
+ if (error == GIT_SUCCESS) {
+ size_t root_size = strlen(path);
+
+ error = gitfo_dirent(path, GIT_PATH_MAX, remove_filesystem_element_recurs, NULL);
if (error < GIT_SUCCESS)
return error;
+ path[root_size] = 0;
return rmdir(path);
}
@@ -199,5 +199,50 @@ static int remove_filesystem_element_recurs(void *GIT_UNUSED(nil), char *path)
int rmdir_recurs(char *directory_path)
{
- return remove_filesystem_element_recurs(NULL, directory_path);
+ char buffer[GIT_PATH_MAX];
+ strcpy(buffer, directory_path);
+ return remove_filesystem_element_recurs(NULL, buffer);
+}
+
+typedef struct {
+ size_t src_len, dst_len;
+ char *dst;
+} copydir_data;
+
+static int copy_filesystem_element_recurs(void *_data, char *source)
+{
+ const int mode = 0755; /* or 0777 ? */
+ copydir_data *data = (copydir_data *)_data;
+
+ data->dst[data->dst_len] = 0;
+ git__joinpath(data->dst, data->dst, source + data->src_len);
+
+ if (gitfo_isdir(source) == GIT_SUCCESS) {
+ if (gitfo_mkdir(data->dst, mode) < GIT_SUCCESS)
+ return GIT_EOSERR;
+
+ return gitfo_dirent(source, GIT_PATH_MAX, copy_filesystem_element_recurs, _data);
+ }
+
+ return copy_file(source, data->dst);
+}
+
+int copydir_recurs(char *source_directory_path, char *destination_directory_path)
+{
+ char source_buffer[GIT_PATH_MAX];
+ char dest_buffer[GIT_PATH_MAX];
+ copydir_data data;
+
+ /* Source has to exist, Destination hast to _not_ exist */
+ if (gitfo_isdir(source_directory_path) || !gitfo_isdir(destination_directory_path))
+ return GIT_EINVALIDPATH;
+
+ git__joinpath(source_buffer, source_directory_path, "");
+ data.src_len = strlen(source_buffer);
+
+ git__joinpath(dest_buffer, destination_directory_path, "");
+ data.dst = dest_buffer;
+ data.dst_len = strlen(dest_buffer);
+
+ return copy_filesystem_element_recurs(&data, source_buffer);
}
diff --git a/tests/test_helpers.h b/tests/test_helpers.h
index 57152b5..af5a0a9 100644
--- a/tests/test_helpers.h
+++ b/tests/test_helpers.h
@@ -63,6 +63,7 @@ extern int remove_loose_object(const char *odb_dir, git_object *object);
extern int cmp_files(const char *a, const char *b);
extern int copy_file(const char *source, const char *dest);
extern int rmdir_recurs(char *directory_path);
+extern int copydir_recurs(char *source_directory_path, char *destination_directory_path);
#endif
/* INCLUDE_test_helpers_h__ */