aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2014-09-15 17:06:10 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2014-09-15 17:06:10 +0200
commit05399fc53dc0b812727e44189882181ecaf3b6d6 (patch)
treeefc93581856e68572359cfd3d6836a205352f0d1
parent26a8b9f1967d910033c516462c101100e041a9b4 (diff)
downloadbusybox-w32-05399fc53dc0b812727e44189882181ecaf3b6d6.tar.gz
busybox-w32-05399fc53dc0b812727e44189882181ecaf3b6d6.tar.bz2
busybox-w32-05399fc53dc0b812727e44189882181ecaf3b6d6.zip
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>
-rw-r--r--editors/vi.c79
1 files changed, 36 insertions, 43 deletions
diff --git a/editors/vi.c b/editors/vi.c
index 24a9f60a8..70bdbab07 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -566,8 +566,7 @@ static void redraw(int); // force a full screen refresh
566static char* format_line(char* /*, int*/); 566static char* format_line(char* /*, int*/);
567static void refresh(int); // update the terminal from screen[] 567static void refresh(int); // update the terminal from screen[]
568 568
569static void Indicate_Error(void); // use flash or beep to indicate error 569static void indicate_error(void); // use flash or beep to indicate error
570#define indicate_error(c) Indicate_Error()
571static void Hit_Return(void); 570static void Hit_Return(void);
572 571
573#if ENABLE_FEATURE_VI_SEARCH 572#if ENABLE_FEATURE_VI_SEARCH
@@ -1840,11 +1839,11 @@ static char *bound_dot(char *p) // make sure text[0] <= P < "end"
1840{ 1839{
1841 if (p >= end && end > text) { 1840 if (p >= end && end > text) {
1842 p = end - 1; 1841 p = end - 1;
1843 indicate_error('1'); 1842 indicate_error();
1844 } 1843 }
1845 if (p < text) { 1844 if (p < text) {
1846 p = text; 1845 p = text;
1847 indicate_error('2'); 1846 indicate_error();
1848 } 1847 }
1849 return p; 1848 return p;
1850} 1849}
@@ -2023,16 +2022,9 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p'
2023 p = text_hole_delete(p, p, ALLOW_UNDO_QUEUED); // shrink buffer 1 char 2022 p = text_hole_delete(p, p, ALLOW_UNDO_QUEUED); // shrink buffer 1 char
2024 } 2023 }
2025 } else { 2024 } else {
2026#if ENABLE_FEATURE_VI_SETOPTS
2027 // insert a char into text[] 2025 // insert a char into text[]
2028 char *sp; // "save p"
2029#endif
2030
2031 if (c == 13) 2026 if (c == 13)
2032 c = '\n'; // translate \r to \n 2027 c = '\n'; // translate \r to \n
2033#if ENABLE_FEATURE_VI_SETOPTS
2034 sp = p; // remember addr of insert
2035#endif
2036#if ENABLE_FEATURE_VI_UNDO 2028#if ENABLE_FEATURE_VI_UNDO
2037# if ENABLE_FEATURE_VI_UNDO_QUEUE 2029# if ENABLE_FEATURE_VI_UNDO_QUEUE
2038 if (c == '\n') 2030 if (c == '\n')
@@ -2056,8 +2048,8 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p'
2056#endif /* ENABLE_FEATURE_VI_UNDO */ 2048#endif /* ENABLE_FEATURE_VI_UNDO */
2057 p += 1 + stupid_insert(p, c); // insert the char 2049 p += 1 + stupid_insert(p, c); // insert the char
2058#if ENABLE_FEATURE_VI_SETOPTS 2050#if ENABLE_FEATURE_VI_SETOPTS
2059 if (showmatch && strchr(")]}", *sp) != NULL) { 2051 if (showmatch && strchr(")]}", c) != NULL) {
2060 showmatching(sp); 2052 showmatching(p - 1);
2061 } 2053 }
2062 if (autoindent && c == '\n') { // auto indent the new line 2054 if (autoindent && c == '\n') { // auto indent the new line
2063 char *q; 2055 char *q;
@@ -2217,34 +2209,32 @@ static char *skip_thing(char *p, int linecnt, int dir, int type)
2217} 2209}
2218 2210
2219// find matching char of pair () [] {} 2211// find matching char of pair () [] {}
2212// will crash if c is not one of these
2220static char *find_pair(char *p, const char c) 2213static char *find_pair(char *p, const char c)
2221{ 2214{
2222 char match, *q; 2215 const char *braces = "()[]{}";
2216 char match;
2223 int dir, level; 2217 int dir, level;
2224 2218
2225 match = ')'; 2219 dir = strchr(braces, c) - braces;
2220 dir ^= 1;
2221 match = braces[dir];
2222 dir = ((dir & 1) << 1) - 1; /* 1 for ([{, -1 for )\} */
2223
2224 // look for match, count levels of pairs (( ))
2226 level = 1; 2225 level = 1;
2227 dir = 1; // assume forward 2226 for (;;) {
2228 switch (c) { 2227 p += dir;
2229 case '(': match = ')'; break; 2228 if (p < text || p >= end)
2230 case '[': match = ']'; break; 2229 return NULL;
2231 case '{': match = '}'; break; 2230 if (*p == c)
2232 case ')': match = '('; dir = -1; break;
2233 case ']': match = '['; dir = -1; break;
2234 case '}': match = '{'; dir = -1; break;
2235 }
2236 for (q = p + dir; text <= q && q < end; q += dir) {
2237 // look for match, count levels of pairs (( ))
2238 if (*q == c)
2239 level++; // increase pair levels 2231 level++; // increase pair levels
2240 if (*q == match) 2232 if (*p == match) {
2241 level--; // reduce pair level 2233 level--; // reduce pair level
2242 if (level == 0) 2234 if (level == 0)
2243 break; // found matching pair 2235 return p; // found matching pair
2236 }
2244 } 2237 }
2245 if (level != 0)
2246 q = NULL; // indicate no match
2247 return q;
2248} 2238}
2249 2239
2250#if ENABLE_FEATURE_VI_SETOPTS 2240#if ENABLE_FEATURE_VI_SETOPTS
@@ -2256,7 +2246,7 @@ static void showmatching(char *p)
2256 // we found half of a pair 2246 // we found half of a pair
2257 q = find_pair(p, *p); // get loc of matching char 2247 q = find_pair(p, *p); // get loc of matching char
2258 if (q == NULL) { 2248 if (q == NULL) {
2259 indicate_error('3'); // no matching char 2249 indicate_error(); // no matching char
2260 } else { 2250 } else {
2261 // "q" now points to matching pair 2251 // "q" now points to matching pair
2262 save_dot = dot; // remember where we are 2252 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
2815{ 2805{
2816 struct pollfd pfd[1]; 2806 struct pollfd pfd[1];
2817 2807
2808 if (hund != 0)
2809 fflush_all();
2810
2818 pfd[0].fd = STDIN_FILENO; 2811 pfd[0].fd = STDIN_FILENO;
2819 pfd[0].events = POLLIN; 2812 pfd[0].events = POLLIN;
2820 return safe_poll(pfd, 1, hund*10) > 0; 2813 return safe_poll(pfd, 1, hund*10) > 0;
@@ -3059,7 +3052,7 @@ static void flash(int h)
3059 redraw(TRUE); 3052 redraw(TRUE);
3060} 3053}
3061 3054
3062static void Indicate_Error(void) 3055static void indicate_error(void)
3063{ 3056{
3064#if ENABLE_FEATURE_VI_CRASHME 3057#if ENABLE_FEATURE_VI_CRASHME
3065 if (crashme > 0) 3058 if (crashme > 0)
@@ -3602,7 +3595,7 @@ static void do_cmd(int c)
3602 break; 3595 break;
3603 case 27: // esc 3596 case 27: // esc
3604 if (cmd_mode == 0) 3597 if (cmd_mode == 0)
3605 indicate_error(c); 3598 indicate_error();
3606 cmd_mode = 0; // stop insrting 3599 cmd_mode = 0; // stop insrting
3607 undo_queue_commit(); 3600 undo_queue_commit();
3608 end_cmd_q(); 3601 end_cmd_q();
@@ -3621,7 +3614,7 @@ static void do_cmd(int c)
3621 if ((unsigned)c1 <= 25) { // a-z? 3614 if ((unsigned)c1 <= 25) { // a-z?
3622 YDreg = c1; 3615 YDreg = c1;
3623 } else { 3616 } else {
3624 indicate_error(c); 3617 indicate_error();
3625 } 3618 }
3626 break; 3619 break;
3627 case '\'': // '- goto a specific mark 3620 case '\'': // '- goto a specific mark
@@ -3639,7 +3632,7 @@ static void do_cmd(int c)
3639 dot_begin(); // go to B-o-l 3632 dot_begin(); // go to B-o-l
3640 dot_skip_over_ws(); 3633 dot_skip_over_ws();
3641 } else { 3634 } else {
3642 indicate_error(c); 3635 indicate_error();
3643 } 3636 }
3644 break; 3637 break;
3645 case 'm': // m- Mark a line 3638 case 'm': // m- Mark a line
@@ -3652,7 +3645,7 @@ static void do_cmd(int c)
3652 // remember the line 3645 // remember the line
3653 mark[c1] = dot; 3646 mark[c1] = dot;
3654 } else { 3647 } else {
3655 indicate_error(c); 3648 indicate_error();
3656 } 3649 }
3657 break; 3650 break;
3658 case 'P': // P- Put register before 3651 case 'P': // P- Put register before
@@ -3713,7 +3706,7 @@ static void do_cmd(int c)
3713 // we found half of a pair 3706 // we found half of a pair
3714 p = find_pair(q, *q); 3707 p = find_pair(q, *q);
3715 if (p == NULL) { 3708 if (p == NULL) {
3716 indicate_error(c); 3709 indicate_error();
3717 } else { 3710 } else {
3718 dot = p; 3711 dot = p;
3719 } 3712 }
@@ -3721,7 +3714,7 @@ static void do_cmd(int c)
3721 } 3714 }
3722 } 3715 }
3723 if (*q == '\n') 3716 if (*q == '\n')
3724 indicate_error(c); 3717 indicate_error();
3725 break; 3718 break;
3726 case 'f': // f- forward to a user specified char 3719 case 'f': // f- forward to a user specified char
3727 last_forward_char = get_one_char(); // get the search char 3720 last_forward_char = get_one_char(); // get the search char
@@ -4054,7 +4047,7 @@ static void do_cmd(int c)
4054 // ZZ means to save file (if necessary), then exit 4047 // ZZ means to save file (if necessary), then exit
4055 c1 = get_one_char(); 4048 c1 = get_one_char();
4056 if (c1 != 'Z') { 4049 if (c1 != 'Z') {
4057 indicate_error(c); 4050 indicate_error();
4058 break; 4051 break;
4059 } 4052 }
4060 if (modified_count) { 4053 if (modified_count) {
@@ -4138,7 +4131,7 @@ static void do_cmd(int c)
4138 // could not recognize object 4131 // could not recognize object
4139 c = c1 = 27; // error- 4132 c = c1 = 27; // error-
4140 ml = 0; 4133 ml = 0;
4141 indicate_error(c); 4134 indicate_error();
4142 } 4135 }
4143 if (ml && whole) { 4136 if (ml && whole) {
4144 if (c == 'c') { 4137 if (c == 'c') {