]> git.ipfire.org Git - thirdparty/readline.git/commitdiff
commit readline-20170626 snapshot
authorChet Ramey <chet.ramey@case.edu>
Mon, 26 Jun 2017 20:50:09 +0000 (16:50 -0400)
committerChet Ramey <chet.ramey@case.edu>
Mon, 26 Jun 2017 20:50:09 +0000 (16:50 -0400)
display.c
histlib.h
input.c
isearch.c
kill.c
mbutil.c
util.c
vi_mode.c

index 35c09490381690920e5d2a4d82cbb0c269e38042..b90437f1dc9d071601f0ce358ecceae3fdce473e 100644 (file)
--- a/display.c
+++ b/display.c
@@ -266,6 +266,8 @@ static int *local_prompt_newlines;
    lines and the current line is so marked. */
 static int modmark;
 
+static int line_totbytes;
+
 /* Variables to save and restore prompt and display information. */
 
 /* These are getting numerous enough that it's time to create a struct. */
@@ -465,6 +467,7 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
              if (physchars > bound)            /* should rarely happen */
                {
 #if defined (HANDLE_MULTIBYTE)
+                 *r = '\0';    /* need null-termination for strlen */
                  if (mb_cur_max > 1 && rl_byte_oriented == 0)
                    new = _rl_find_prev_mbchar (ret, r - ret, MB_FIND_ANY);
                  else
@@ -1072,6 +1075,7 @@ rl_redisplay (void)
 #endif
     }
   line[out] = '\0';
