tex: prevent buffer overflow after expanding % and # - neatvi - [fork] simple v… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit 86745f7e230cc2ceb023cab75ff3105d713bb6d6 | |
parent 3932f52736caa572c60ab3dae7b5302ce361146a | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Fri, 24 Sep 2021 12:27:39 +0330 | |
ex: prevent buffer overflow after expanding % and # | |
Diffstat: | |
M ex.c | 59 +++++++++++++++++++----------… | |
1 file changed, 37 insertions(+), 22 deletions(-) | |
--- | |
diff --git a/ex.c b/ex.c | |
t@@ -149,7 +149,7 @@ static char *ex_cmd(char *src, char *cmd) | |
src = ex_loc(src, cmd); | |
while (*src == ' ' || *src == '\t') | |
src++; | |
- while (isalpha((unsigned char) *src)) | |
+ while (isalpha((unsigned char) *src) && cmd < cmd0 + 16) | |
if ((*cmd++ = *src++) == 'k' && cmd == cmd0 + 1) | |
break; | |
if (*src == '!' || *src == '=') | |
t@@ -159,35 +159,35 @@ static char *ex_cmd(char *src, char *cmd) | |
} | |
/* read ex file argument */ | |
-static char *ex_filearg(char *src, char *dst, int spaceallowed) | |
+static char *ex_filearg(char *src, int spaceallowed) | |
{ | |
+ struct sbuf *sb = sbuf_make(); | |
while (*src && *src != '\n' && (spaceallowed || (*src != ' ' && *src !… | |
if (*src == '%') { | |
if (!bufs[0].path || !bufs[0].path[0]) { | |
ex_show("\"%\" is unset\n"); | |
+ sbuf_free(sb); | |
return NULL; | |
} | |
- strcpy(dst, bufs[0].path); | |
- dst = strchr(dst, '\0'); | |
+ sbuf_str(sb, bufs[0].path); | |
src++; | |
continue; | |
} | |
if (*src == '#') { | |
if (!bufs[1].path || !bufs[1].path[0]) { | |
ex_show("\"#\" is unset\n"); | |
+ sbuf_free(sb); | |
return NULL; | |
} | |
- strcpy(dst, bufs[1].path); | |
- dst = strchr(dst, '\0'); | |
+ sbuf_str(sb, bufs[1].path); | |
src++; | |
continue; | |
} | |
if (*src == '\\' && src[1]) | |
src++; | |
- *dst++ = *src++; | |
+ sbuf_chr(sb, *src++); | |
} | |
- *dst = '\0'; | |
- return src; | |
+ return sbuf_done(sb); | |
} | |
/* the previous search keyword */ | |
t@@ -372,17 +372,18 @@ static int ec_edit(char *ec) | |
char msg[128]; | |
char cmd[EXLEN]; | |
char arg[EXLEN]; | |
- char path[EXLEN]; | |
+ char *path; | |
int fd; | |
ex_cmd(ec, cmd); | |
ex_arg(ec, arg); | |
- if (!ex_filearg(arg, path, 0)) | |
- return 1; | |
if (!strchr(cmd, '!')) | |
if (xb && ex_modifiedbuffer("buffer modified\n")) | |
return 1; | |
+ if (!(path = ex_filearg(arg, 0))) | |
+ return 1; | |
if (path[0] && bufs_find(path) >= 0) { | |
bufs_switch(bufs_find(path)); | |
+ free(path); | |
return 0; | |
} | |
if (path[0] || !bufs[0].path) | |
t@@ -403,6 +404,7 @@ static int ec_edit(char *ec) | |
xrow = MAX(0, MIN(xrow, lbuf_len(xb) - 1)); | |
xoff = 0; | |
xtop = MAX(0, MIN(xtop, lbuf_len(xb) - 1)); | |
+ free(path); | |
return 0; | |
} | |
t@@ -421,12 +423,13 @@ static int ec_read(char *ec) | |
return 1; | |
if (arg[0] == '!') { | |
int pos = MIN(xrow + 1, lbuf_len(xb)); | |
- char ecmd[EXLEN * 2]; | |
- if (!ex_filearg(arg, ecmd, 1)) | |
+ char *ecmd = ex_filearg(arg, 1); | |
+ if (!ecmd) | |
return 1; | |
obuf = cmd_pipe(ecmd + 1, NULL, 0, 1); | |
if (obuf) | |
lbuf_edit(xb, obuf, pos, pos); | |
+ free(ecmd); | |
free(obuf); | |
} else { | |
int fd = open(path, O_RDONLY); | |
t@@ -469,12 +472,13 @@ static int ec_write(char *ec) | |
end = lbuf_len(xb); | |
} | |
if (arg[0] == '!') { | |
- char ecmd[EXLEN * 2]; | |
- if (!ex_filearg(arg, ecmd, 1)) | |
+ char *ecmd = ex_filearg(arg, 1); | |
+ if (!ecmd) | |
return 1; | |
ibuf = lbuf_cp(xb, beg, end); | |
ex_print(NULL); | |
cmd_pipe(ecmd + 1, ibuf, 1, 0); | |
+ free(ecmd); | |
free(ibuf); | |
} else { | |
int fd; | |
t@@ -751,25 +755,31 @@ static int ec_exec(char *ec) | |
{ | |
char loc[EXLEN]; | |
char arg[EXLEN]; | |
- char ecmd[EXLEN * 2]; | |
int beg, end; | |
char *text; | |
char *rep; | |
+ char *ecmd; | |
ex_modifiedbuffer(NULL); | |
ex_loc(ec, loc); | |
ex_arg(ec, arg); | |
- if (!ex_filearg(arg, ecmd, 1)) | |
+ if (!(ecmd = ex_filearg(arg, 1))) | |
return 1; | |
if (!loc[0]) { | |
+ int ret; | |
ex_print(NULL); | |
- return cmd_exec(ecmd); | |
+ ret = cmd_exec(ecmd); | |
+ free(ecmd); | |
+ return ret; | |
} | |
- if (ex_region(loc, &beg, &end)) | |
+ if (ex_region(loc, &beg, &end)) { | |
+ free(ecmd); | |
return 1; | |
+ } | |
text = lbuf_cp(xb, beg, end); | |
rep = cmd_pipe(ecmd, text, 1, 1); | |
if (rep) | |
lbuf_edit(xb, rep, beg, end); | |
+ free(ecmd); | |
free(text); | |
free(rep); | |
return 0; | |
t@@ -779,12 +789,13 @@ static int ec_make(char *ec) | |
{ | |
char arg[EXLEN]; | |
char make[EXLEN]; | |
- char target[EXLEN * 2]; | |
+ char *target; | |
ex_modifiedbuffer(NULL); | |
ex_arg(ec, arg); | |
- if (!ex_filearg(arg, target, 0)) | |
+ if (!(target = ex_filearg(arg, 0))) | |
return 1; | |
sprintf(make, "make %s", target); | |
+ free(target); | |
ex_print(NULL); | |
if (cmd_exec(make)) | |
return 1; | |
t@@ -1049,6 +1060,10 @@ static int ex_exec(char *ln) | |
int ret = 0; | |
while (*ln) { | |
ex_cmd(ln, cmd); | |
+ if (strlen(ln) >= EXLEN) { | |
+ ex_show("command too long"); | |
+ return 1; | |
+ } | |
ln = ex_line(ln, ec); | |
if ((idx = ex_idx(cmd)) >= 0) | |
ret = excmds[idx].ec(ec); |