mirror of
https://git.code.sf.net/p/quake/quake2forge
synced 2024-11-10 07:12:01 +00:00
Fixed potential buffer overflow in Cbuf_Execute, and implemented more Unix-like cmd/cvar tab completion.
This commit is contained in:
parent
7bae893bd2
commit
9fa7e5e7ba
3 changed files with 62 additions and 32 deletions
39
src/cmd.c
39
src/cmd.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
20
src/cvar.c
20
src/cvar.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
27
src/keys.c
27
src/keys.c
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue