Thread (126 messages) flat view 126 messages, 3 authors, 2017-01-09
STALE3500d

Revision v1 of 5 in this series.

Revisions (5)
  1. v1 current
  2. v2 [diff vs current]
  3. v3 [diff vs current]
  4. v4 [diff vs current]
  5. v5 [diff vs current]

[PATCH 01/17] mv: convert to using pathspec struct interface

From: Brandon Williams <hidden>
Date: 2016-12-06 21:53:18
Subsystem: the rest · Maintainer: Linus Torvalds

Convert the 'internal_copy_pathspec()' function to use the pathspec
struct interface from using the deprecated 'get_pathspec()' interface.

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 prior to duplicating the result of parse_pathspec (which contains
each of the elements with the prefix prepended).

Signed-off-by: Brandon Williams <redacted>
---
 builtin/mv.c | 45 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 32 insertions(+), 13 deletions(-)
diff --git a/builtin/mv.c b/builtin/mv.c
index 2f43877..4df4a12 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2006 Johannes Schindelin
  */
 #include "builtin.h"
+#include "pathspec.h"
 #include "lockfile.h"
 #include "dir.h"
 #include "cache-tree.h"
@@ -25,25 +26,43 @@ static const char **internal_copy_pathspec(const char *prefix,
 {
 	int i;
 	const char **result;
+	struct pathspec ps;
 	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++) {
-		int length = strlen(result[i]);
+		int length = strlen(pathspec[i]);
 		int to_copy = length;
+		char *it;
 		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--;
-		if (to_copy != length || flags & DUP_BASENAME) {
-			char *it = xmemdupz(result[i], to_copy);
-			if (flags & DUP_BASENAME) {
-				result[i] = xstrdup(basename(it));
-				free(it);
-			} else
-				result[i] = it;
-		}
+
+		it = xmemdupz(pathspec[i], to_copy);
+		if (flags & DUP_BASENAME) {
+			result[i] = xstrdup(basename(it));
+			free(it);
+		} else
+			result[i] = it;
+	}
+	result[count] = NULL;
+
+	parse_pathspec(&ps,
+		       PATHSPEC_ALL_MAGIC &
+		       ~(PATHSPEC_FROMTOP | PATHSPEC_LITERAL),
+		       PATHSPEC_KEEP_ORDER | PATHSPEC_PREFER_CWD,
+		       prefix, result);
+	assert(count == ps.nr);
+
+	/* Copy the pathspec and free the old intermediate strings */
+	for (i = 0; i < count; i++) {
+		const char *match = xstrdup(ps.items[i].match);
+		free((char *) result[i]);
+		result[i] = match;
 	}
-	return get_pathspec(prefix, result);
+
+	clear_pathspec(&ps);
+	return result;
 }
 
 static const char *add_slash(const char *path)
-- 
2.8.0.rc3.226.g39d4020
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help