From eefb116b6a88415e4a9e9a1d94f12781853df376 Mon Sep 17 00:00:00 2001 From: "R. Steve McKown" Date: Tue, 4 Dec 2012 13:43:58 -0700 Subject: [PATCH] Fix improper handling of repo_groups sections When parsing repo_groups ini entries, repo_shell was calling strip_repo() on the entry value, then calling str_has_word() to see if the desired repo was in the list of words represented by the ini value. Of course this is wrong, each token in the value string must have strip_repo() called upon it instead. The solution: * Move strip_repo() to stringutils.c * Add str_has_repo(), when can call strip_repo() on each token in its string. --- git_acl.c | 24 +----------------------- stringutils.c | 37 +++++++++++++++++++++++++++++++++++++ stringutils.h | 14 ++++++++++++++ 3 files changed, 52 insertions(+), 23 deletions(-) diff --git a/git_acl.c b/git_acl.c index 9c39ec2..8783874 100644 --- a/git_acl.c +++ b/git_acl.c @@ -107,26 +107,6 @@ static acl_clear(acl_t *acl) stra_destroy(&acl->userids); } -/* git tools match /path/to/repo against /path/to/repo.git when the former - * doesn't exist and the latter does. repo_shell addresses this by stripping - * the .git prefix off all repopath's read in from .gitacls and the SSH comand - * line. This mimics the expected git tool behavior except when /path/to/repo - * and /path/to/repo.git both exist. This case shouldn't ever be seen anyway. - */ -static char *strip_repo(const char *repo_name) -{ - if (!repo_name) - return NULL; - else { - char *dot = rindex(repo_name, '.'); - - if (dot && !strcmp(dot, ".git")) - return xstrndup(repo_name, dot - repo_name); - else - return xstrdup(repo_name); - } -} - static int acl_handler(void* user, const char* section, const char* name, const char* value) { @@ -143,12 +123,10 @@ static int acl_handler(void* user, const char* section, const char* name, stra_add(&acl->userids, name); } } else if (!strcmp(section, "repo_groups")) { - char *v = strip_repo(value); - if (str_has_word(v, acl->repo)) { + if (str_has_repo(value, acl->repo)) { //debug("repoids += '%s'", name); stra_add(&acl->repoids, name); } - free(v); } else if (!strncmp(section, "repo", 4)) { char *_p = xstrdup(section + 4); char *p = _p; diff --git a/stringutils.c b/stringutils.c index 8249d86..08afc45 100644 --- a/stringutils.c +++ b/stringutils.c @@ -75,3 +75,40 @@ bool str_has_word(const char* string, const char* word) free(_s); return false; } + +char *strip_repo(const char *repo_name) +{ + if (!repo_name) + return NULL; + else { + char *dot = rindex(repo_name, '.'); + + if (dot && !strcmp(dot, ".git")) + return xstrndup(repo_name, dot - repo_name); + else + return xstrdup(repo_name); + } +} + +bool str_has_repo(const char* string, const char* repo) +{ + char *_s = xstrdup(string); + char *s = _s; + char *p = my_strtok(&s, " \t\n"); + char *r = strip_repo(repo); + + while (p) { + char *q = strip_repo(p); + if (match(q, r)) { + free(q); + free(r); + free(_s); + return true; + } + free(q); + p = my_strtok(&s, " \t\n"); + } + free(r); + free(_s); + return false; +} diff --git a/stringutils.h b/stringutils.h index 16731dd..634745d 100644 --- a/stringutils.h +++ b/stringutils.h @@ -40,4 +40,18 @@ bool str_has_word(const char* string, const char* word); */ bool match(const char* pattern, const char* string); +/* git tools match /path/to/repo against /path/to/repo.git when the former + * doesn't exist and the latter does. repo_shell addresses this by stripping + * the .git prefix off all repopath's read in from .gitacls and the SSH comand + * line. This mimics the expected git tool behavior except when /path/to/repo + * and /path/to/repo.git both exist. This case shouldn't ever be seen anyway. + */ +char *strip_repo(const char *repo_name); + +/* Returns true if the repo is contained within string. repos are delimited by + * any whitespace characters, and the optional '.git' prefix is ignored during + * match. + */ +bool str_has_repo(const char* string, const char* repo); + #endif /* end of include guard: MYSTRTOK_H */ -- 2.39.2