mv: remove use of deprecated 'get_pathspec()'
Convert the 'internal_copy_pathspec()' function to 'prefix_path()' instead of using the deprecated 'get_pathspec()' interface. Also, rename 'internal_copy_pathspec()' to 'internal_prefix_pathspec()' to be more descriptive of what the funciton is actually doing. In addition to this, fix a memory leak caused by only duplicating some of the pathspec elements. Instead always duplicate all of the the pathspec elements as an intermediate step (with modificationed based on the passed in flags). This way the intermediate strings can then be freed after getting the result from 'prefix_path()'. Signed-off-by: Brandon Williams <bmwill@google.com> Reviewed-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
		
				
					committed by
					
						
						Junio C Hamano
					
				
			
			
				
	
			
			
			
						parent
						
							454cb6bd52
						
					
				
				
					commit
					2ec87741b2
				
			
							
								
								
									
										50
									
								
								builtin/mv.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								builtin/mv.c
									
									
									
									
									
								
							@ -4,6 +4,7 @@
 | 
				
			|||||||
 * Copyright (C) 2006 Johannes Schindelin
 | 
					 * Copyright (C) 2006 Johannes Schindelin
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#include "builtin.h"
 | 
					#include "builtin.h"
 | 
				
			||||||
 | 
					#include "pathspec.h"
 | 
				
			||||||
#include "lockfile.h"
 | 
					#include "lockfile.h"
 | 
				
			||||||
#include "dir.h"
 | 
					#include "dir.h"
 | 
				
			||||||
#include "cache-tree.h"
 | 
					#include "cache-tree.h"
 | 
				
			||||||
@ -19,31 +20,42 @@ static const char * const builtin_mv_usage[] = {
 | 
				
			|||||||
#define DUP_BASENAME 1
 | 
					#define DUP_BASENAME 1
 | 
				
			||||||
#define KEEP_TRAILING_SLASH 2
 | 
					#define KEEP_TRAILING_SLASH 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char **internal_copy_pathspec(const char *prefix,
 | 
					static const char **internal_prefix_pathspec(const char *prefix,
 | 
				
			||||||
					   const char **pathspec,
 | 
										     const char **pathspec,
 | 
				
			||||||
					   int count, unsigned flags)
 | 
										     int count, unsigned flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	const char **result;
 | 
						const char **result;
 | 
				
			||||||
 | 
						int prefixlen = prefix ? strlen(prefix) : 0;
 | 
				
			||||||
	ALLOC_ARRAY(result, count + 1);
 | 
						ALLOC_ARRAY(result, count + 1);
 | 
				
			||||||
	COPY_ARRAY(result, pathspec, count);
 | 
					
 | 
				
			||||||
	result[count] = NULL;
 | 
						/* Create an intermediate copy of the pathspec based on the flags */
 | 
				
			||||||
	for (i = 0; i < count; i++) {
 | 
						for (i = 0; i < count; i++) {
 | 
				
			||||||
		int length = strlen(result[i]);
 | 
							int length = strlen(pathspec[i]);
 | 
				
			||||||
		int to_copy = length;
 | 
							int to_copy = length;
 | 
				
			||||||
 | 
							char *it;
 | 
				
			||||||
		while (!(flags & KEEP_TRAILING_SLASH) &&
 | 
							while (!(flags & KEEP_TRAILING_SLASH) &&
 | 
				
			||||||
		       to_copy > 0 && is_dir_sep(result[i][to_copy - 1]))
 | 
							       to_copy > 0 && is_dir_sep(pathspec[i][to_copy - 1]))
 | 
				
			||||||
			to_copy--;
 | 
								to_copy--;
 | 
				
			||||||
		if (to_copy != length || flags & DUP_BASENAME) {
 | 
					
 | 
				
			||||||
			char *it = xmemdupz(result[i], to_copy);
 | 
							it = xmemdupz(pathspec[i], to_copy);
 | 
				
			||||||
			if (flags & DUP_BASENAME) {
 | 
							if (flags & DUP_BASENAME) {
 | 
				
			||||||
				result[i] = xstrdup(basename(it));
 | 
								result[i] = xstrdup(basename(it));
 | 
				
			||||||
				free(it);
 | 
								free(it);
 | 
				
			||||||
			} else
 | 
							} else {
 | 
				
			||||||
				result[i] = it;
 | 
								result[i] = it;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return get_pathspec(prefix, result);
 | 
						result[count] = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Prefix the pathspec and free the old intermediate strings */
 | 
				
			||||||
 | 
						for (i = 0; i < count; i++) {
 | 
				
			||||||
 | 
							const char *match = prefix_path(prefix, prefixlen, result[i]);
 | 
				
			||||||
 | 
							free((char *) result[i]);
 | 
				
			||||||
 | 
							result[i] = match;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *add_slash(const char *path)
 | 
					static const char *add_slash(const char *path)
 | 
				
			||||||
@ -130,7 +142,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 | 
				
			|||||||
	if (read_cache() < 0)
 | 
						if (read_cache() < 0)
 | 
				
			||||||
		die(_("index file corrupt"));
 | 
							die(_("index file corrupt"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	source = internal_copy_pathspec(prefix, argv, argc, 0);
 | 
						source = internal_prefix_pathspec(prefix, argv, argc, 0);
 | 
				
			||||||
	modes = xcalloc(argc, sizeof(enum update_mode));
 | 
						modes = xcalloc(argc, sizeof(enum update_mode));
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Keep trailing slash, needed to let
 | 
						 * Keep trailing slash, needed to let
 | 
				
			||||||
@ -140,16 +152,16 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 | 
				
			|||||||
	flags = KEEP_TRAILING_SLASH;
 | 
						flags = KEEP_TRAILING_SLASH;
 | 
				
			||||||
	if (argc == 1 && is_directory(argv[0]) && !is_directory(argv[1]))
 | 
						if (argc == 1 && is_directory(argv[0]) && !is_directory(argv[1]))
 | 
				
			||||||
		flags = 0;
 | 
							flags = 0;
 | 
				
			||||||
	dest_path = internal_copy_pathspec(prefix, argv + argc, 1, flags);
 | 
						dest_path = internal_prefix_pathspec(prefix, argv + argc, 1, flags);
 | 
				
			||||||
	submodule_gitfile = xcalloc(argc, sizeof(char *));
 | 
						submodule_gitfile = xcalloc(argc, sizeof(char *));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dest_path[0][0] == '\0')
 | 
						if (dest_path[0][0] == '\0')
 | 
				
			||||||
		/* special case: "." was normalized to "" */
 | 
							/* special case: "." was normalized to "" */
 | 
				
			||||||
		destination = internal_copy_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
 | 
							destination = internal_prefix_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
 | 
				
			||||||
	else if (!lstat(dest_path[0], &st) &&
 | 
						else if (!lstat(dest_path[0], &st) &&
 | 
				
			||||||
			S_ISDIR(st.st_mode)) {
 | 
								S_ISDIR(st.st_mode)) {
 | 
				
			||||||
		dest_path[0] = add_slash(dest_path[0]);
 | 
							dest_path[0] = add_slash(dest_path[0]);
 | 
				
			||||||
		destination = internal_copy_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
 | 
							destination = internal_prefix_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if (argc != 1)
 | 
							if (argc != 1)
 | 
				
			||||||
			die(_("destination '%s' is not a directory"), dest_path[0]);
 | 
								die(_("destination '%s' is not a directory"), dest_path[0]);
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user