Merge branch 'jk/leakfixes'
Memory leaks in "git mv" has been plugged. * jk/leakfixes: mv: replace src_dir with a strvec mv: factor out empty src_dir removal mv: move src_dir cleanup to end of cmd_mv() t-strvec: mark variable-arg helper with LAST_ARG_MUST_BE_NULL t-strvec: use va_end() to match va_start()
This commit is contained in:
		
							
								
								
									
										50
									
								
								builtin/mv.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								builtin/mv.c
									
									
									
									
									
								
							@ -156,6 +156,28 @@ free_return:
 | 
				
			|||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void remove_empty_src_dirs(const char **src_dir, size_t src_dir_nr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						size_t i;
 | 
				
			||||||
 | 
						struct strbuf a_src_dir = STRBUF_INIT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < src_dir_nr; i++) {
 | 
				
			||||||
 | 
							int dummy;
 | 
				
			||||||
 | 
							strbuf_addstr(&a_src_dir, src_dir[i]);
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * if entries under a_src_dir are all moved away,
 | 
				
			||||||
 | 
							 * recursively remove a_src_dir to cleanup
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (index_range_of_same_dir(a_src_dir.buf, a_src_dir.len,
 | 
				
			||||||
 | 
										    &dummy, &dummy) < 1) {
 | 
				
			||||||
 | 
								remove_dir_recursively(&a_src_dir, 0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							strbuf_reset(&a_src_dir);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						strbuf_release(&a_src_dir);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int cmd_mv(int argc, const char **argv, const char *prefix)
 | 
					int cmd_mv(int argc, const char **argv, const char *prefix)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, flags, gitmodules_modified = 0;
 | 
						int i, flags, gitmodules_modified = 0;
 | 
				
			||||||
@ -175,9 +197,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 | 
				
			|||||||
	struct strvec submodule_gitfiles_to_free = STRVEC_INIT;
 | 
						struct strvec submodule_gitfiles_to_free = STRVEC_INIT;
 | 
				
			||||||
	const char **submodule_gitfiles;
 | 
						const char **submodule_gitfiles;
 | 
				
			||||||
	char *dst_w_slash = NULL;
 | 
						char *dst_w_slash = NULL;
 | 
				
			||||||
	const char **src_dir = NULL;
 | 
						struct strvec src_dir = STRVEC_INIT;
 | 
				
			||||||
	int src_dir_nr = 0, src_dir_alloc = 0;
 | 
					 | 
				
			||||||
	struct strbuf a_src_dir = STRBUF_INIT;
 | 
					 | 
				
			||||||
	enum update_mode *modes, dst_mode = 0;
 | 
						enum update_mode *modes, dst_mode = 0;
 | 
				
			||||||
	struct stat st, dest_st;
 | 
						struct stat st, dest_st;
 | 
				
			||||||
	struct string_list src_for_dst = STRING_LIST_INIT_DUP;
 | 
						struct string_list src_for_dst = STRING_LIST_INIT_DUP;
 | 
				
			||||||
@ -323,8 +343,7 @@ dir_check:
 | 
				
			|||||||
			/* last - first >= 1 */
 | 
								/* last - first >= 1 */
 | 
				
			||||||
			modes[i] |= WORKING_DIRECTORY;
 | 
								modes[i] |= WORKING_DIRECTORY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			ALLOC_GROW(src_dir, src_dir_nr + 1, src_dir_alloc);
 | 
								strvec_push(&src_dir, src);
 | 
				
			||||||
			src_dir[src_dir_nr++] = src;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			n = argc + last - first;
 | 
								n = argc + last - first;
 | 
				
			||||||
			REALLOC_ARRAY(modes, n);
 | 
								REALLOC_ARRAY(modes, n);
 | 
				
			||||||
@ -538,25 +557,7 @@ remove_entry:
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						remove_empty_src_dirs(src_dir.v, src_dir.nr);
 | 
				
			||||||
	 * cleanup the empty src_dirs
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	for (i = 0; i < src_dir_nr; i++) {
 | 
					 | 
				
			||||||
		int dummy;
 | 
					 | 
				
			||||||
		strbuf_addstr(&a_src_dir, src_dir[i]);
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * if entries under a_src_dir are all moved away,
 | 
					 | 
				
			||||||
		 * recursively remove a_src_dir to cleanup
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		if (index_range_of_same_dir(a_src_dir.buf, a_src_dir.len,
 | 
					 | 
				
			||||||
					    &dummy, &dummy) < 1) {
 | 
					 | 
				
			||||||
			remove_dir_recursively(&a_src_dir, 0);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		strbuf_reset(&a_src_dir);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	strbuf_release(&a_src_dir);
 | 
					 | 
				
			||||||
	free(src_dir);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dirty_paths.nr)
 | 
						if (dirty_paths.nr)
 | 
				
			||||||
		advise_on_moving_dirty_path(&dirty_paths);
 | 
							advise_on_moving_dirty_path(&dirty_paths);
 | 
				
			||||||
@ -571,6 +572,7 @@ remove_entry:
 | 
				
			|||||||
	ret = 0;
 | 
						ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
 | 
						strvec_clear(&src_dir);
 | 
				
			||||||
	free(dst_w_slash);
 | 
						free(dst_w_slash);
 | 
				
			||||||
	string_list_clear(&src_for_dst, 0);
 | 
						string_list_clear(&src_for_dst, 0);
 | 
				
			||||||
	string_list_clear(&dirty_paths, 0);
 | 
						string_list_clear(&dirty_paths, 0);
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define check_strvec(vec, ...) \
 | 
					#define check_strvec(vec, ...) \
 | 
				
			||||||
	check_strvec_loc(TEST_LOCATION(), vec, __VA_ARGS__)
 | 
						check_strvec_loc(TEST_LOCATION(), vec, __VA_ARGS__)
 | 
				
			||||||
 | 
					LAST_ARG_MUST_BE_NULL
 | 
				
			||||||
static void check_strvec_loc(const char *loc, struct strvec *vec, ...)
 | 
					static void check_strvec_loc(const char *loc, struct strvec *vec, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	va_list ap;
 | 
						va_list ap;
 | 
				
			||||||
@ -22,11 +23,13 @@ static void check_strvec_loc(const char *loc, struct strvec *vec, ...)
 | 
				
			|||||||
			strbuf_addf(&msg, "strvec index %"PRIuMAX, (uintmax_t) nr);
 | 
								strbuf_addf(&msg, "strvec index %"PRIuMAX, (uintmax_t) nr);
 | 
				
			||||||
			test_assert(loc, msg.buf, 0);
 | 
								test_assert(loc, msg.buf, 0);
 | 
				
			||||||
			strbuf_release(&msg);
 | 
								strbuf_release(&msg);
 | 
				
			||||||
 | 
								va_end(ap);
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nr++;
 | 
							nr++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						va_end(ap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	check_uint(vec->nr, ==, nr);
 | 
						check_uint(vec->nr, ==, nr);
 | 
				
			||||||
	check_uint(vec->alloc, >=, nr);
 | 
						check_uint(vec->alloc, >=, nr);
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user