Fixed potential buffer overflow in Cbuf_Execute, and implemented more Unix-like cmd/cvar tab completion.

This commit is contained in:
Jay Dolan 2006-01-14 19:00:50 +00:00
parent 7bae893bd2
commit 9fa7e5e7ba
3 changed files with 62 additions and 32 deletions

View File

@ -201,6 +201,10 @@ void Cbuf_Execute(void){
break;
}
if(i > MAX_STRING_CHARS){ //length check each command
Com_Printf("Command exceeded %i chars, discarded\n", MAX_STRING_CHARS);
return;
}
memcpy(line, text, i);
line[i] = 0;
@ -708,32 +712,43 @@ Cmd_CompleteCommand
============
*/
char *Cmd_CompleteCommand(char *partial){
cmd_function_t *cmd;
int len;
cmdalias_t *a;
cmd_function_t *cmd;
cmdalias_t *a;
char *match = NULL;
int len;
len = strlen(partial);
if(!len)
return NULL;
// check for exact match
// check for exact match in commands
for(cmd = cmd_functions; cmd; cmd = cmd->next)
if(!strcmp(partial, cmd->name))
return cmd->name;
// and then aliases
for(a = cmd_alias; a; a = a->next)
if(!strcmp(partial, a->name))
return a->name;
// check for partial match
for(cmd = cmd_functions; cmd; cmd = cmd->next)
if(!strncmp(partial, cmd->name, len))
return cmd->name;
for(a = cmd_alias; a; a = a->next)
if(!strncmp(partial, a->name, len))
return a->name;
return NULL;
// check for partial matches in commands
for(cmd = cmd_functions; cmd; cmd = cmd->next){
if(!strncmp(partial, cmd->name, len)){
Com_Printf("%c%s\n", (char)1, cmd->name);
match = cmd->name;
}
}
// and then aliases
for(a = cmd_alias; a; a = a->next){
if(!strncmp(partial, a->name, len)){
Com_Printf("%c%s\n", (char)1, a->name);
match = a->name;
}
}
return match;
}

View File

@ -89,25 +89,29 @@ Cvar_CompleteVariable
============
*/
char *Cvar_CompleteVariable(char *partial){
cvar_t *cvar;
int len;
cvar_t *cvar;
char *match = NULL;
int len;
len = strlen(partial);
if(!len)
return NULL;
// check exact match
// check for exact match
for(cvar = cvar_vars; cvar; cvar = cvar->next)
if(!strcmp(partial, cvar->name))
return cvar->name;
// check partial match
for(cvar = cvar_vars; cvar; cvar = cvar->next)
if(!strncmp(partial, cvar->name, len))
return cvar->name;
return NULL;
// check for partial matches
for(cvar = cvar_vars; cvar; cvar = cvar->next){
if(!strncmp(partial, cvar->name, len)){
Com_Printf("%s\n", cvar->name);
match = cvar->name;
}
}
return match;
}

View File

@ -167,16 +167,27 @@ keyname_t keynames[] = {
*/
void CompleteCommand(void){
char *cmd, *s;
char *cmd, *cvar, *partial;
s = key_lines[edit_line] + 1;
if(*s == '\\' || *s == '/')
s++;
partial = key_lines[edit_line] + 1;
if(*partial == '\\' || *partial == '/')
partial++;
if(!*partial) return; //lets start with at least something
cmd = Cmd_CompleteCommand(partial); //partial command lookup
if(!cmd || strcmp(cmd, partial)){ //not exact command match
cmd = Cmd_CompleteCommand(s);
if(!cmd)
cmd = Cvar_CompleteVariable(s);
if(cmd){
cvar = Cvar_CompleteVariable(partial); //so try cvars
if(cvar){ //found something
if(!strcmp(cvar, partial)) cmd = cvar; //exact cvar match
else cmd = NULL; //no exact match, partial for both
}
}
if(cmd){ //found something
key_lines[edit_line][1] = '/';
strcpy(key_lines[edit_line] + 2, cmd);
key_linepos = strlen(cmd) + 2;