Patch 7.1a.001
Problem:    Crash when downloading a spell file.  (Szabolcs Horvat)
Solution:   Avoid that did_set_spelllang() is used recursively when a new
            window is opened for the download.
            Also avoid wiping out the wrong buffer.
Files:      runtime/autoload/spellfile.vim, src/buffer.c, src/ex_cmds.c,
            src/spell.c


*** ../vim-7.1a.000/runtime/autoload/spellfile.vim      Tue Aug 29 22:31:34 2006
--- runtime/autoload/spellfile.vim      Sun May  6 23:52:05 2007
***************
*** 1,6 ****
  " Vim script to download a missing spell file
  " Maintainer: Bram Moolenaar <[EMAIL PROTECTED]>
! " Last Change:        2006 Aug 29
  
  if !exists('g:spellfile_URL')
    let g:spellfile_URL = 'ftp://ftp.vim.org/pub/vim/runtime/spell'
--- 1,6 ----
  " Vim script to download a missing spell file
  " Maintainer: Bram Moolenaar <[EMAIL PROTECTED]>
! " Last Change:        2007 May 06
  
  if !exists('g:spellfile_URL')
    let g:spellfile_URL = 'ftp://ftp.vim.org/pub/vim/runtime/spell'
***************
*** 58,76 ****
      let fname = a:lang . '.' . enc . '.spl'
  
      " Split the window, read the file into a new buffer.
      new
      setlocal bin
      echo 'Downloading ' . fname . '...'
      call spellfile#Nread(fname)
      if getline(2) !~ 'VIMspell'
        " Didn't work, perhaps there is an ASCII one.
!       g/^/d
        let fname = a:lang . '.ascii.spl'
        echo 'Could not find it, trying ' . fname . '...'
        call spellfile#Nread(fname)
        if getline(2) !~ 'VIMspell'
        echo 'Sorry, downloading failed'
!       bwipe!
        return
        endif
      endif
--- 58,97 ----
      let fname = a:lang . '.' . enc . '.spl'
  
      " Split the window, read the file into a new buffer.
+     " Remember the buffer number, we check it below.
      new
+     let newbufnr = winbufnr(0)
      setlocal bin
      echo 'Downloading ' . fname . '...'
      call spellfile#Nread(fname)
      if getline(2) !~ 'VIMspell'
        " Didn't work, perhaps there is an ASCII one.
!       " Careful: Nread() may have opened a new window for the error message,
!       " we need to go back to our own buffer and window.
!       if newbufnr != winbufnr(0)
!       let winnr = bufwinnr(newbufnr)
!       if winnr == -1
!         " Our buffer has vanished!?  Open a new window.
!         echomsg "download buffer disappeared, opening a new one"
!         new
!         setlocal bin
!       else
!         exe winnr . "wincmd w"
!       endif
!       endif
!       if newbufnr == winbufnr(0)
!       " We are back the old buffer, remove any (half-finished) download.
!         g/^/d
!       else
!       let newbufnr = winbufnr(0)
!       endif
! 
        let fname = a:lang . '.ascii.spl'
        echo 'Could not find it, trying ' . fname . '...'
        call spellfile#Nread(fname)
        if getline(2) !~ 'VIMspell'
        echo 'Sorry, downloading failed'
!       exe newbufnr . "bwipe!"
        return
        endif
      endif
***************
*** 96,112 ****
        let fname = substitute(fname, '\.spl$', '.sug', '')
        echo 'Downloading ' . fname . '...'
        call spellfile#Nread(fname)
!       if getline(2) !~ 'VIMsug'
!         echo 'Sorry, downloading failed'
!       else
          1d
          exe "write " . escape(dirlist[dirchoice], ' ') . '/' . fname
        endif
-       set nomod
        endif
      endif
  
!     bwipe
    endif
  endfunc
  
--- 117,145 ----
        let fname = substitute(fname, '\.spl$', '.sug', '')
        echo 'Downloading ' . fname . '...'
        call spellfile#Nread(fname)
!       if getline(2) =~ 'VIMsug'
          1d
          exe "write " . escape(dirlist[dirchoice], ' ') . '/' . fname
+         set nomod
+       else
+         echo 'Sorry, downloading failed'
+         " Go back to our own buffer/window, Nread() may have taken us to
+         " another window.
+         if newbufnr != winbufnr(0)
+           let winnr = bufwinnr(newbufnr)
+           if winnr != -1
+             exe winnr . "wincmd w"
+           endif
+         endif
+         if newbufnr == winbufnr(0)
+           set nomod
+         endif
        endif
        endif
      endif
  
!     " Wipe out the buffer we used.
!     exe newbufnr . "bwipe"
    endif
  endfunc
  
*** ../vim-7.1a.000/src/buffer.c        Thu Mar 15 22:53:25 2007
--- src/buffer.c        Sun May  6 15:44:08 2007
***************
*** 1426,1431 ****
--- 1426,1438 ----
      if (curbuf->b_kmap_state & KEYMAP_INIT)
        keymap_init();
  #endif
+ #ifdef FEAT_SPELL
+     /* May need to set the spell language.  Can only do this after the buffer
+      * has been properly setup. */
+     if (!curbuf->b_help && curwin->w_p_spell && *curbuf->b_p_spl != NUL)
+       did_set_spelllang(curbuf);
+ #endif
+ 
      redraw_later(NOT_VALID);
  }
  
***************
*** 2414,2424 ****
      /* Set 'foldlevel' to 'foldlevelstart' if it's not negative. */
      if (p_fdls >= 0)
        curwin->w_p_fdl = p_fdls;