+  line_totbytes = out;
   if (cpos_buffer_position < 0)
     {
       cpos_buffer_position = out;
@@ -1480,6 +1484,8 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
         the screen and dealing with changes to what's visible by modifying
         OLD to match it.  Complicated by the presence of multi-width
         characters at the end of the line or beginning of the new one. */
+      /* old is always somewhere in visible_line; new is always somewhere in
+         invisible_line.  These should always be null-terminated. */
 #if defined (HANDLE_MULTIBYTE)
       if (mb_cur_max > 1 && rl_byte_oriented == 0)
        {
@@ -1513,6 +1519,8 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
            oldwidth = 0;
          else
            oldwidth = WCWIDTH (wc);
+         if (oldwidth < 0)
+           oldwidth = 1;
 
          /* 2. how many screen positions does the first char in new consume? */
          memset (&ps, 0, sizeof (mbstate_t));
@@ -1527,12 +1535,16 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
            newwidth = 0;
          else
            newwidth = WCWIDTH (wc);
+         if (newwidth < 0)
+           newwidth = 1;
 
          /* 3. if the new width is less than the old width, we need to keep
             going in new until we have consumed at least that many screen
             positions, and figure out how many bytes that will take */
          while (newbytes < nmax && newwidth < oldwidth)
            {
+             int t;
+
              ret = mbrtowc (&wc, new+newbytes, mb_cur_max, &ps);
              if (MB_INVALIDCH (ret))
                {
@@ -1543,7 +1555,8 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
                break;
              else
                {
-                 newwidth += WCWIDTH (wc);
+                 t = WCWIDTH (wc);
+                 newwidth += (t >= 0) ? t : 1;
                  newbytes += ret;
                }
            }
@@ -1552,6 +1565,8 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
             figure out how many bytes that will take.  This is an optimization */
          while (oldbytes < omax && oldwidth < newwidth)
            {
+             int t;
+
              ret = mbrtowc (&wc, old+oldbytes, mb_cur_max, &ps);
              if (MB_INVALIDCH (ret))
                {
@@ -1562,7 +1577,8 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
                break;
              else
                {
-                 oldwidth += WCWIDTH (wc);
+                 t = WCWIDTH (wc);
+                 oldwidth += (t >= 0) ? t : 1;
                  oldbytes += ret;
                }
            }
@@ -1593,8 +1609,9 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
                {
                  /* We have written as many bytes from new as we need to
                     consume the first character of old. Fix up `old' so it
-                    reflects the new screen contents */
-                 memmove (old+newbytes, old+oldbytes, strlen (old+oldbytes));
+                    reflects the new screen contents.  We use +1 in the
+                    memmove call to copy the trailing NUL. */
+                 memmove (old+newbytes, old+oldbytes, strlen (old+oldbytes) + 1);
                  memcpy (old, new, newbytes);
                  j = newbytes - oldbytes;
                      
@@ -1627,7 +1644,6 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
        }
     }
 
-      
   /* Find first difference. */
 #if defined (HANDLE_MULTIBYTE)
   if (mb_cur_max > 1 && rl_byte_oriented == 0)
@@ -2112,6 +2128,7 @@ dumb_update:
                    }
 
 #if 1
+#ifdef HANDLE_MULTIBYTE
                  /* If we write a non-space into the last screen column,
                     remove the note that we added a space to compensate for
                     a multibyte double-width character that didn't fit, since
@@ -2121,6 +2138,7 @@ dumb_update:
                        line_state_invisible->wrapped_line[current_line+1] &&
                        nfd[bytes_to_insert-1] != ' ')
                    line_state_invisible->wrapped_line[current_line+1] = 0;
+#endif
 #endif
                }
              else
index 9986a2e4ff69e321c14be298088da506016130d5..9627b24500012e03eefa8ad0e7dc056b756ed246 100644 (file)
--- a/histlib.h
+++ b/histlib.h
@@ -51,9 +51,9 @@
 #endif
 
 #ifndef member
-#  ifndef strchr
+#  if !defined (strchr) && !defined (__STDC__)
 extern char *strchr ();
-#  endif
+#  endif /* !strchr && !__STDC__ */
 #define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
 #endif
 
diff --git a/input.c b/input.c
index b57bba61b75dd8c309adee7c5de5962aef3a53f7..00916456e5d560e40f73db11966f464d0d60b9fd 100644 (file)
--- a/input.c
+++ b/input.c
@@ -655,7 +655,7 @@ _rl_read_mbchar (char *mbchar, int size)
 int
 _rl_read_mbstring (int first, char *mb, int mlen)
 {
-  int i, c;
+  int i, c, n;
   mbstate_t ps;
 
   c = first;
@@ -664,7 +664,8 @@ _rl_read_mbstring (int first, char *mb, int mlen)
     {
       mb[i] = (char)c;
       memset (&ps, 0, sizeof (mbstate_t));
-      if (_rl_get_char_len (mb, &ps) == -2)
+      n = _rl_get_char_len (mb, &ps);
+      if (n == -2)
        {
          /* Read more for multibyte character */
          RL_SETSTATE (RL_STATE_MOREINPUT);
index 10419cdbaded11f8748bb61f2cf91fc78a1815b6..da9f0cef4950c8adfedd8481bbcaed961a33f985 100644 (file)
--- a/isearch.c
+++ b/isearch.c
@@ -262,7 +262,7 @@ static void
 _rl_isearch_fini (_rl_search_cxt *cxt)
 {
   /* First put back the original state. */
-  strcpy (rl_line_buffer, cxt->lines[cxt->save_line]);
+  rl_replace_line (cxt->lines[cxt->save_line], 0);
 
   rl_restore_prompt ();
 
@@ -292,6 +292,7 @@ _rl_isearch_fini (_rl_search_cxt *cxt)
   rl_point = cxt->sline_index;
   /* Don't worry about where to put the mark here; rl_get_previous_history
      and rl_get_next_history take care of it. */
+  _rl_fix_point (0);
 
   rl_clear_message ();
 }
@@ -515,7 +516,7 @@ add_character:
            }
          return (1);
        }
-      else if (cxt->sflags & SF_REVERSE)
+      else if (cxt->sflags & SF_REVERSE && cxt->sline_index > 0)
        cxt->sline_index--;
       else if (cxt->sline_index != cxt->sline_len)
        cxt->sline_index++;
@@ -664,6 +665,11 @@ add_character:
            }
          else
            cxt->sline_index += cxt->direction;
+         if (cxt->sline_index < 0)
+           {
+             cxt->sline_index = 0;
+             break;
+           }
        }
       if (cxt->sflags & SF_FOUND)
        break;
diff --git a/kill.c b/kill.c
index 65ab7e986c609021476cfe8dc17e779a09568d6b..983a98482d92fecc27e7cd1246d64a030987aa9f 100644 (file)
--- a/kill.c
+++ b/kill.c
@@ -119,7 +119,7 @@ _rl_copy_to_kill_ring (char *text, int append)
          else
            {
              slot = rl_kill_ring_length += 1;
-             rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
+             rl_kill_ring = (char **)xrealloc (rl_kill_ring, (slot + 1) * sizeof (char *));
            }
          rl_kill_ring[--slot] = (char *)NULL;
        }
