Fix crash and memory leak in $aliasctl(COMMAND MATCH)
glob_commands() would run off the end of the irc_command array if given a match that matched the last command. It also leaked memory because it used m_s3cat() to construct the string, then passed that to m_strdup(). This fixes these problems by reworking glob_commands(), and at the same time removes the use of alloca() and wild_match() by using strncmp() instead to match the start of a string. Move glob_commands() to alias.c and make it static since it's only used for aliasctl(). Change the 'name' argument of find_command() and find_dll_command() to const char * at the same time, so that glob_commands()'s prefix argument can be const char * too.
This commit is contained in:
@@ -2227,14 +2227,36 @@ char *lookup_member(char *varname, char *var_args, char *ptr, char *args)
|
||||
|
||||
/****************************** ALIASCTL ************************************/
|
||||
#define EMPTY empty_string
|
||||
#define RETURN_EMPTY return m_strdup(EMPTY)
|
||||
#define EMPTY_STRING m_strdup(EMPTY)
|
||||
#define RETURN_EMPTY return EMPTY_STRING
|
||||
#define RETURN_IF_EMPTY(x) if (empty( x )) RETURN_EMPTY
|
||||
#define GET_INT_ARG(x, y) {RETURN_IF_EMPTY(y); x = my_atol(safe_new_next_arg(y, &y));}
|
||||
#define GET_FLOAT_ARG(x, y) {RETURN_IF_EMPTY(y); x = atof(safe_new_next_arg(y, &y));}
|
||||
#define GET_STR_ARG(x, y) {RETURN_IF_EMPTY(y); x = new_next_arg(y, &y);RETURN_IF_EMPTY(x);}
|
||||
#define RETURN_STR(x) return m_strdup(x ? x : EMPTY)
|
||||
#define RETURN_MSTR(x) return ((x) ? (x) : EMPTY_STRING)
|
||||
#define RETURN_INT(x) return m_strdup(ltoa(x));
|
||||
|
||||
/* glob_commands()
|
||||
* Returns a space-separated list of commands beginning with 'prefix'.
|
||||
*/
|
||||
static char *glob_commands(const char *prefix, int *cnt)
|
||||
{
|
||||
IrcCommand *var;
|
||||
char *mylist = NULL;
|
||||
const size_t prefix_len = strlen(prefix);
|
||||
|
||||
*cnt = 0;
|
||||
/* let's do a command completion here */
|
||||
for (var = find_command(prefix, cnt);
|
||||
var && var->name && !strncmp(prefix, var->name, prefix_len);
|
||||
var++)
|
||||
{
|
||||
m_s3cat(&mylist, space, var->name);
|
||||
}
|
||||
RETURN_MSTR(mylist);
|
||||
}
|
||||
|
||||
/* Used by function_aliasctl */
|
||||
/* MUST BE FIXED */
|
||||
BUILT_IN_FUNCTION(aliasctl)
|
||||
@@ -2321,7 +2343,7 @@ BUILT_IN_FUNCTION(aliasctl)
|
||||
else if (list == VAR_ALIAS)
|
||||
mlist = glob_assign_alias(listc, &num);
|
||||
else if (list == -1)
|
||||
return glob_commands(listc, &num, 0);
|
||||
return glob_commands(listc, &num);
|
||||
|
||||
for (ctr = 0; ctr < num; ctr++)
|
||||
{
|
||||
@@ -2345,7 +2367,7 @@ BUILT_IN_FUNCTION(aliasctl)
|
||||
else if (list == VAR_ALIAS)
|
||||
mlist = pmatch_assign_alias(listc, &num);
|
||||
else if (list == -1)
|
||||
return glob_commands(listc, &num, 1);
|
||||
return glob_commands(listc, &num);
|
||||
|
||||
for (ctr = 0; ctr < num; ctr++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user