- #endif
- 
- #ifdef FEAT_SPELL
-     if (curwin->w_p_spell && *buf->b_p_spl != NUL)
-       did_set_spelllang(buf);
  #endif
  }
  
--- 2421,2426 ----
*** ../vim-7.1a.000/src/ex_cmds.c       Thu Mar 15 21:38:26 2007
--- src/ex_cmds.c       Sun May  6 15:38:25 2007
***************
*** 3088,3093 ****
--- 3088,3096 ----
      char_u    *cp;
  #endif
      char_u    *command = NULL;
+ #ifdef FEAT_SPELL
+     int               did_get_winopts = FALSE;
+ #endif
  
      if (eap != NULL)
        command = eap->do_ecmd_cmd;
***************
*** 3365,3370 ****
--- 3368,3376 ----
                 * before, reset the local window options to the global
                 * values.  Also restores old folding stuff. */
                get_winopts(buf);
+ #ifdef FEAT_SPELL
+               did_get_winopts = TRUE;
+ #endif
  
  #ifdef FEAT_AUTOCMD
            }
***************
*** 3638,3643 ****
--- 3644,3656 ----
        diff_buf_add(curbuf);
        diff_invalidate(curbuf);
      }
+ #endif
+ 
+ #ifdef FEAT_SPELL
+     /* If the window options were changed may need to set the spell language.
+      * Can only do this after the buffer has been properly setup. */
+     if (did_get_winopts && curwin->w_p_spell && *buf->b_p_spl != NUL)
+       did_set_spelllang(buf);
  #endif
  
      if (command == NULL)
*** ../vim-7.1a.000/src/spell.c Thu Mar  8 14:49:18 2007
--- src/spell.c Sun May  6 17:08:06 2007
***************
*** 4105,4116 ****
      int               nobreak = FALSE;
      int               i, j;
      langp_T   *lp, *lp2;
  
      ga_init2(&ga, sizeof(langp_T), 2);
      clear_midword(buf);
  
      /* loop over comma separated language names. */
!     for (splp = buf->b_p_spl; *splp != NUL; )
      {
        /* Get one language name. */
        copy_option_part(&splp, lang, MAXWLEN, ",");
--- 4105,4132 ----
      int               nobreak = FALSE;
      int               i, j;
      langp_T   *lp, *lp2;
+     static int        recursive = FALSE;
+     char_u    *ret_msg = NULL;
+     char_u    *spl_copy;
+ 
+     /* We don't want to do this recursively.  May happen when a language is
+      * not available and the SpellFileMissing autocommand opens a new buffer
+      * in which 'spell' is set. */
+     if (recursive)
+       return NULL;
+     recursive = TRUE;
  
      ga_init2(&ga, sizeof(langp_T), 2);
      clear_midword(buf);
  
+     /* Make a copy of 'spellang', the SpellFileMissing autocommands may change
+      * it under our fingers. */
+     spl_copy = vim_strsave(buf->b_p_spl);
+     if (spl_copy == NULL)
+       goto theend;
+ 
      /* loop over comma separated language names. */
!     for (splp = spl_copy; *splp != NUL; )
      {
        /* Get one language name. */
        copy_option_part(&splp, lang, MAXWLEN, ",");
***************
*** 4176,4182 ****
--- 4192,4209 ----
            if (filename)
                (void)spell_load_file(lang, lang, NULL, FALSE);
            else
+           {
                spell_load_lang(lang);
+ #ifdef FEAT_AUTOCMD
+               /* SpellFileMissing autocommands may do anything, including
+                * destroying the buffer we are using... */
+               if (!buf_valid(buf))
+               {
+                   ret_msg = (char_u *)"E797: SpellFileMissing autocommand 
deleted buffer";
+                   goto theend;
+               }
+ #endif
+           }
        }
  
        /*
***************
*** 4215,4221 ****
                    if (ga_grow(&ga, 1) == FAIL)
                    {
                        ga_clear(&ga);
!                       return e_outofmem;
                    }
                    LANGP_ENTRY(ga, ga.ga_len)->lp_slang = slang;
                    LANGP_ENTRY(ga, ga.ga_len)->lp_region = region_mask;
--- 4242,4249 ----
                    if (ga_grow(&ga, 1) == FAIL)
                    {
                        ga_clear(&ga);
!                       ret_msg = e_outofmem;
!                       goto theend;
                    }
                    LANGP_ENTRY(ga, ga.ga_len)->lp_slang = slang;
                    LANGP_ENTRY(ga, ga.ga_len)->lp_region = region_mask;
***************
*** 4231,4237 ****
       * round 1: load first name in 'spellfile'.
       * round 2: load second name in 'spellfile.
       * etc. */
!     spf = curbuf->b_p_spf;
      for (round = 0; round == 0 || *spf != NUL; ++round)
      {
        if (round == 0)
--- 4259,4265 ----
       * round 1: load first name in 'spellfile'.
       * round 2: load second name in 'spellfile.
       * etc. */
!     spf = buf->b_p_spf;
      for (round = 0; round == 0 || *spf != NUL; ++round)
      {
        if (round == 0)
***************
*** 4357,4363 ****
            }
      }
  
!     return NULL;
  }
  
  /*
--- 4385,4394 ----
            }
      }
  
! theend:
!     vim_free(spl_copy);
!     recursive = FALSE;
!     return ret_msg;
  }
  
  /*
*** ../vim-7.1a.000/src/version.c       Sun May  6 15:28:50 2007
--- src/version.c       Sun May  6 23:50:00 2007
***************
*** 668,669 ****
--- 668,671 ----
  {   /* Add new patch number below this line */
+ /**/
+     1,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
69. Yahoo welcomes you with your own start page

 /// Bram Moolenaar -- [EMAIL PROTECTED] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

Reply via email to