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; 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); memcpy(line, text, i);
line[i] = 0; line[i] = 0;
@ -708,32 +712,43 @@ Cmd_CompleteCommand
============ ============
*/ */
char *Cmd_CompleteCommand(char *partial){ char *Cmd_CompleteCommand(char *partial){
cmd_function_t *cmd; cmd_function_t *cmd;
int len; cmdalias_t *a;
cmdalias_t *a; char *match = NULL;
int len;
len = strlen(partial); len = strlen(partial);
if(!len) if(!len)
return NULL; return NULL;
// check for exact match // check for exact match in commands
for(cmd = cmd_functions; cmd; cmd = cmd->next) for(cmd = cmd_functions; cmd; cmd = cmd->next)
if(!strcmp(partial, cmd->name)) if(!strcmp(partial, cmd->name))
return cmd->name; return cmd->name;
// and then aliases
for(a = cmd_alias; a; a = a->next) for(a = cmd_alias; a; a = a->next)
if(!strcmp(partial, a->name)) if(!strcmp(partial, a->name))
return a->name; return a->name;
// check for partial match // check for partial matches in commands
for(cmd = cmd_functions; cmd; cmd = cmd->next) for(cmd = cmd_functions; cmd; cmd = cmd->next){
if(!strncmp(partial, cmd->name, len)) if(!strncmp(partial, cmd->name, len)){
return cmd->name; Com_Printf("%c%s\n", (char)1, cmd->name);
for(a = cmd_alias; a; a = a->next) match = cmd->name;
if(!strncmp(partial, a->name, len)) }
return a->name; }
return NULL; // 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){ char *Cvar_CompleteVariable(char *partial){
cvar_t *cvar; cvar_t *cvar;
int len; char *match = NULL;
int len;
len = strlen(partial); len = strlen(partial);
if(!len) if(!len)
return NULL; return NULL;
// check exact match // check for exact match
for(cvar = cvar_vars; cvar; cvar = cvar->next) for(cvar = cvar_vars; cvar; cvar = cvar->next)
if(!strcmp(partial, cvar->name)) if(!strcmp(partial, cvar->name))
return cvar->name; return cvar->name;
// check partial match // check for partial matches
for(cvar = cvar_vars; cvar; cvar = cvar->next) for(cvar = cvar_vars; cvar; cvar = cvar->next){
if(!strncmp(partial, cvar->name, len)) if(!strncmp(partial, cvar->name, len)){
return cvar->name; Com_Printf("%s\n", cvar->name);
match = cvar->name;
}
}
return NULL; return match;
} }

View file

@ -167,16 +167,27 @@ keyname_t keynames[] = {
*/ */
void CompleteCommand(void){ void CompleteCommand(void){
char *cmd, *s; char *cmd, *cvar, *partial;
s = key_lines[edit_line] + 1; partial = key_lines[edit_line] + 1;
if(*s == '\\' || *s == '/') if(*partial == '\\' || *partial == '/')
s++; partial++;
cmd = Cmd_CompleteCommand(s); if(!*partial) return; //lets start with at least something
if(!cmd)
cmd = Cvar_CompleteVariable(s); cmd = Cmd_CompleteCommand(partial); //partial command lookup
if(cmd){
if(!cmd || strcmp(cmd, partial)){ //not exact command match
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] = '/'; key_lines[edit_line][1] = '/';
strcpy(key_lines[edit_line] + 2, cmd); strcpy(key_lines[edit_line] + 2, cmd);
key_linepos = strlen(cmd) + 2; key_linepos = strlen(cmd) + 2;