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 1.2.3-korg 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/clean.c | 18 +++++++++--------- builtin/grep.c | 5 ++--- builtin/ls-files.c | 2 +- quote.c | 7 ++----- quote.h | 4 ++-- wt-status.c | 17 ++++++++--------- 6 files changed, 24 insertions(+), 29 deletions(-) (limited to 'builtin/ls-files.c') diff --git a/builtin/clean.c b/builtin/clean.c index 04e396b17a..f77f95d7ad 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -56,7 +56,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag, if ((force_flag & REMOVE_DIR_KEEP_NESTED_GIT) && !resolve_gitlink_ref(path->buf, "HEAD", submodule_head)) { if (!quiet) { - quote_path_relative(path->buf, strlen(path->buf), "ed, prefix); + quote_path_relative(path->buf, prefix, "ed); printf(dry_run ? _(msg_would_skip_git_dir) : _(msg_skip_git_dir), quoted.buf); } @@ -70,7 +70,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag, /* an empty dir could be removed even if it is unreadble */ res = dry_run ? 0 : rmdir(path->buf); if (res) { - quote_path_relative(path->buf, strlen(path->buf), "ed, prefix); + quote_path_relative(path->buf, prefix, "ed); warning(_(msg_warn_remove_failed), quoted.buf); *dir_gone = 0; } @@ -94,7 +94,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag, if (remove_dirs(path, prefix, force_flag, dry_run, quiet, &gone)) ret = 1; if (gone) { - quote_path_relative(path->buf, strlen(path->buf), "ed, prefix); + quote_path_relative(path->buf, prefix, "ed); string_list_append(&dels, quoted.buf); } else *dir_gone = 0; @@ -102,10 +102,10 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag, } else { res = dry_run ? 0 : unlink(path->buf); if (!res) { - quote_path_relative(path->buf, strlen(path->buf), "ed, prefix); + quote_path_relative(path->buf, prefix, "ed); string_list_append(&dels, quoted.buf); } else { - quote_path_relative(path->buf, strlen(path->buf), "ed, prefix); + quote_path_relative(path->buf, prefix, "ed); warning(_(msg_warn_remove_failed), quoted.buf); *dir_gone = 0; ret = 1; @@ -127,7 +127,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag, if (!res) *dir_gone = 1; else { - quote_path_relative(path->buf, strlen(path->buf), "ed, prefix); + quote_path_relative(path->buf, prefix, "ed); warning(_(msg_warn_remove_failed), quoted.buf); *dir_gone = 0; ret = 1; @@ -262,7 +262,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix) if (remove_dirs(&directory, prefix, rm_flags, dry_run, quiet, &gone)) errors++; if (gone && !quiet) { - qname = quote_path_relative(directory.buf, directory.len, &buf, prefix); + qname = quote_path_relative(directory.buf, prefix, &buf); printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname); } } @@ -272,11 +272,11 @@ int cmd_clean(int argc, const char **argv, const char *prefix) continue; res = dry_run ? 0 : unlink(ent->name); if (res) { - qname = quote_path_relative(ent->name, -1, &buf, prefix); + qname = quote_path_relative(ent->name, prefix, &buf); warning(_(msg_warn_remove_failed), qname); errors++; } else if (!quiet) { - qname = quote_path_relative(ent->name, -1, &buf, prefix); + qname = quote_path_relative(ent->name, prefix, &buf); printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname); } } diff --git a/builtin/grep.c b/builtin/grep.c index 159e65d47a..a419cda729 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -286,8 +286,7 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1, struct strbuf pathbuf = STRBUF_INIT; if (opt->relative && opt->prefix_length) { - quote_path_relative(filename + tree_name_len, -1, &pathbuf, - opt->prefix); + quote_path_relative(filename + tree_name_len, opt->prefix, &pathbuf); strbuf_insert(&pathbuf, 0, filename, tree_name_len); } else { strbuf_addstr(&pathbuf, filename); @@ -318,7 +317,7 @@ static int grep_file(struct grep_opt *opt, const char *filename) struct strbuf buf = STRBUF_INIT; if (opt->relative && opt->prefix_length) - quote_path_relative(filename, -1, &buf, opt->prefix); + quote_path_relative(filename, opt->prefix, &buf); else strbuf_addstr(&buf, filename); 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++; diff --git a/quote.c b/quote.c index 64ff344158..ebb835923f 100644 --- a/quote.c +++ b/quote.c @@ -325,8 +325,8 @@ void write_name_quoted_relative(const char *name, size_t len, } /* quote path as relative to the given prefix */ -char *quote_path_relative(const char *in, int len, - struct strbuf *out, const char *prefix) +char *quote_path_relative(const char *in, const char *prefix, + struct strbuf *out) { struct strbuf sb = STRBUF_INIT; const char *rel = relative_path(in, prefix, &sb); @@ -334,9 +334,6 @@ char *quote_path_relative(const char *in, int len, quote_c_style_counted(rel, strlen(rel), out, NULL, 0); strbuf_release(&sb); - if (!out->len) - strbuf_addstr(out, "./"); - return out->buf; } diff --git a/quote.h b/quote.h index 133155a48b..5610159c59 100644 --- a/quote.h +++ b/quote.h @@ -65,8 +65,8 @@ extern void write_name_quoted_relative(const char *name, size_t len, FILE *fp, int terminator); /* quote path as relative to the given prefix */ -extern char *quote_path_relative(const char *in, int len, - struct strbuf *out, const char *prefix); +extern char *quote_path_relative(const char *in, const char *prefix, + struct strbuf *out); /* quoting as a string literal for other languages */ extern void perl_quote_print(FILE *stream, const char *src); diff --git a/wt-status.c b/wt-status.c index bf84a86ee3..ef0fc4bb49 100644 --- a/wt-status.c +++ b/wt-status.c @@ -243,7 +243,7 @@ static void wt_status_print_unmerged_data(struct wt_status *s, struct strbuf onebuf = STRBUF_INIT; const char *one, *how = _("bug"); - one = quote_path(it->string, -1, &onebuf, s->prefix); + one = quote_path(it->string, s->prefix, &onebuf); status_printf(s, color(WT_STATUS_HEADER, s), "\t"); switch (d->stagemask) { case 1: how = _("both deleted:"); break; @@ -297,8 +297,8 @@ static void wt_status_print_change_data(struct wt_status *s, change_type); } - one = quote_path(one_name, -1, &onebuf, s->prefix); - two = quote_path(two_name, -1, &twobuf, s->prefix); + one = quote_path(one_name, s->prefix, &onebuf); + two = quote_path(two_name, s->prefix, &twobuf); status_printf(s, color(WT_STATUS_HEADER, s), "\t"); switch (status) { @@ -706,8 +706,7 @@ static void wt_status_print_other(struct wt_status *s, struct string_list_item *it; const char *path; it = &(l->items[i]); - path = quote_path(it->string, strlen(it->string), - &buf, s->prefix); + path = quote_path(it->string, s->prefix, &buf); if (column_active(s->colopts)) { string_list_append(&output, path); continue; @@ -1289,7 +1288,7 @@ static void wt_shortstatus_unmerged(struct string_list_item *it, } else { struct strbuf onebuf = STRBUF_INIT; const char *one; - one = quote_path(it->string, -1, &onebuf, s->prefix); + one = quote_path(it->string, s->prefix, &onebuf); printf(" %s\n", one); strbuf_release(&onebuf); } @@ -1317,7 +1316,7 @@ static void wt_shortstatus_status(struct string_list_item *it, struct strbuf onebuf = STRBUF_INIT; const char *one; if (d->head_path) { - one = quote_path(d->head_path, -1, &onebuf, s->prefix); + one = quote_path(d->head_path, s->prefix, &onebuf); if (*one != '"' && strchr(one, ' ') != NULL) { putchar('"'); strbuf_addch(&onebuf, '"'); @@ -1326,7 +1325,7 @@ static void wt_shortstatus_status(struct string_list_item *it, printf("%s -> ", one); strbuf_release(&onebuf); } - one = quote_path(it->string, -1, &onebuf, s->prefix); + one = quote_path(it->string, s->prefix, &onebuf); if (*one != '"' && strchr(one, ' ') != NULL) { putchar('"'); strbuf_addch(&onebuf, '"'); @@ -1345,7 +1344,7 @@ static void wt_shortstatus_other(struct string_list_item *it, } else { struct strbuf onebuf = STRBUF_INIT; const char *one; - one = quote_path(it->string, -1, &onebuf, s->prefix); + one = quote_path(it->string, s->prefix, &onebuf); color_fprintf(s->fp, color(WT_STATUS_UNTRACKED, s), "%s", sign); printf(" %s\n", one); strbuf_release(&onebuf); -- cgit 1.2.3-korg 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 ++++++++--------- quote.c | 3 +-- quote.h | 3 +-- 3 files changed, 10 insertions(+), 13 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); } } } diff --git a/quote.c b/quote.c index ebb835923f..5c8808160e 100644 --- a/quote.c +++ b/quote.c @@ -312,8 +312,7 @@ void write_name_quotedpfx(const char *pfx, size_t pfxlen, fputc(terminator, fp); } -void write_name_quoted_relative(const char *name, size_t len, - const char *prefix, size_t prefix_len, +void write_name_quoted_relative(const char *name, const char *prefix, FILE *fp, int terminator) { struct strbuf sb = STRBUF_INIT; diff --git a/quote.h b/quote.h index 5610159c59..ed110a5d8d 100644 --- a/quote.h +++ b/quote.h @@ -60,8 +60,7 @@ extern void quote_two_c_style(struct strbuf *, const char *, const char *, int); extern void write_name_quoted(const char *name, FILE *, int terminator); extern void write_name_quotedpfx(const char *pfx, size_t pfxlen, const char *name, FILE *, int terminator); -extern void write_name_quoted_relative(const char *name, size_t len, - const char *prefix, size_t prefix_len, +extern void write_name_quoted_relative(const char *name, const char *prefix, FILE *fp, int terminator); /* quote path as relative to the given prefix */ -- cgit 1.2.3-korg