mirror of
				https://git.proxmox.com/git/libgit2
				synced 2025-10-27 17:52:39 +00:00 
			
		
		
		
	 212eb09d5f
			
		
	
	
		212eb09d5f
		
	
	
	
	
		
			
			Since we now rely on it (at least under Solaris), I figured we probably want to make sure it's accurate. The new test makes sure that creating a file with a name of length FILENAME_MAX+1 fails.
		
			
				
	
	
		
			236 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			236 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "clar_libgit2.h"
 | |
| #include "fileops.h"
 | |
| 
 | |
| typedef struct name_data {
 | |
| 	int count; /* return count */
 | |
| 	char *name; /* filename		*/
 | |
| } name_data;
 | |
| 
 | |
| typedef struct walk_data {
 | |
| 	char *sub;		/* sub-directory name */
 | |
| 	name_data *names; /* name state data	*/
 | |
| 	git_buf path;
 | |
| } walk_data;
 | |
| 
 | |
| 
 | |
| static char *top_dir = "dir-walk";
 | |
| static walk_data *state_loc;
 | |
| 
 | |
| static void setup(walk_data *d)
 | |
| {
 | |
| 	name_data *n;
 | |
| 
 | |
| 	cl_must_pass(p_mkdir(top_dir, 0777));
 | |
| 
 | |
| 	cl_must_pass(p_chdir(top_dir));
 | |
| 
 | |
| 	if (strcmp(d->sub, ".") != 0)
 | |
| 		cl_must_pass(p_mkdir(d->sub, 0777));
 | |
| 
 | |
| 	cl_git_pass(git_buf_sets(&d->path, d->sub));
 | |
| 
 | |
| 	state_loc = d;
 | |
| 
 | |
| 	for (n = d->names; n->name; n++) {
 | |
| 		git_file fd = p_creat(n->name, 0666);
 | |
| 		cl_assert(fd >= 0);
 | |
| 		p_close(fd);
 | |
| 		n->count = 0;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static void dirent_cleanup__cb(void *_d)
 | |
| {
 | |
| 	walk_data *d = _d;
 | |
| 	name_data *n;
 | |
| 
 | |
| 	for (n = d->names; n->name; n++) {
 | |
| 		cl_must_pass(p_unlink(n->name));
 | |
| 	}
 | |
| 
 | |
| 	if (strcmp(d->sub, ".") != 0)
 | |
| 		cl_must_pass(p_rmdir(d->sub));
 | |
| 
 | |
| 	cl_must_pass(p_chdir(".."));
 | |
| 
 | |
| 	cl_must_pass(p_rmdir(top_dir));
 | |
| 
 | |
| 	git_buf_free(&d->path);
 | |
| }
 | |
| 
 | |
| static void check_counts(walk_data *d)
 | |
| {
 | |
| 	name_data *n;
 | |
| 
 | |
| 	for (n = d->names; n->name; n++) {
 | |
| 		cl_assert(n->count == 1);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static int one_entry(void *state, git_buf *path)
 | |
| {
 | |
| 	walk_data *d = (walk_data *) state;
 | |
| 	name_data *n;
 | |
| 
 | |
| 	if (state != state_loc)
 | |
| 		return GIT_ERROR;
 | |
| 
 | |
| 	if (path != &d->path)
 | |
| 		return GIT_ERROR;
 | |
| 
 | |
| 	for (n = d->names; n->name; n++) {
 | |
| 		if (!strcmp(n->name, path->ptr)) {
 | |
| 			n->count++;
 | |
| 			return 0;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return GIT_ERROR;
 | |
| }
 | |
| 
 | |
| static int dont_call_me(void *state, git_buf *path)
 | |
| {
 | |
| 	GIT_UNUSED(state);
 | |
| 	GIT_UNUSED(path);
 | |
| 	return GIT_ERROR;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| static name_data dot_names[] = {
 | |
| 	{ 0, "./a" },
 | |
| 	{ 0, "./asdf" },
 | |
| 	{ 0, "./pack-foo.pack" },
 | |
| 	{ 0, NULL }
 | |
| };
 | |
| static walk_data dot = {
 | |
| 	".",
 | |
| 	dot_names,
 | |
| 	GIT_BUF_INIT
 | |
| };
 | |
| 
 | |
| /* make sure that the '.' folder is not traversed */
 | |
| void test_core_dirent__dont_traverse_dot(void)
 | |
| {
 | |
| 	cl_set_cleanup(&dirent_cleanup__cb, &dot);
 | |
| 	setup(&dot);
 | |
| 
 | |
| 	cl_git_pass(git_path_direach(&dot.path,
 | |
| 					one_entry,
 | |
| 					&dot));
 | |
| 
 | |
| 	check_counts(&dot);
 | |
| }
 | |
| 
 | |
| 
 | |
| static name_data sub_names[] = {
 | |
| 	{ 0, "sub/a" },
 | |
| 	{ 0, "sub/asdf" },
 | |
| 	{ 0, "sub/pack-foo.pack" },
 | |
| 	{ 0, NULL }
 | |
| };
 | |
| static walk_data sub = {
 | |
| 	"sub",
 | |
| 	sub_names,
 | |
| 	GIT_BUF_INIT
 | |
| };
 | |
| 
 | |
| /* traverse a subfolder */
 | |
| void test_core_dirent__traverse_subfolder(void)
 | |
| {
 | |
| 	cl_set_cleanup(&dirent_cleanup__cb, &sub);
 | |
| 	setup(&sub);
 | |
| 
 | |
| 	cl_git_pass(git_path_direach(&sub.path,
 | |
| 					one_entry,
 | |
| 					&sub));
 | |
| 
 | |
| 	check_counts(&sub);
 | |
| }
 | |
| 
 | |
| 
 | |
| static walk_data sub_slash = {
 | |
| 	"sub/",
 | |
| 	sub_names,
 | |
| 	GIT_BUF_INIT
 | |
| };
 | |
| 
 | |
| /* traverse a slash-terminated subfolder */
 | |
| void test_core_dirent__traverse_slash_terminated_folder(void)
 | |
| {
 | |
| 	cl_set_cleanup(&dirent_cleanup__cb, &sub_slash);
 | |
| 	setup(&sub_slash);
 | |
| 
 | |
| 	cl_git_pass(git_path_direach(&sub_slash.path,
 | |
| 					one_entry,
 | |
| 					&sub_slash));
 | |
| 
 | |
| 	check_counts(&sub_slash);
 | |
| }
 | |
| 
 | |
| 
 | |
| static name_data empty_names[] = {
 | |
| 	{ 0, NULL }
 | |
| };
 | |
| static walk_data empty = {
 | |
| 	"empty",
 | |
| 	empty_names,
 | |
| 	GIT_BUF_INIT
 | |
| };
 | |
| 
 | |
| /* make sure that empty folders are not traversed */
 | |
| void test_core_dirent__dont_traverse_empty_folders(void)
 | |
| {
 | |
| 	cl_set_cleanup(&dirent_cleanup__cb, &empty);
 | |
| 	setup(&empty);
 | |
| 
 | |
| 	cl_git_pass(git_path_direach(&empty.path,
 | |
| 					one_entry,
 | |
| 					&empty));
 | |
| 
 | |
| 	check_counts(&empty);
 | |
| 
 | |
| 	/* make sure callback not called */
 | |
| 	cl_git_pass(git_path_direach(&empty.path,
 | |
| 					dont_call_me,
 | |
| 					&empty));
 | |
| }
 | |
| 
 | |
| static name_data odd_names[] = {
 | |
| 	{ 0, "odd/.a" },
 | |
| 	{ 0, "odd/..c" },
 | |
| 	/* the following don't work on cygwin/win32 */
 | |
| 	/* { 0, "odd/.b." }, */
 | |
| 	/* { 0, "odd/..d.." }, */
 | |
| 	{ 0, NULL }
 | |
| };
 | |
| static walk_data odd = {
 | |
| 	"odd",
 | |
| 	odd_names,
 | |
| 	GIT_BUF_INIT
 | |
| };
 | |
| 
 | |
| /* make sure that strange looking filenames ('..c') are traversed */
 | |
| void test_core_dirent__traverse_weird_filenames(void)
 | |
| {
 | |
| 	cl_set_cleanup(&dirent_cleanup__cb, &odd);
 | |
| 	setup(&odd);
 | |
| 
 | |
| 	cl_git_pass(git_path_direach(&odd.path,
 | |
| 					one_entry,
 | |
| 					&odd));
 | |
| 
 | |
| 	check_counts(&odd);
 | |
| }
 | |
| 
 | |
| /* test filename length limits */
 | |
| void test_core_dirent__length_limits(void)
 | |
| {
 | |
| 	char *big_filename = (char *)git__malloc(FILENAME_MAX + 1);
 | |
| 	memset(big_filename, 'a', FILENAME_MAX + 1);
 | |
| 	big_filename[FILENAME_MAX] = 0;
 | |
| 
 | |
| 	cl_must_fail(p_creat(big_filename, 0666));
 | |
| 	git__free(big_filename);
 | |
| }
 |