summaryrefslogtreecommitdiff
path: root/shells/pdksh/files/vi.c
diff options
context:
space:
mode:
authortnn <tnn@pkgsrc.org>2008-05-31 16:47:36 +0000
committertnn <tnn@pkgsrc.org>2008-05-31 16:47:36 +0000
commit07f2d7c8b3668b5b03e53d79519d48b22c7f6ce3 (patch)
tree148a3174dd13953fbaa9a00d98253dea52297fd9 /shells/pdksh/files/vi.c
parent69f6bb8dbc4daf959d342154179c9d338d1acac0 (diff)
downloadpkgsrc-07f2d7c8b3668b5b03e53d79519d48b22c7f6ce3.tar.gz
Merge assorted bugfixes to pdksh-5.2.14, taken as diff between
PDKSH-5_2_14 and NetBSD-current HEAD as of 2008-05-31. - Fixes rare segfault seen on Solaris. - add strlcpy and strlcat fallback implementations from libnbcompat - regenerate configure (using autoconf-2.12, ugh)
Diffstat (limited to 'shells/pdksh/files/vi.c')
-rw-r--r--shells/pdksh/files/vi.c188
1 files changed, 109 insertions, 79 deletions
diff --git a/shells/pdksh/files/vi.c b/shells/pdksh/files/vi.c
index b9408ceb490..dbde10b9e05 100644
--- a/shells/pdksh/files/vi.c
+++ b/shells/pdksh/files/vi.c
@@ -1,9 +1,17 @@
+/* $NetBSD: vi.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */
+
/*
* vi command editing
* written by John Rochester (initially for nsh)
* bludgeoned to fit pdksh by Larry Bouzane, Jeff Sparkes & Eric Gisin
*
*/
+#include <sys/cdefs.h>
+
+#ifndef lint
+__RCSID("$NetBSD: vi.c,v 1.2 2008/05/31 16:47:37 tnn Exp $");
+#endif
+
#include "config.h"
#ifdef VI
@@ -25,44 +33,45 @@ struct edstate {
};
-static int vi_hook ARGS((int ch));
-static void vi_reset ARGS((char *buf, size_t len));
-static int nextstate ARGS((int ch));
-static int vi_insert ARGS((int ch));
-static int vi_cmd ARGS((int argcnt, const char *cmd));
-static int domove ARGS((int argcnt, const char *cmd, int sub));
-static int redo_insert ARGS((int count));
-static void yank_range ARGS((int a, int b));
-static int bracktype ARGS((int ch));
+static int vi_hook ARGS((int));
+static void vi_reset ARGS((char *, size_t));
+static int nextstate ARGS((int));
+static int vi_insert ARGS((int));
+static int vi_cmd ARGS((int, const char *));
+static int domove ARGS((int, const char *, int));
+static int redo_insert ARGS((int));
+static void yank_range ARGS((int, int));
+static int bracktype ARGS((int));
static void save_cbuf ARGS((void));
static void restore_cbuf ARGS((void));
-static void edit_reset ARGS((char *buf, size_t len));
-static int putbuf ARGS((const char *buf, int len, int repl));
-static void del_range ARGS((int a, int b));
-static int findch ARGS((int ch, int cnt, int forw, int incl));
-static int forwword ARGS((int argcnt));
-static int backword ARGS((int argcnt));
-static int endword ARGS((int argcnt));
-static int Forwword ARGS((int argcnt));
-static int Backword ARGS((int argcnt));
-static int Endword ARGS((int argcnt));
-static int grabhist ARGS((int save, int n));
-static int grabsearch ARGS((int save, int start, int fwd, char *pat));
-static void redraw_line ARGS((int newline));
-static void refresh ARGS((int leftside));
+static void edit_reset ARGS((char *, size_t));
+static int putbuf ARGS((const char *, int, int));
+static void del_range ARGS((int, int));
+static int findch ARGS((int, int, int, int));
+static int forwword ARGS((int));
+static int backword ARGS((int));
+static int endword ARGS((int));
+static int Forwword ARGS((int));
+static int Backword ARGS((int));
+static int Endword ARGS((int));
+static int grabhist ARGS((int, int));
+static int grabsearch ARGS((int, int, int, char *));
+static void redraw_line ARGS((int));
+static void refresh ARGS((int));
static int outofwin ARGS((void));
static void rewindow ARGS((void));
-static int newcol ARGS((int ch, int col));
-static void display ARGS((char *wb1, char *wb2, int leftside));
-static void ed_mov_opt ARGS((int col, char *wb));
-static int expand_word ARGS((int command));
-static int complete_word ARGS((int command, int count));
-static int print_expansions ARGS((struct edstate *e, int command));
-static int char_len ARGS((int c));
-static void x_vi_zotc ARGS((int c));
-static void vi_pprompt ARGS((int full));
+static int newcol ARGS((int, int));
+static void display ARGS((char *, char *, int));
+static void ed_mov_opt ARGS((int, char *));
+static int expand_word ARGS((int));
+static int complete_word ARGS((int, int));
+static int print_expansions ARGS((struct edstate *, int));
+static int char_len ARGS((int));
+static void x_vi_zotc ARGS((int));
+static void vi_pprompt ARGS((int));
static void vi_error ARGS((void));
static void vi_macro_reset ARGS((void));
+static int x_vi_putbuf ARGS((const char *, size_t));
#define C_ 0x1 /* a valid command that isn't a M_, E_, U_ */
#define M_ 0x2 /* movement command (h, l, etc.) */
@@ -235,7 +244,7 @@ x_vi(buf, len)
x_putc('\r'); x_putc('\n'); x_flush();
- if (c == -1)
+ if (c == -1 || len <= es->linelen)
return -1;
if (es->cbuf != buf)
@@ -419,7 +428,7 @@ vi_hook(ch)
}
} else {
locpat[srchlen] = '\0';
- (void) strcpy(srchpat, locpat);
+ (void) strlcpy(srchpat, locpat, sizeof srchpat);
}
state = VCMD;
} else if (ch == edchars.erase || ch == Ctrl('h')) {
@@ -443,9 +452,9 @@ vi_hook(ch)
int i;
int n = srchlen;
- while (n > 0 && isspace(locpat[n - 1]))
+ while (n > 0 && isspace((unsigned char)locpat[n - 1]))
n--;
- while (n > 0 && !isspace(locpat[n - 1]))
+ while (n > 0 && !isspace((unsigned char)locpat[n - 1]))
n--;
for (i = srchlen; --i >= n; )
es->linelen -= char_len((unsigned char) locpat[i]);
@@ -459,15 +468,22 @@ vi_hook(ch)
else {
locpat[srchlen++] = ch;
if ((ch & 0x80) && Flag(FVISHOW8)) {
+ if (es->linelen + 2 > es->cbufsize)
+ vi_error();
es->cbuf[es->linelen++] = 'M';
es->cbuf[es->linelen++] = '-';
ch &= 0x7f;
}
if (ch < ' ' || ch == 0x7f) {
+ if (es->linelen + 2 > es->cbufsize)
+ vi_error();
es->cbuf[es->linelen++] = '^';
es->cbuf[es->linelen++] = ch ^ '@';
- } else
+ } else {
+ if (es->linelen >= es->cbufsize)
+ vi_error();
es->cbuf[es->linelen++] = ch;
+ }
es->cursor = es->linelen;
refresh(0);
}
@@ -690,7 +706,7 @@ vi_insert(ch)
/* End nonstandard vi commands } */
default:
- if (es->linelen == es->cbufsize - 1)
+ if (es->linelen >= es->cbufsize - 1)
return -1;
ibuf[inslen++] = ch;
if (insert == INSERT) {
@@ -817,8 +833,8 @@ vi_cmd(argcnt, cmd)
return -1;
if (*cmd == 'c' &&
(cmd[1]=='w' || cmd[1]=='W') &&
- !isspace(es->cbuf[es->cursor])) {
- while (isspace(es->cbuf[--ncursor]))
+ !isspace((unsigned char)es->cbuf[es->cursor])) {
+ while (isspace((unsigned char)es->cbuf[--ncursor]))
;
ncursor++;
}
@@ -1050,7 +1066,7 @@ vi_cmd(argcnt, cmd)
if (histnum(-1) < 0)
return -1;
p = *histpos();
-#define issp(c) (isspace((c)) || (c) == '\n')
+#define issp(c) (isspace((unsigned char)(c)) || (c) == '\n')
if (argcnt) {
while (*p && issp(*p))
p++;
@@ -1105,12 +1121,12 @@ vi_cmd(argcnt, cmd)
return -1;
for (i = 0; i < argcnt; i++) {
p = &es->cbuf[es->cursor];
- if (islower(*p)) {
+ if (islower((unsigned char)*p)) {
modified = 1; hnum = hlast;
- *p = toupper(*p);
- } else if (isupper(*p)) {
+ *p = toupper((unsigned char)*p);
+ } else if (isupper((unsigned char)*p)) {
modified = 1; hnum = hlast;
- *p = tolower(*p);
+ *p = tolower((unsigned char)*p);
}
if (es->cursor < es->linelen - 1)
es->cursor++;
@@ -1258,7 +1274,7 @@ domove(argcnt, cmd, sub)
case '^':
ncursor = 0;
- while (ncursor < es->linelen - 1 && isspace(es->cbuf[ncursor]))
+ while (ncursor < es->linelen - 1 && isspace((unsigned char)es->cbuf[ncursor]))
ncursor++;
break;
@@ -1402,8 +1418,8 @@ save_edstate(old)
new = (struct edstate *)alloc(sizeof(struct edstate), APERM);
new->cbuf = alloc(old->cbufsize, APERM);
+ memcpy(new->cbuf, old->cbuf, old->linelen);
new->cbufsize = old->cbufsize;
- strcpy(new->cbuf, old->cbuf);
new->linelen = old->linelen;
new->cursor = old->cursor;
new->winleft = old->winleft;
@@ -1414,7 +1430,7 @@ static void
restore_edstate(new, old)
struct edstate *old, *new;
{
- strncpy(new->cbuf, old->cbuf, old->linelen);
+ memcpy(new->cbuf, old->cbuf, old->linelen);
new->linelen = old->linelen;
new->cursor = old->cursor;
new->winleft = old->winleft;
@@ -1470,6 +1486,17 @@ edit_reset(buf, len)
holdlen = 0;
}
+/*
+ * this is used for calling x_escape() in complete_word()
+ */
+static int
+x_vi_putbuf(s, len)
+ const char *s;
+ size_t len;
+{
+ return putbuf(s, len, 0);
+}
+
static int
putbuf(buf, len, repl)
const char *buf;
@@ -1548,12 +1575,12 @@ forwword(argcnt)
while (is_wordch(es->cbuf[ncursor]) &&
ncursor < es->linelen)
ncursor++;
- else if (!isspace(es->cbuf[ncursor]))
+ else if (!isspace((unsigned char)es->cbuf[ncursor]))
while (!is_wordch(es->cbuf[ncursor]) &&
- !isspace(es->cbuf[ncursor]) &&
+ !isspace((unsigned char)es->cbuf[ncursor]) &&
ncursor < es->linelen)
ncursor++;
- while (isspace(es->cbuf[ncursor]) && ncursor < es->linelen)
+ while (isspace((unsigned char)es->cbuf[ncursor]) && ncursor < es->linelen)
ncursor++;
}
return ncursor;
@@ -1567,7 +1594,7 @@ backword(argcnt)
ncursor = es->cursor;
while (ncursor > 0 && argcnt--) {
- while (--ncursor > 0 && isspace(es->cbuf[ncursor]))
+ while (--ncursor > 0 && isspace((unsigned char)es->cbuf[ncursor]))
;
if (ncursor > 0) {
if (is_wordch(es->cbuf[ncursor]))
@@ -1577,7 +1604,7 @@ backword(argcnt)
else
while (--ncursor >= 0 &&
!is_wordch(es->cbuf[ncursor]) &&
- !isspace(es->cbuf[ncursor]))
+ !isspace((unsigned char)es->cbuf[ncursor]))
;
ncursor++;
}
@@ -1594,7 +1621,7 @@ endword(argcnt)
ncursor = es->cursor;
while (ncursor < es->linelen && argcnt--) {
while (++ncursor < es->linelen - 1 &&
- isspace(es->cbuf[ncursor]))
+ isspace((unsigned char)es->cbuf[ncursor]))
;
if (ncursor < es->linelen - 1) {
if (is_wordch(es->cbuf[ncursor]))
@@ -1604,7 +1631,7 @@ endword(argcnt)
else
while (++ncursor < es->linelen &&
!is_wordch(es->cbuf[ncursor]) &&
- !isspace(es->cbuf[ncursor]))
+ !isspace((unsigned char)es->cbuf[ncursor]))
;
ncursor--;
}
@@ -1620,9 +1647,9 @@ Forwword(argcnt)
ncursor = es->cursor;
while (ncursor < es->linelen && argcnt--) {
- while (!isspace(es->cbuf[ncursor]) && ncursor < es->linelen)
+ while (!isspace((unsigned char)es->cbuf[ncursor]) && ncursor < es->linelen)
ncursor++;
- while (isspace(es->cbuf[ncursor]) && ncursor < es->linelen)
+ while (isspace((unsigned char)es->cbuf[ncursor]) && ncursor < es->linelen)
ncursor++;
}
return ncursor;
@@ -1636,9 +1663,9 @@ Backword(argcnt)
ncursor = es->cursor;
while (ncursor > 0 && argcnt--) {
- while (--ncursor >= 0 && isspace(es->cbuf[ncursor]))
+ while (--ncursor >= 0 && isspace((unsigned char)es->cbuf[ncursor]))
;
- while (ncursor >= 0 && !isspace(es->cbuf[ncursor]))
+ while (ncursor >= 0 && !isspace((unsigned char)es->cbuf[ncursor]))
ncursor--;
ncursor++;
}
@@ -1654,11 +1681,11 @@ Endword(argcnt)
ncursor = es->cursor;
while (ncursor < es->linelen - 1 && argcnt--) {
while (++ncursor < es->linelen - 1 &&
- isspace(es->cbuf[ncursor]))
+ isspace((unsigned char)es->cbuf[ncursor]))
;
if (ncursor < es->linelen - 1) {
while (++ncursor < es->linelen &&
- !isspace(es->cbuf[ncursor]))
+ !isspace((unsigned char)es->cbuf[ncursor]))
;
ncursor--;
}
@@ -1732,8 +1759,8 @@ grabsearch(save, start, fwd, pat)
}
static void
-redraw_line(newline)
- int newline;
+redraw_line(newlinex)
+ int newlinex;
{
(void) memset(wbuf[win], ' ', wbuf_len);
if (newline) {
@@ -1930,8 +1957,8 @@ ed_mov_opt(col, wb)
/* replace word with all expansions (ie, expand word*) */
static int
-expand_word(command)
- int command;
+expand_word(commandx)
+ int commandx;
{
static struct edstate *buf;
int rval = 0;
@@ -1941,7 +1968,7 @@ expand_word(command)
int i;
/* Undo previous expansion */
- if (command == 0 && expanded == EXPAND && buf) {
+ if (commandx == 0 && expanded == EXPAND && buf) {
restore_edstate(es, buf);
buf = 0;
expanded = NONE;
@@ -1965,7 +1992,7 @@ expand_word(command)
del_range(start, end);
es->cursor = start;
for (i = 0; i < nwords; ) {
- if (putbuf(words[i], (int) strlen(words[i]), 0) != 0) {
+ if (x_escape(words[i], strlen(words[i]), x_vi_putbuf) != 0) {
rval = -1;
break;
}
@@ -1985,8 +2012,8 @@ expand_word(command)
}
static int
-complete_word(command, count)
- int command;
+complete_word(commandx, count)
+ int commandx;
int count;
{
static struct edstate *buf;
@@ -2000,12 +2027,12 @@ complete_word(command, count)
int is_command;
/* Undo previous completion */
- if (command == 0 && expanded == COMPLETE && buf) {
+ if (commandx == 0 && expanded == COMPLETE && buf) {
print_expansions(buf, 0);
expanded = PRINT;
return 0;
}
- if (command == 0 && expanded == PRINT && buf) {
+ if (commandx == 0 && expanded == PRINT && buf) {
restore_edstate(es, buf);
buf = 0;
expanded = NONE;
@@ -2068,9 +2095,12 @@ complete_word(command, count)
buf = save_edstate(es);
del_range(start, end);
es->cursor = start;
- if (putbuf(match, match_len, 0) != 0)
- rval = -1;
- else if (is_unique) {
+
+ /* escape all shell-sensitive characters and put the result into
+ * command buffer */
+ rval = x_escape(match, match_len, x_vi_putbuf);
+
+ if (rval == 0 && is_unique) {
/* If exact match, don't undo. Allows directory completions
* to be used (ie, complete the next portion of the path).
*/
@@ -2091,9 +2121,9 @@ complete_word(command, count)
}
static int
-print_expansions(e, command)
- struct edstate *e;
- int command;
+print_expansions(ex, commandx)
+ struct edstate *ex;
+ int commandx;
{
int nwords;
int start, end;
@@ -2101,7 +2131,7 @@ print_expansions(e, command)
int is_command;
nwords = x_cf_glob(XCF_COMMAND_FILE|XCF_FULLPATH,
- e->cbuf, e->linelen, e->cursor,
+ ex->cbuf, ex->linelen, ex->cursor,
&start, &end, &words, &is_command);
if (nwords == 0) {
vi_error();
@@ -2129,7 +2159,7 @@ char_len(c)
return len;
}
-/* Similar to x_zotc(emacs.c), but no tab wierdness */
+/* Similar to x_zotc(emacs.c), but no tab weirdness */
static void
x_vi_zotc(c)
int c;