From: Jonathan Rose Date: Fri, 15 Apr 2011 14:58:37 +0000 (+0000) Subject: Fix a Tab Completion bug that occurs due to multiple matches on a substring. X-Git-Tag: 1.6.2.19-rc1~3^2~58 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4751ddd44e3af04a11299c612a1c22a7083dd184;p=thirdparty%2Fasterisk.git Fix a Tab Completion bug that occurs due to multiple matches on a substring. Makes word_match function in cli.c repeat a search for a command string until a proper match is found or the string is searched to the last point. (closes issue #17494) Reported by: ffossard Review: https://reviewboard.asterisk.org/r/1180/ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.2@313859 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/main/cli.c b/main/cli.c index b2638cc48f..ea37e087e1 100644 --- a/main/cli.c +++ b/main/cli.c @@ -1747,20 +1747,30 @@ static int word_match(const char *cmd, const char *cli_word) return -1; if (!strchr(cli_rsvd, cli_word[0])) /* normal match */ return (strcasecmp(cmd, cli_word) == 0) ? 1 : -1; - /* regexp match, takes [foo|bar] or {foo|bar} */ l = strlen(cmd); /* wildcard match - will extend in the future */ if (l > 0 && cli_word[0] == '%') { return 1; /* wildcard */ } + + /* Start a search for the command entered against the cli word in question */ pos = strcasestr(cli_word, cmd); - if (pos == NULL) /* not found, say ok if optional */ - return cli_word[0] == '[' ? 0 : -1; - if (pos == cli_word) /* no valid match at the beginning */ - return -1; - if (strchr(cli_rsvd, pos[-1]) && strchr(cli_rsvd, pos[l])) - return 1; /* valid match */ - return -1; /* not found */ + while (pos) { + + /* + *Check if the word matched with is surrounded by reserved characters on both sides + * and isn't at the beginning of the cli_word since that would make it check in a location we shouldn't know about. + * If it is surrounded by reserved chars and isn't at the beginning, it's a match. + */ + if (pos != cli_word && strchr(cli_rsvd, pos[-1]) && strchr(cli_rsvd, pos[l])) { + return 1; /* valid match */ + } + + /* Ok, that one didn't match, strcasestr to the next appearance of the command and start over.*/ + pos = strcasestr(pos + 1, cmd); + } + /* If no matches were found over the course of the while loop, we hit the end of the string. It's a mismatch. */ + return -1; } /*! \brief if word is a valid prefix for token, returns the pos-th