index fac1460f2ee7c8e9170fac6787884fe79f38aadf..65543416cb64c2bf0ccbde5d7143ce805aab1ea9 100644 (file)
--- a/mbutil.c
+++ b/mbutil.c
@@ -92,6 +92,11 @@ _rl_find_next_mbchar_internal (char *string, int seed, int count, int find_non_z
     return seed;
 
   point = seed + _rl_adjust_point (string, seed, &ps);
+  /* if _rl_adjust_point returns -1, the character or string is invalid.
+     treat as a byte. */
+  if (point == seed - 1)       /* invalid */
+    return seed + 1;
+    
   /* if this is true, means that seed was not pointing to a byte indicating
      the beginning of a multibyte character.  Correct the point and consume
      one char. */
@@ -218,9 +223,13 @@ _rl_find_prev_mbchar_internal (char *string, int seed, int find_non_zero)
 int
 _rl_get_char_len (char *src, mbstate_t *ps)
 {
-  size_t tmp;
+  size_t tmp, l;
+  int mb_cur_max;
 
-  tmp = mbrlen((const char *)src, (size_t)strlen (src), ps);
+  /* Look at no more than MB_CUR_MAX characters */
+  l = (size_t)strlen (src);
+  mb_cur_max = MB_CUR_MAX;
+  tmp = mbrlen((const char *)src, (l < mb_cur_max) ? l : mb_cur_max, ps);
   if (tmp == (size_t)(-2))
     {
       /* shorted to compose multibyte char */
@@ -265,7 +274,7 @@ _rl_compare_chars (char *buf1, int pos1, mbstate_t *ps1, char *buf2, int pos2, m
 /* adjust pointed byte and find mbstate of the point of string.
    adjusted point will be point <= adjusted_point, and returns
    differences of the byte(adjusted_point - point).
-   if point is invalied (point < 0 || more than string length),
+   if point is invalid (point < 0 || more than string length),
    it returns -1 */
 int
 _rl_adjust_point (char *string, int point, mbstate_t *ps)
@@ -336,6 +345,8 @@ _rl_char_value (char *buf, int ind)
   l = strlen (buf);
   if (ind >= l - 1)
     return ((wchar_t) buf[ind]);
+  if (l < ind)                 /* Sanity check */
+    l = strlen (buf+ind);
   memset (&ps, 0, sizeof (mbstate_t));
   tmp = mbrtowc (&wc, buf + ind, l - ind, &ps);
   if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp))  
diff --git a/util.c b/util.c
index 23e4edde0a2846b6572b0bba7a85a06852cf6d35..e009b2383828e5ed49628b2b04d6ff24b8b519bf 100644 (file)
--- a/util.c
+++ b/util.c
@@ -193,7 +193,7 @@ rl_tilde_expand (int ignore, int key)
     }
   else if (start >= 0 && rl_line_buffer[start] != '~')
     {
-      for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--)
+      for (; start >= 0 && !whitespace (rl_line_buffer[start]); start--)
         ;
       start++;
     }
index 3613d195aad1f6e55dc97cb2536ae9ed60122ca2..db1bd7999a79321c2cb2fe2b7131689078191d5e 100644 (file)
--- a/vi_mode.c
+++ b/vi_mode.c
@@ -101,7 +101,7 @@ static int _rl_vi_last_search_mblen;
 #else
 static int _rl_vi_last_search_char;
 #endif
-static int _rl_vi_last_replacement;
+static char _rl_vi_last_replacement[MB_LEN_MAX+1];     /* reserve for trailing NULL */
 
 static int _rl_vi_last_key_before_insert;
 
@@ -646,11 +646,7 @@ _rl_vi_append_forward (int key)
       else
        {
          point = rl_point;
-#if 0
-         rl_forward_char (1, key);
-#else
          rl_point = _rl_forward_char_internal (1);
-#endif
          if (point == rl_point)
            rl_point = rl_end;
        }
@@ -1889,7 +1885,7 @@ _rl_vi_change_char (int count, int c, char *mb)
       p = rl_point;
       rl_vi_delete (1, c);
       if (rl_point < p)                /* Did we retreat at EOL? */
-       rl_point++;
+       _rl_vi_append_forward (c);
 #if defined (HANDLE_MULTIBYTE)
       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
        rl_insert_text (mb);
@@ -1931,9 +1927,15 @@ static int
 _rl_vi_callback_change_char (_rl_callback_generic_arg *data)
 {
   int c;
-  char mb[MB_LEN_MAX];
+  char mb[MB_LEN_MAX+1];
 
-  _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
+  c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
+#if defined (HANDLE_MULTIBYTE)
+  strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
+#else
+  _rl_vi_last_replacement[0] = c;
+#endif
+  _rl_vi_last_replacement[MB_LEN_MAX] = '\0';  /* XXX */
 
   if (c < 0)
     return -1;
@@ -1949,13 +1951,13 @@ int
 rl_vi_change_char (int count, int key)
 {
   int c;
-  char mb[MB_LEN_MAX];
+  char mb[MB_LEN_MAX+1];
 
   if (_rl_vi_redoing)
     {
-      c = _rl_vi_last_replacement;
-      mb[0] = c;
-      mb[1] = '\0';
+      strncpy (mb, _rl_vi_last_replacement, MB_LEN_MAX);
+      c = (unsigned char)_rl_vi_last_replacement[0];   /* XXX */
+      mb[MB_LEN_MAX] = '\0';
     }
 #if defined (READLINE_CALLBACKS)
   else if (RL_ISSTATE (RL_STATE_CALLBACK))
@@ -1966,7 +1968,15 @@ rl_vi_change_char (int count, int key)
     }
 #endif
   else
-    _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
+    {
+      c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
+#ifdef HANDLE_MULTIBYTE
+      strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
+#else
+      _rl_vi_last_replacement[0] = c;
+#endif
+      _rl_vi_last_replacement[MB_LEN_MAX] = '\0';      /* just in case */      
+    }
 
   if (c < 0)
     return -1;