From e3a6003647b28971d83ad14756d1c1e05281eb59 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Sat, 25 Oct 2008 21:29:51 +0200 Subject: [PATCH] Refuse to open a directory in the status and stage view Adds suffixcmp() used for checking if the status entry name ends with "/". Also use it for repository reference loading. --- NEWS | 1 + tig.c | 24 ++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index a0f75c6..47b5af8 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,7 @@ Bug fixes: - Separate blame revision and file argument by "--" to avoid problems. - Main view: fix redrawing of the last commit wrt. the revision graph. - Fix waiting for input after executing a run request in pager mode. + - Status & stage view: refuse to open directories. tig-0.12.1 ---------- diff --git a/tig.c b/tig.c index 3394d40..041e282 100644 --- a/tig.c +++ b/tig.c @@ -280,6 +280,15 @@ string_enum_compare(const char *str1, const char *str2, int len) #define prefixcmp(str1, str2) \ strncmp(str1, str2, STRING_SIZE(str2)) +static inline int +suffixcmp(const char *str, int slen, const char *suffix) +{ + size_t len = slen >= 0 ? slen : strlen(str); + size_t suffixlen = strlen(suffix); + + return suffixlen < len ? strcmp(str + len - suffixlen, suffix) : -1; +} + /* Shell quoting * * NOTE: The following is a slightly modified copy of the git project's shell @@ -4191,6 +4200,11 @@ status_enter(struct view *view, struct line *line) return REQ_NONE; } + if (!suffixcmp(status->new.name, -1, "/")) { + report("Cannot display a directory"); + return REQ_NONE; + } + opt_pipe = fopen(status->new.name, "r"); info = "Untracked file %s"; break; @@ -4771,8 +4785,14 @@ stage_request(struct view *view, enum request request, struct line *line) if (!status_exists(&stage_status, stage_line_type)) return REQ_VIEW_CLOSE; - if (stage_line_type == LINE_STAT_UNTRACKED) + if (stage_line_type == LINE_STAT_UNTRACKED) { + if (!suffixcmp(stage_status.new.name, -1, "/")) { + report("Cannot display a directory"); + return REQ_NONE; + } + opt_pipe = fopen(stage_status.new.name, "r"); + } open_view(view, REQ_VIEW_STAGE, OPEN_REFRESH); return REQ_NONE; @@ -5779,7 +5799,7 @@ read_ref(char *id, size_t idlen, char *name, size_t namelen) bool head = FALSE; if (!prefixcmp(name, "refs/tags/")) { - if (!strcmp(name + namelen - 3, "^{}")) { + if (!suffixcmp(name, namelen, "^{}")) { namelen -= 3; name[namelen] = 0; if (refs_size > 0 && refs[refs_size - 1].ltag == TRUE) -- 2.30.2