From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH/WIP 02/10] parse_pathspec: make sure the prefix part is wildcard-free
Date: Sun, 13 Jan 2013 19:49:31 +0700 [thread overview]
Message-ID: <1358081379-17752-3-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1358081379-17752-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
cache.h | 1 +
path.c | 15 ++++++++++++++-
setup.c | 24 +++++++++++++++--------
t/t6131-pathspec-prefix.sh | 47 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 78 insertions(+), 9 deletions(-)
create mode 100755 t/t6131-pathspec-prefix.sh
diff --git a/cache.h b/cache.h
index c7a8d28..f3de28d 100644
--- a/cache.h
+++ b/cache.h
@@ -747,6 +747,7 @@ const char *real_path(const char *path);
const char *real_path_if_valid(const char *path);
const char *absolute_path(const char *path);
const char *relative_path(const char *abs, const char *base);
+int normalize_path_copy_len(char *dst, const char *src, int *prefix_len);
int normalize_path_copy(char *dst, const char *src);
int longest_ancestor_length(const char *path, struct string_list *prefixes);
char *strip_path_suffix(const char *path, const char *suffix);
diff --git a/path.c b/path.c
index d3d3f8b..7baf334 100644
--- a/path.c
+++ b/path.c
@@ -487,8 +487,14 @@ const char *relative_path(const char *abs, const char *base)
*
* Note that this function is purely textual. It does not follow symlinks,
* verify the existence of the path, or make any system calls.
+ *
+ * prefix_len != NULL is for a specific case of prefix_pathspec():
+ * assume that src == dst and src[0..prefix_len-1] is already
+ * normalized, any time "../" eats up to the prefix_len part,
+ * prefix_len is reduced. In the end prefix_len is the remaining
+ * prefix that has not been overridden by user pathspec.
*/
-int normalize_path_copy(char *dst, const char *src)
+int normalize_path_copy_len(char *dst, const char *src, int *prefix_len)
{
char *dst0;
@@ -563,11 +569,18 @@ int normalize_path_copy(char *dst, const char *src)
/* Windows: dst[-1] cannot be backslash anymore */
while (dst0 < dst && dst[-1] != '/')
dst--;
+ if (prefix_len && *prefix_len > dst - dst0)
+ *prefix_len = dst - dst0;
}
*dst = '\0';
return 0;
}
+int normalize_path_copy(char *dst, const char *src)
+{
+ return normalize_path_copy_len(dst, src, NULL);
+}
+
/*
* path = Canonical absolute path
* prefixes = string_list containing normalized, absolute paths without
diff --git a/setup.c b/setup.c
index 9db6093..c5e97c9 100644
--- a/setup.c
+++ b/setup.c
@@ -5,10 +5,11 @@
static int inside_git_dir = -1;
static int inside_work_tree = -1;
-static char *prefix_path_gently(const char *prefix, int len, const char *path)
+static char *prefix_path_gently(const char *prefix, int *p_len, const char *path)
{
const char *orig = path;
char *sanitized;
+ int len = *p_len;
if (is_absolute_path(orig)) {
const char *temp = real_path(path);
sanitized = xmalloc(len + strlen(temp) + 1);
@@ -19,7 +20,7 @@ static char *prefix_path_gently(const char *prefix, int len, const char *path)
memcpy(sanitized, prefix, len);
strcpy(sanitized + len, path);
}
- if (normalize_path_copy(sanitized, sanitized))
+ if (normalize_path_copy_len(sanitized, sanitized, p_len))
goto error_out;
if (is_absolute_path(orig)) {
size_t root_len, len, total;
@@ -44,7 +45,7 @@ static char *prefix_path_gently(const char *prefix, int len, const char *path)
char *prefix_path(const char *prefix, int len, const char *path)
{
- char *r = prefix_path_gently(prefix, len, path);
+ char *r = prefix_path_gently(prefix, &len, path);
if (!r)
die("'%s' is outside repository", path);
return r;
@@ -53,7 +54,7 @@ char *prefix_path(const char *prefix, int len, const char *path)
int path_inside_repo(const char *prefix, const char *path)
{
int len = prefix ? strlen(prefix) : 0;
- char *r = prefix_path_gently(prefix, len, path);
+ char *r = prefix_path_gently(prefix, &len, path);
if (r) {
free(r);
return 1;
@@ -261,10 +262,14 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
copyfrom++;
}
- if (magic & PATHSPEC_FROMTOP)
+ if (magic & PATHSPEC_FROMTOP) {
match = xstrdup(copyfrom);
- else
- match = prefix_path(prefix, prefixlen, copyfrom);
+ prefixlen = 0;
+ } else {
+ match = prefix_path_gently(prefix, &prefixlen, copyfrom);
+ if (!match)
+ die("%s: '%s' is outside repository", elt, copyfrom);
+ }
*raw = item->match = match;
item->original = elt;
item->len = strlen(item->match);
@@ -300,8 +305,11 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
item->flags = 0;
if (limit_pathspec_to_literal())
item->nowildcard_len = item->len;
- else
+ else {
item->nowildcard_len = simple_length(item->match);
+ if (item->nowildcard_len < prefixlen)
+ item->nowildcard_len = prefixlen;
+ }
if (item->nowildcard_len < item->len &&
item->match[item->nowildcard_len] == '*' &&
no_wildcard(item->match + item->nowildcard_len + 1))
diff --git a/t/t6131-pathspec-prefix.sh b/t/t6131-pathspec-prefix.sh
new file mode 100755
index 0000000..db59091
--- /dev/null
+++ b/t/t6131-pathspec-prefix.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+test_description='Verify the exact matching of prefix part in pathspec'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ mkdir a\* ab &&
+ : >a\*/foo &&
+ : >ab/foo &&
+ git add .
+'
+
+test_expect_success 'prefix has wildcards but treated as literal' '
+ (
+ cd a\* &&
+ git ls-files --cached foo
+ ) >actual &&
+ echo foo >expected &&
+ test_cmp expected actual
+'
+
+test_expect_success 'prefix is reduced to empty' '
+ (
+ cd a\* &&
+ git ls-files --cached ../a\*/foo
+ ) >actual &&
+ cat <<\EOF >expected &&
+foo
+../ab/foo
+EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'prefix is reduced to empty (2)' '
+ (
+ cd a\* &&
+ git ls-files --cached non-existing//../fancy/.//../../a\*/foo
+ ) >actual &&
+ cat <<\EOF >expected &&
+foo
+../ab/foo
+EOF
+ test_cmp expected actual
+'
+
+test_done
--
1.8.0.rc2.23.g1fb49df
next prev parent reply other threads:[~2013-01-13 12:50 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-13 12:49 [PATCH/WIP 00/10] Fancy pathspec stuff Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 01/10] pathspec: allow to use alternate char for quoting long magic mnemonic Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` Nguyễn Thái Ngọc Duy [this message]
2013-01-13 12:49 ` [PATCH/WIP 03/10] pathspec: support :(literal) syntax for noglob pathspec Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 04/10] parse_pathspec: save prefix information Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 05/10] pathspec: prepare for :(glob)path syntax Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 06/10] Enable :(glob)path syntax for a lot of commands Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 07/10] parse_pathspec: accept :(icase)path syntax Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 08/10] common_prefix/read_directory: treat PATHSPEC_ICASE like wildcards Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 09/10] pathspec: support icase in match_pathspec_depth and tree_entry_interesting Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 10/10] Enable ls-files and ls-tree for testing PATHSPEC_ICASE Nguyễn Thái Ngọc Duy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1358081379-17752-3-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).