From ad66df2df14991e7436474d266cc6db823e6ae78 Mon Sep 17 00:00:00 2001 From: Jiang Xin Date: Tue, 25 Jun 2013 23:53:44 +0800 Subject: quote.c: substitute path_relative with relative_path Substitute the function path_relative in quote.c with the function relative_path. Function relative_path can be treated as an enhanced and more robust version of path_relative. Outputs of path_relative and it's replacement (relative_path) are the same for the following cases: path prefix output of path_relative output of relative_path ======== ========= ======================= ======================= /a/b/c/ /a/b/ c/ c/ /a/b/c /a/b/ c c /a/ /a/b/ ../ ../ / /a/b/ ../../ ../../ /a/c /a/b/ ../c ../c /x/y /a/b/ ../../x/y ../../x/y a/b/c/ a/b/ c/ c/ a/ a/b/ ../ ../ x/y a/b/ ../../x/y ../../x/y /a/b (empty) /a/b /a/b /a/b (null) /a/b /a/b a/b (empty) a/b a/b a/b (null) a/b a/b But if both of the path and the prefix are the same, or the returned relative path should be the current directory, the outputs of both functions are different. Function relative_path returns "./", while function path_relative returns empty string. path prefix output of path_relative output of relative_path ======== ========= ======================= ======================= /a/b/ /a/b/ (empty) ./ a/b/ a/b/ (empty) ./ (empty) (null) (empty) ./ (empty) (empty) (empty) ./ But the callers of path_relative can handle such cases, or never encounter this issue at all, because: * In function quote_path_relative, if the output of path_relative is empty, append "./" to it, like: if (!out->len) strbuf_addstr(out, "./"); * Another caller is write_name_quoted_relative, which is only used by builtin/ls-files.c. git-ls-files only show files, so path of files will never be identical with the prefix of a directory. The following differences show that path_relative does not handle extra slashes properly: path prefix output of path_relative output of relative_path ======== ========= ======================= ======================= /a//b//c/ //a/b// ../../../../a//b//c/ c/ a/b//c a//b ../b//c c And if prefix has no trailing slash, path_relative does not work properly either. But since prefix always has a trailing slash, it's not a problem. path prefix output of path_relative output of relative_path ======== ========= ======================= ======================= /a/b/c/ /a/b b/c/ c/ /a/b /a/b b ./ /a/b/ /a/b b/ ./ /a /a/b/ ../../a ../ a/b/c/ a/b b/c/ c/ a/b/ a/b b/ ./ a a/b ../a ../ x/y a/b/ ../x/y ../../x/y a/c a/b c ../c /a/ /a/b (empty) ../ (empty) /a/b ../../ ./ One tricky part in this conversion is write_name() function in ls-files.c. It takes a counted string, , that is to be made relative to and then quoted. Because write_name_quoted_relative() still takes these two parameters as counted string, but ignores the count and treat these two as NUL-terminated strings, this conversion needs to be audited for its callers: - For , all three callers of write_name() passes a NUL-terminated string and its true length, so this patch makes "len" unused. - For , prefix could be a string that is longer than empty while prefix_len could be 0 when "--full-name" option is used. This is fixed by checking prefix_len in write_name() and calling write_name_quoted_relative() with NULL when prefix_len is set to 0. Again, this makes "prefix_len" given to write_name_quoted_relative() unused, without introducing a bug. Signed-off-by: Jiang Xin Signed-off-by: Junio C Hamano --- builtin/ls-files.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'builtin/ls-files.c') diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 22020729cb..67e3713cd3 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -48,8 +48,13 @@ static const char *tag_resolve_undo = ""; static void write_name(const char* name, size_t len) { - write_name_quoted_relative(name, len, prefix, prefix_len, stdout, - line_terminator); + /* + * With "--full-name", prefix_len=0; write_name_quoted_relative() + * ignores prefix_len, so this caller needs to pass empty string + * in that case (a NULL is good for ""). + */ + write_name_quoted_relative(name, len, prefix_len ? prefix : NULL, + prefix_len, stdout, line_terminator); } static void show_dir_entry(const char *tag, struct dir_entry *ent) -- cgit v1.2.1 From 39598f9983f759b5e38b9e762c695bad6c89a1b3 Mon Sep 17 00:00:00 2001 From: Jiang Xin Date: Tue, 25 Jun 2013 23:53:45 +0800 Subject: quote_path_relative(): remove redundant parameter quote_path_relative() used to take a counted string as its parameter (the string to be quoted). With an earlier change, it now uses relative_path() that does not take a counted string, and we have been passing only the pointer to the string since then. Remove the length parameter from quote_path_relative() to show that this parameter was redundant. All the changed lines show that the caller passed either -1 (to ask the function run strlen() on the string), or the length of the string, so the earlier conversion was safe. All the callers of quote_path_relative() that used to take counted string have been audited to make sure that they are passing length of the actual string (or -1 to ask the callee run strlen()) Signed-off-by: Jiang Xin Signed-off-by: Junio C Hamano --- builtin/ls-files.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin/ls-files.c') diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 67e3713cd3..48c82e8e9b 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -394,7 +394,7 @@ int report_path_error(const char *ps_matched, const char **pathspec, const char if (found_dup) continue; - name = quote_path_relative(pathspec[num], -1, &sb, prefix); + name = quote_path_relative(pathspec[num], prefix, &sb); error("pathspec '%s' did not match any file(s) known to git.", name); errors++; -- cgit v1.2.1 From e9a820cefde2170840fbcdf7c4b74369988869dc Mon Sep 17 00:00:00 2001 From: Jiang Xin Date: Tue, 25 Jun 2013 23:53:46 +0800 Subject: write_name{_quoted_relative,}(): remove redundant parameters After substitute path_relative() in quote.c with relative_path() from path.c, parameters (such as len and prefix_len) are redundant in function write_name() and write_name_quoted_relative(). The callers have already been audited that the strings they pass are properly NUL terminated and the length they give are the length of the string (or -1 that asks the length to be counted by the callee). Remove these now-redundant parameters. Signed-off-by: Jiang Xin Signed-off-by: Junio C Hamano --- builtin/ls-files.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'builtin/ls-files.c') diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 48c82e8e9b..29d45b4f5a 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -46,15 +46,14 @@ static const char *tag_modified = ""; static const char *tag_skip_worktree = ""; static const char *tag_resolve_undo = ""; -static void write_name(const char* name, size_t len) +static void write_name(const char *name) { /* - * With "--full-name", prefix_len=0; write_name_quoted_relative() - * ignores prefix_len, so this caller needs to pass empty string - * in that case (a NULL is good for ""). + * With "--full-name", prefix_len=0; this caller needs to pass + * an empty string in that case (a NULL is good for ""). */ - write_name_quoted_relative(name, len, prefix_len ? prefix : NULL, - prefix_len, stdout, line_terminator); + write_name_quoted_relative(name, prefix_len ? prefix : NULL, + stdout, line_terminator); } static void show_dir_entry(const char *tag, struct dir_entry *ent) @@ -68,7 +67,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent) return; fputs(tag, stdout); - write_name(ent->name, ent->len); + write_name(ent->name); } static void show_other_files(struct dir_struct *dir) @@ -168,7 +167,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce) find_unique_abbrev(ce->sha1,abbrev), ce_stage(ce)); } - write_name(ce->name, ce_namelen(ce)); + write_name(ce->name); if (debug_mode) { printf(" ctime: %d:%d\n", ce->ce_ctime.sec, ce->ce_ctime.nsec); printf(" mtime: %d:%d\n", ce->ce_mtime.sec, ce->ce_mtime.nsec); @@ -201,7 +200,7 @@ static void show_ru_info(void) printf("%s%06o %s %d\t", tag_resolve_undo, ui->mode[i], find_unique_abbrev(ui->sha1[i], abbrev), i + 1); - write_name(path, len); + write_name(path); } } } -- cgit v1.2.1