vi: fix incorrect memory access on brace matching. Closes 7256
While at it, fix brace matching to actually show the match (missed fflush was causing cursor positioning to be buffered); shorten brace matching code; remove unused macro indirection in indicate_error(). Custom linker script 'busybox_ldscript' found, using it function old new delta indicate_error - 61 +61 mysleep 43 56 +13 char_insert 483 486 +3 find_pair 167 124 -43 Indicate_Error 61 - -61 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 2/1 up/down: 77/-104) Total: -27 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
26a8b9f196
commit
05399fc53d
77
editors/vi.c
77
editors/vi.c
@ -566,8 +566,7 @@ static void redraw(int); // force a full screen refresh
|
|||||||
static char* format_line(char* /*, int*/);
|
static char* format_line(char* /*, int*/);
|
||||||
static void refresh(int); // update the terminal from screen[]
|
static void refresh(int); // update the terminal from screen[]
|
||||||
|
|
||||||
static void Indicate_Error(void); // use flash or beep to indicate error
|
static void indicate_error(void); // use flash or beep to indicate error
|
||||||
#define indicate_error(c) Indicate_Error()
|
|
||||||
static void Hit_Return(void);
|
static void Hit_Return(void);
|
||||||
|
|
||||||
#if ENABLE_FEATURE_VI_SEARCH
|
#if ENABLE_FEATURE_VI_SEARCH
|
||||||
@ -1840,11 +1839,11 @@ static char *bound_dot(char *p) // make sure text[0] <= P < "end"
|
|||||||
{
|
{
|
||||||
if (p >= end && end > text) {
|
if (p >= end && end > text) {
|
||||||
p = end - 1;
|
p = end - 1;
|
||||||
indicate_error('1');
|
indicate_error();
|
||||||
}
|
}
|
||||||
if (p < text) {
|
if (p < text) {
|
||||||
p = text;
|
p = text;
|
||||||
indicate_error('2');
|
indicate_error();
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -2023,16 +2022,9 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p'
|
|||||||
p = text_hole_delete(p, p, ALLOW_UNDO_QUEUED); // shrink buffer 1 char
|
p = text_hole_delete(p, p, ALLOW_UNDO_QUEUED); // shrink buffer 1 char
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if ENABLE_FEATURE_VI_SETOPTS
|
|
||||||
// insert a char into text[]
|
// insert a char into text[]
|
||||||
char *sp; // "save p"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (c == 13)
|
if (c == 13)
|
||||||
c = '\n'; // translate \r to \n
|
c = '\n'; // translate \r to \n
|
||||||
#if ENABLE_FEATURE_VI_SETOPTS
|
|
||||||
sp = p; // remember addr of insert
|
|
||||||
#endif
|
|
||||||
#if ENABLE_FEATURE_VI_UNDO
|
#if ENABLE_FEATURE_VI_UNDO
|
||||||
# if ENABLE_FEATURE_VI_UNDO_QUEUE
|
# if ENABLE_FEATURE_VI_UNDO_QUEUE
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
@ -2056,8 +2048,8 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p'
|
|||||||
#endif /* ENABLE_FEATURE_VI_UNDO */
|
#endif /* ENABLE_FEATURE_VI_UNDO */
|
||||||
p += 1 + stupid_insert(p, c); // insert the char
|
p += 1 + stupid_insert(p, c); // insert the char
|
||||||
#if ENABLE_FEATURE_VI_SETOPTS
|
#if ENABLE_FEATURE_VI_SETOPTS
|
||||||
if (showmatch && strchr(")]}", *sp) != NULL) {
|
if (showmatch && strchr(")]}", c) != NULL) {
|
||||||
showmatching(sp);
|
showmatching(p - 1);
|
||||||
}
|
}
|
||||||
if (autoindent && c == '\n') { // auto indent the new line
|
if (autoindent && c == '\n') { // auto indent the new line
|
||||||
char *q;
|
char *q;
|
||||||
@ -2217,34 +2209,32 @@ static char *skip_thing(char *p, int linecnt, int dir, int type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// find matching char of pair () [] {}
|
// find matching char of pair () [] {}
|
||||||
|
// will crash if c is not one of these
|
||||||
static char *find_pair(char *p, const char c)
|
static char *find_pair(char *p, const char c)
|
||||||
{
|
{
|
||||||
char match, *q;
|
const char *braces = "()[]{}";
|
||||||
|
char match;
|
||||||
int dir, level;
|
int dir, level;
|
||||||
|
|
||||||
match = ')';
|
dir = strchr(braces, c) - braces;
|
||||||
level = 1;
|
dir ^= 1;
|
||||||
dir = 1; // assume forward
|
match = braces[dir];
|
||||||
switch (c) {
|
dir = ((dir & 1) << 1) - 1; /* 1 for ([{, -1 for )\} */
|
||||||
case '(': match = ')'; break;
|
|
||||||
case '[': match = ']'; break;
|
|
||||||
case '{': match = '}'; break;
|
|
||||||
case ')': match = '('; dir = -1; break;
|
|
||||||
case ']': match = '['; dir = -1; break;
|
|
||||||
case '}': match = '{'; dir = -1; break;
|
|
||||||
}
|
|
||||||
for (q = p + dir; text <= q && q < end; q += dir) {
|
|
||||||
// look for match, count levels of pairs (( ))
|
// look for match, count levels of pairs (( ))
|
||||||
if (*q == c)
|
level = 1;
|
||||||
|
for (;;) {
|
||||||
|
p += dir;
|
||||||
|
if (p < text || p >= end)
|
||||||
|
return NULL;
|
||||||
|
if (*p == c)
|
||||||
level++; // increase pair levels
|
level++; // increase pair levels
|
||||||
if (*q == match)
|
if (*p == match) {
|
||||||
level--; // reduce pair level
|
level--; // reduce pair level
|
||||||
if (level == 0)
|
if (level == 0)
|
||||||
break; // found matching pair
|
return p; // found matching pair
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (level != 0)
|
|
||||||
q = NULL; // indicate no match
|
|
||||||
return q;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_FEATURE_VI_SETOPTS
|
#if ENABLE_FEATURE_VI_SETOPTS
|
||||||
@ -2256,7 +2246,7 @@ static void showmatching(char *p)
|
|||||||
// we found half of a pair
|
// we found half of a pair
|
||||||
q = find_pair(p, *p); // get loc of matching char
|
q = find_pair(p, *p); // get loc of matching char
|
||||||
if (q == NULL) {
|
if (q == NULL) {
|
||||||
indicate_error('3'); // no matching char
|
indicate_error(); // no matching char
|
||||||
} else {
|
} else {
|
||||||
// "q" now points to matching pair
|
// "q" now points to matching pair
|
||||||
save_dot = dot; // remember where we are
|
save_dot = dot; // remember where we are
|
||||||
@ -2815,6 +2805,9 @@ static int mysleep(int hund) // sleep for 'hund' 1/100 seconds or stdin ready
|
|||||||
{
|
{
|
||||||
struct pollfd pfd[1];
|
struct pollfd pfd[1];
|
||||||
|
|
||||||
|
if (hund != 0)
|
||||||
|
fflush_all();
|
||||||
|
|
||||||
pfd[0].fd = STDIN_FILENO;
|
pfd[0].fd = STDIN_FILENO;
|
||||||
pfd[0].events = POLLIN;
|
pfd[0].events = POLLIN;
|
||||||
return safe_poll(pfd, 1, hund*10) > 0;
|
return safe_poll(pfd, 1, hund*10) > 0;
|
||||||
@ -3059,7 +3052,7 @@ static void flash(int h)
|
|||||||
redraw(TRUE);
|
redraw(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Indicate_Error(void)
|
static void indicate_error(void)
|
||||||
{
|
{
|
||||||
#if ENABLE_FEATURE_VI_CRASHME
|
#if ENABLE_FEATURE_VI_CRASHME
|
||||||
if (crashme > 0)
|
if (crashme > 0)
|
||||||
@ -3602,7 +3595,7 @@ static void do_cmd(int c)
|
|||||||
break;
|
break;
|
||||||
case 27: // esc
|
case 27: // esc
|
||||||
if (cmd_mode == 0)
|
if (cmd_mode == 0)
|
||||||
indicate_error(c);
|
indicate_error();
|
||||||
cmd_mode = 0; // stop insrting
|
cmd_mode = 0; // stop insrting
|
||||||
undo_queue_commit();
|
undo_queue_commit();
|
||||||
end_cmd_q();
|
end_cmd_q();
|
||||||
@ -3621,7 +3614,7 @@ static void do_cmd(int c)
|
|||||||
if ((unsigned)c1 <= 25) { // a-z?
|
if ((unsigned)c1 <= 25) { // a-z?
|
||||||
YDreg = c1;
|
YDreg = c1;
|
||||||
} else {
|
} else {
|
||||||
indicate_error(c);
|
indicate_error();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '\'': // '- goto a specific mark
|
case '\'': // '- goto a specific mark
|
||||||
@ -3639,7 +3632,7 @@ static void do_cmd(int c)
|
|||||||
dot_begin(); // go to B-o-l
|
dot_begin(); // go to B-o-l
|
||||||
dot_skip_over_ws();
|
dot_skip_over_ws();
|
||||||
} else {
|
} else {
|
||||||
indicate_error(c);
|
indicate_error();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'm': // m- Mark a line
|
case 'm': // m- Mark a line
|
||||||
@ -3652,7 +3645,7 @@ static void do_cmd(int c)
|
|||||||
// remember the line
|
// remember the line
|
||||||
mark[c1] = dot;
|
mark[c1] = dot;
|
||||||
} else {
|
} else {
|
||||||
indicate_error(c);
|
indicate_error();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'P': // P- Put register before
|
case 'P': // P- Put register before
|
||||||
@ -3713,7 +3706,7 @@ static void do_cmd(int c)
|
|||||||
// we found half of a pair
|
// we found half of a pair
|
||||||
p = find_pair(q, *q);
|
p = find_pair(q, *q);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
indicate_error(c);
|
indicate_error();
|
||||||
} else {
|
} else {
|
||||||
dot = p;
|
dot = p;
|
||||||
}
|
}
|
||||||
@ -3721,7 +3714,7 @@ static void do_cmd(int c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*q == '\n')
|
if (*q == '\n')
|
||||||
indicate_error(c);
|
indicate_error();
|
||||||
break;
|
break;
|
||||||
case 'f': // f- forward to a user specified char
|
case 'f': // f- forward to a user specified char
|
||||||
last_forward_char = get_one_char(); // get the search char
|
last_forward_char = get_one_char(); // get the search char
|
||||||
@ -4054,7 +4047,7 @@ static void do_cmd(int c)
|
|||||||
// ZZ means to save file (if necessary), then exit
|
// ZZ means to save file (if necessary), then exit
|
||||||
c1 = get_one_char();
|
c1 = get_one_char();
|
||||||
if (c1 != 'Z') {
|
if (c1 != 'Z') {
|
||||||
indicate_error(c);
|
indicate_error();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (modified_count) {
|
if (modified_count) {
|
||||||
@ -4138,7 +4131,7 @@ static void do_cmd(int c)
|
|||||||
// could not recognize object
|
// could not recognize object
|
||||||
c = c1 = 27; // error-
|
c = c1 = 27; // error-
|
||||||
ml = 0;
|
ml = 0;
|
||||||
indicate_error(c);
|
indicate_error();
|
||||||
}
|
}
|
||||||
if (ml && whole) {
|
if (ml && whole) {
|
||||||
if (c == 'c') {
|
if (c == 'c') {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user