Patch 8.0.0737
Problem:    Crash when X11 selection is very big.
Solution:   Use static items instead of allocating them.  Add callbacks.
            (Ozaki Kiichi)
Files:      src/testdir/shared.vim, src/testdir/test_quotestar.vim,
            src/ui.c


*** ../vim-8.0.0736/src/testdir/shared.vim      2017-03-18 16:18:25.099693814 
+0100
--- src/testdir/shared.vim      2017-07-19 19:16:11.235499909 +0200
***************
*** 111,124 ****
  " Wait for up to a second for "expr" to become true.
  " Return time slept in milliseconds.  With the +reltime feature this can be
  " more than the actual waiting time.  Without +reltime it can also be less.
! func WaitFor(expr)
    " using reltime() is more accurate, but not always available
    if has('reltime')
      let start = reltime()
    else
      let slept = 0
    endif
!   for i in range(100)
      try
        if eval(a:expr)
        if has('reltime')
--- 111,125 ----
  " Wait for up to a second for "expr" to become true.
  " Return time slept in milliseconds.  With the +reltime feature this can be
  " more than the actual waiting time.  Without +reltime it can also be less.
! func WaitFor(expr, ...)
!   let timeout = get(a:000, 0, 1000)
    " using reltime() is more accurate, but not always available
    if has('reltime')
      let start = reltime()
    else
      let slept = 0
    endif
!   for i in range(timeout / 10)
      try
        if eval(a:expr)
        if has('reltime')
***************
*** 133,139 ****
      endif
      sleep 10m
    endfor
!   return 1000
  endfunc
  
  " Wait for up to a given milliseconds.
--- 134,140 ----
      endif
      sleep 10m
    endfor
!   return timeout
  endfunc
  
  " Wait for up to a given milliseconds.
*** ../vim-8.0.0736/src/testdir/test_quotestar.vim      2017-06-10 
16:30:27.965876961 +0200
--- src/testdir/test_quotestar.vim      2017-07-19 19:16:11.235499909 +0200
***************
*** 88,93 ****
--- 88,105 ----
    call WaitFor('@* == "yes"')
    call assert_equal('yes', @*)
  
+   " Handle the large selection over 262040 byte.
+   let length = 262044
+   let sample = 'a' . repeat('b', length - 2) . 'c'
+   let @* = sample
+   call WaitFor('remote_expr("' . name . '", "len(@*) >= ' . length . '", "", 
1)', 3000)
+   let res = remote_expr(name, "@*", "", 2)
+   call assert_equal(length, len(res))
+   " Check length to prevent a large amount of output at assertion failure.
+   if length == len(res)
+     call assert_equal(sample, res)
+   endif
+ 
    if has('unix') && has('gui') && !has('gui_running')
      let @* = ''
  
*** ../vim-8.0.0736/src/ui.c    2017-03-29 19:20:25.385015086 +0200
--- src/ui.c    2017-07-19 19:26:34.987051580 +0200
***************
*** 2042,2051 ****
   * X Selection stuff, for cutting and pasting text to other windows.
   */
  
! static Boolean        clip_x11_convert_selection_cb(Widget, Atom *, Atom *, 
Atom *, XtPointer *, long_u *, int *);
! static void  clip_x11_lose_ownership_cb(Widget, Atom *);
  static void clip_x11_timestamp_cb(Widget w, XtPointer n, XEvent *event, 
Boolean *cont);
! static void  clip_x11_request_selection_cb(Widget, XtPointer, Atom *, Atom *, 
XtPointer, long_u *, int *);
  
  /*
   * Property callback to get a timestamp for XtOwnSelection.
--- 2042,2052 ----
   * X Selection stuff, for cutting and pasting text to other windows.
   */
  
! static Boolean        clip_x11_convert_selection_cb(Widget w, Atom *sel_atom, 
Atom *target, Atom *type, XtPointer *value, long_u *length, int *format);
! static void clip_x11_lose_ownership_cb(Widget w, Atom *sel_atom);
! static void clip_x11_notify_cb(Widget w, Atom *sel_atom, Atom *target);
  static void clip_x11_timestamp_cb(Widget w, XtPointer n, XEvent *event, 
Boolean *cont);
! static void clip_x11_request_selection_cb(Widget w, XtPointer success, Atom 
*sel_atom, Atom *type, XtPointer value, long_u *length, int *format);
  
  /*
   * Property callback to get a timestamp for XtOwnSelection.
***************
*** 2085,2091 ****
      /* Get the selection, using the event timestamp. */
      if (XtOwnSelection(w, xproperty->atom, xproperty->time,
            clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb,
!           NULL) == OK)
      {
        /* Set the "owned" flag now, there may have been a call to
         * lose_ownership_cb in between. */
--- 2086,2092 ----
      /* Get the selection, using the event timestamp. */
      if (XtOwnSelection(w, xproperty->atom, xproperty->time,
            clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb,
!           clip_x11_notify_cb) == OK)
      {
        /* Set the "owned" flag now, there may have been a call to
         * lose_ownership_cb in between. */
***************
*** 2276,2284 ****
        start_time = time(NULL);
        while (success == MAYBE)
        {
!           if (XCheckTypedEvent(dpy, SelectionNotify, &event)
!                   || XCheckTypedEvent(dpy, SelectionRequest, &event)
!                   || XCheckTypedEvent(dpy, PropertyNotify, &event))
            {
                /* This is where clip_x11_request_selection_cb() should be
                 * called.  It may actually happen a bit later, so we loop
--- 2277,2285 ----
        start_time = time(NULL);
        while (success == MAYBE)
        {
!           if (XCheckTypedEvent(dpy, PropertyNotify, &event)
!                   || XCheckTypedEvent(dpy, SelectionNotify, &event)
!                   || XCheckTypedEvent(dpy, SelectionRequest, &event))
            {
                /* This is where clip_x11_request_selection_cb() should be
                 * called.  It may actually happen a bit later, so we loop
***************
*** 2331,2341 ****
      long_u    *length,
      int               *format)
  {
!     char_u    *string;
!     char_u    *result;
!     int               motion_type;
!     VimClipboard      *cbd;
!     int               i;
  
      if (*sel_atom == clip_plus.sel_atom)
        cbd = &clip_plus;
--- 2332,2343 ----
      long_u    *length,
      int               *format)
  {
!     static char_u   *save_result = NULL;
!     static long_u   save_length = 0;
!     char_u        *string;
!     int                   motion_type;
!     VimClipboard    *cbd;
!     int                   i;
  
      if (*sel_atom == clip_plus.sel_atom)
        cbd = &clip_plus;
***************
*** 2348,2357 ****
      /* requestor wants to know what target types we support */
      if (*target == targets_atom)
      {
!       Atom *array;
  
-       if ((array = (Atom *)XtMalloc((unsigned)(sizeof(Atom) * 7))) == NULL)
-           return False;
        *value = (XtPointer)array;
        i = 0;
        array[i++] = targets_atom;
--- 2350,2357 ----
      /* requestor wants to know what target types we support */
      if (*target == targets_atom)
      {
!       static Atom array[7];
  
        *value = (XtPointer)array;
        i = 0;
        array[i++] = targets_atom;
***************
*** 2400,2412 ****
        *length += STRLEN(p_enc) + 2;
  #endif
  
!     *value = XtMalloc((Cardinal)*length);
!     result = (char_u *)*value;
!     if (result == NULL)
      {
        vim_free(string);
        return False;
      }
  
      if (*target == XA_STRING
  #ifdef FEAT_MBYTE
--- 2400,2416 ----
        *length += STRLEN(p_enc) + 2;
  #endif
  
!     if (save_length < *length || save_length / 2 >= *length)
!       *value = XtRealloc((char *)save_result, (Cardinal)*length + 1);
!     else
!       *value = save_result;
!     if (*value == NULL)
      {
        vim_free(string);
        return False;
      }
+     save_result = (char_u *)*value;
+     save_length = *length;
  
      if (*target == XA_STRING
  #ifdef FEAT_MBYTE
***************
*** 2414,2426 ****
  #endif
            )
      {
!       mch_memmove(result, string, (size_t)(*length));
        *type = *target;
      }
      else if (*target == compound_text_atom || *target == text_atom)
      {
        XTextProperty   text_prop;
!       char            *string_nt = (char *)alloc((unsigned)*length + 1);
        int             conv_result;
  
        /* create NUL terminated string which XmbTextListToTextProperty wants */
--- 2418,2430 ----
  #endif
            )
      {
!       mch_memmove(save_result, string, (size_t)(*length));
        *type = *target;
      }
      else if (*target == compound_text_atom || *target == text_atom)
      {
        XTextProperty   text_prop;
!       char            *string_nt = (char *)save_result;
        int             conv_result;
  
        /* create NUL terminated string which XmbTextListToTextProperty wants */
***************
*** 2428,2435 ****
        string_nt[*length] = NUL;
        conv_result = XmbTextListToTextProperty(X_DISPLAY, (char **)&string_nt,
                                           1, XCompoundTextStyle, &text_prop);
-       vim_free(string_nt);
-       XtFree(*value);                 /* replace with COMPOUND text */
        if (conv_result != Success)
        {
            vim_free(string);
--- 2432,2437 ----
***************
*** 2438,2461 ****
        *value = (XtPointer)(text_prop.value);  /*    from plain text */
        *length = text_prop.nitems;
        *type = compound_text_atom;
      }
- 
  #ifdef FEAT_MBYTE
      else if (*target == vimenc_atom)
      {
        int l = STRLEN(p_enc);
  
!       result[0] = motion_type;
!       STRCPY(result + 1, p_enc);
!       mch_memmove(result + l + 2, string, (size_t)(*length - l - 2));
        *type = vimenc_atom;
      }
  #endif
- 
      else
      {
!       result[0] = motion_type;
!       mch_memmove(result + 1, string, (size_t)(*length - 1));
        *type = vim_atom;
      }
      *format = 8;          /* 8 bits per char */
--- 2440,2464 ----
        *value = (XtPointer)(text_prop.value);  /*    from plain text */
        *length = text_prop.nitems;
        *type = compound_text_atom;
+       XtFree((char *)save_result);
+       save_result = (char_u *)*value;
+       save_length = *length;
      }
  #ifdef FEAT_MBYTE
      else if (*target == vimenc_atom)
      {
        int l = STRLEN(p_enc);
  
!       save_result[0] = motion_type;
!       STRCPY(save_result + 1, p_enc);
!       mch_memmove(save_result + l + 2, string, (size_t)(*length - l - 2));
        *type = vimenc_atom;
      }
  #endif
      else
      {
!       save_result[0] = motion_type;
!       mch_memmove(save_result + 1, string, (size_t)(*length - 1));
        *type = vim_atom;
      }
      *format = 8;          /* 8 bits per char */
***************
*** 2479,2484 ****
--- 2482,2493 ----
                                XtLastTimestampProcessed(XtDisplay(myShell)));
  }
  
+     static void
+ clip_x11_notify_cb(Widget w UNUSED, Atom *sel_atom UNUSED, Atom *target 
UNUSED)
+ {
+     /* To prevent automatically freeing the selection value. */
+ }
+ 
      int
  clip_x11_own_selection(Widget myShell, VimClipboard *cbd)
  {
***************
*** 2492,2498 ****
        if (XtOwnSelection(myShell, cbd->sel_atom,
               XtLastTimestampProcessed(XtDisplay(myShell)),
               clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb,
!              NULL) == False)
            return FAIL;
      }
      else
--- 2501,2507 ----
        if (XtOwnSelection(myShell, cbd->sel_atom,
               XtLastTimestampProcessed(XtDisplay(myShell)),
               clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb,
!              clip_x11_notify_cb) == False)
            return FAIL;
      }
      else
*** ../vim-8.0.0736/src/version.c       2017-07-19 18:18:27.828135659 +0200
--- src/version.c       2017-07-19 19:18:49.030374635 +0200
***************
*** 771,772 ****
--- 771,774 ----
  {   /* Add new patch number below this line */
+ /**/
+     737,
  /**/

-- 
A computer program does what you tell it to do, not what you want it to do.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui