From 0bf59cca9470914af13a5d5ac3aa3ba5555475e8 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 12 Jun 2010 20:12:02 +0200 Subject: [PATCH 01/11] updated for version 7.2.443 Problem: Using taglist() on a tag file with duplicate fields generates an internal error. (Peter Odding) Solution: Check for duplicate field names. --HG-- branch : vim73 --- src/eval.c | 3 +-- src/proto/eval.pro | 1 + src/tag.c | 14 +++++++++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/eval.c b/src/eval.c index 2e5b8766c6..10732ccade 100644 --- a/src/eval.c +++ b/src/eval.c @@ -451,7 +451,6 @@ static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); static long dict_len __ARGS((dict_T *d)); -static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); static char_u *dict2string __ARGS((typval_T *tv, int copyID)); static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); @@ -7043,7 +7042,7 @@ dict_len(d) * If "len" is negative use strlen(key). * Returns NULL when not found. */ - static dictitem_T * + dictitem_T * dict_find(d, key, len) dict_T *d; char_u *key; diff --git a/src/proto/eval.pro b/src/proto/eval.pro index e817769ede..6d11d970d7 100644 --- a/src/proto/eval.pro +++ b/src/proto/eval.pro @@ -56,6 +56,7 @@ dictitem_T *dictitem_alloc __ARGS((char_u *key)); void dictitem_free __ARGS((dictitem_T *item)); int dict_add __ARGS((dict_T *d, dictitem_T *item)); int dict_add_nr_str __ARGS((dict_T *d, char *key, long nr, char_u *str)); +dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); char_u *get_dict_string __ARGS((dict_T *d, char_u *key, int save)); long get_dict_number __ARGS((dict_T *d, char_u *key)); char_u *get_function_name __ARGS((expand_T *xp, int idx)); diff --git a/src/tag.c b/src/tag.c index ba36de735c..db00c2e1f6 100644 --- a/src/tag.c +++ b/src/tag.c @@ -3771,7 +3771,8 @@ expand_tags(tagnames, pat, num_file, file) static int add_tag_field __ARGS((dict_T *dict, char *field_name, char_u *start, char_u *end)); /* - * Add a tag field to the dictionary "dict" + * Add a tag field to the dictionary "dict". + * Return OK or FAIL. */ static int add_tag_field(dict, field_name, start, end) @@ -3783,6 +3784,17 @@ add_tag_field(dict, field_name, start, end) char_u buf[MAXPATHL]; int len = 0; + /* check that the field name doesn't exist yet */ + if (dict_find(dict, (char_u *)field_name, -1) != NULL) + { + if (p_verbose > 0) + { + verbose_enter(); + smsg((char_u *)_("Duplicate field name: %s"), field_name); + verbose_leave(); + } + return FAIL; + } if (start != NULL) { if (end == NULL) From 318f787765160d20d246652ff2973b48eab6ea8a Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 12 Jun 2010 20:18:19 +0200 Subject: [PATCH 02/11] Update help files. --HG-- branch : vim73 --- runtime/doc/editing.txt | 2 +- runtime/doc/todo.txt | 5 ----- runtime/doc/various.txt | 3 ++- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt index b4cdc48243..a10e8220a7 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1376,7 +1376,7 @@ check if the encryption works as expected. If you get one of these errors don't write the file encrypted! You need to rebuild the Vim binary to fix this. -*E831* This is an internal error, "cannot happen". If you can reproduc it, +*E831* This is an internal error, "cannot happen". If you can reproduce it, please report to the developers. When reading a file that has been encrypted and the 'key' option is not empty, diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index d9174fcf11..605c3cbe1e 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -30,11 +30,6 @@ be worked on, but only if you sponsor Vim development. See |sponsor|. *known-bugs* -------------------- Known bugs and current work ----------------------- -internal error hash_add() (Peter Odding) - :set tags=/tmp/bad_tags - :call taglist('.') -Also with one line tags file. (Lech Lorens, Jun 9) - gtk_selection_clear_targets not available in GTK1 (Patrick Texier) Use #ifdefs to use old code for GTK1. diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt index 63b279b322..eed7d9c4c7 100644 --- a/runtime/doc/various.txt +++ b/runtime/doc/various.txt @@ -189,7 +189,8 @@ g8 Print the hex values of the bytes used in the mapping |:noremap|, the argument can be mapped anyway. An alternative is to use |:execute|, which uses an expression as argument. This allows the use of - printable characters. Example: > + printable characters to represent special characters. + Example: > :exe "normal \\" < {not in Vi, of course} {not available when the |+ex_extra| feature was From e20a968994fd4ebd2b793864f7d450b198d65a0b Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 13 Jun 2010 05:20:42 +0200 Subject: [PATCH 03/11] Added salt to blowfish encryption. --HG-- branch : vim73 --- runtime/doc/options.txt | 2 +- runtime/doc/todo.txt | 4 - runtime/tutor/tutor.eo | 14 +-- runtime/tutor/tutor.eo.utf-8 | 14 +-- runtime/tutor/tutor.fr | 22 ++--- runtime/tutor/tutor.fr.utf-8 | 22 ++--- src/blowfish.c | 42 ++++++--- src/fileio.c | 68 +++++++++----- src/po/eo.po | 169 ++++++++++++++++++++++++++++------- src/po/fr.po | 164 ++++++++++++++++++++++++++------- src/proto.h | 2 +- src/proto/blowfish.pro | 2 +- src/proto/sha256.pro | 4 +- src/sha256.c | 50 +++++++---- src/testdir/test71.in | 2 +- 15 files changed, 425 insertions(+), 156 deletions(-) diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index c021edfc47..e63bcdb73c 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -7363,7 +7363,7 @@ A jump table for the options with a short description can be found at |Q_op|. When not empty all messages are written in a file with this name. When the file exists messages are appended. Writing to the file ends when Vim exits or when 'verbosefile' is made - empty. + empty. Writes are buffered, thus may not show up for some time. Setting 'verbosefile' to a new value is like making it empty first. The difference with |:redir| is that verbose messages are not displayed when 'verbosefile' is set. diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index 605c3cbe1e..f898c0297b 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -30,9 +30,6 @@ be worked on, but only if you sponsor Vim development. See |sponsor|. *known-bugs* -------------------- Known bugs and current work ----------------------- -gtk_selection_clear_targets not available in GTK1 (Patrick Texier) -Use #ifdefs to use old code for GTK1. - Cursor positioning wrong with 0x200e character. (John Becket, 2010 May 6) E315 when trying to change a file in FileChangedRO autocommand event. @@ -1088,7 +1085,6 @@ restored. (Luc St-Louis) Vim 7.3: -- crash when reloading file. (Namsh, 2010 Jun 11) - using NSIS 2.46: install on Windows 7 works, but no "Edit with Vim" menu. Use register_shell_extension()? (George Reilly, 2010 May 26) Ron's version: http://dev.ronware.org/p/vim/finfo?name=gvim.nsi diff --git a/runtime/tutor/tutor.eo b/runtime/tutor/tutor.eo index 2ac06893c0..958d393d2e 100644 --- a/runtime/tutor/tutor.eo +++ b/runtime/tutor/tutor.eo @@ -1,5 +1,5 @@ ============================================================================== -= B o n v e n o n al la I n s t r u i l o de V I M - Versio 1.7.eo.2 = += B o n v e n o n al la I n s t r u i l o de V I M - Versio 1.7.eo.3 = ============================================================================== Vim estas tre potenca redaktilo, kiu havas multajn komandojn, tro da ili @@ -149,6 +149,7 @@ RIMARKO: Trairante la instruilon, ne provu memori, lernu per la uzo. !! RIMARKO: Antaý ol plenumi iun suban paþon ajn, legu la tutan lecionon!! 1. Eliru el la instruilo kiel vi faris en la leciono 1.2: :q! + Aý, se vi havas atingon al alia terminalo, faru tion, kio sekvas tie. 2. Æe la þelinvito, tajpu æi tiun komandon: vim tutor 'vim' estas la komando por lanæi la redaktilon Vim, 'tutor' estas la @@ -159,7 +160,8 @@ RIMARKO: Trairante la instruilon, ne provu memori, lernu per la uzo. 4. Konservu la dosieron kun þanøoj kaj eliru el Vim per: :wq - 5. Relanæu la instruilon vimtutor kaj moviøu suben al la sekvanta resumo. + 5. Se vi eliris la instruilon vimtutor en paþo 1, restartu la intruilon + vimtutor kaj moviøu suben al la sekvanta resumo. 6. Post kiam vi legis la suprajn paþojn, kaj komprenis ilin: faru ilin. @@ -413,7 +415,7 @@ RIMARKO: Premo de nur la movo en Normala re 5. Nun moviøu al la leciono 3.3. -Rimarko: Memoru, ke vi devus lerni per uzo, kaj ne per memorado. +RIMARKO: Memoru, ke vi devus lerni per uzo, kaj ne per memorado. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -908,7 +910,7 @@ RIMARKO: Se vi deziras ignori usklecon por nur unu ser ** Ebligu kapablojn de Vim ** Vim havas multe pli da kapabloj ol Vi, sed la plej multaj estas defaýlte - malþaltitaj. Por ekuzi la kapablojn, vi devas krei dosieron "vimrc. + malþaltitaj. Por ekuzi la kapablojn, vi devas krei dosieron "vimrc". 1. Ekredaktu la dosieron "vimrc". Tio dependas de via sistemo: :e ~/.vimrc por Unikso @@ -969,7 +971,7 @@ RIMARKO: Kompletigo funkcias por multaj komandoj. Nur provu premi CTRL-D kaj ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tio konkludas la instruilon de Vim. Øi celis doni mallongan superrigardon - de la redaktilo Vim, nur tio kio sufiæas por ebligi al vi facilan uzon de + de la redaktilo Vim, nur tion kio sufiæas por ebligi al vi facilan uzon de la redaktilo. Estas nepre nekompleta, æar Vim havas multajn multajn pliajn komandojn. Legu la manlibron: ":help user-manual". @@ -984,6 +986,6 @@ RIMARKO: Kompletigo funkcias por multaj komandoj. Nur provu premi CTRL-D kaj Tradukita en Esperanto de Dominique Pellé, 2008-04-01 Retpoþto: dominique.pelle@gmail.com - Lasta þanøo: 2009-02-01 + Lasta þanøo: 2010-05-23 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/runtime/tutor/tutor.eo.utf-8 b/runtime/tutor/tutor.eo.utf-8 index 5adad3913e..febf2f983e 100644 --- a/runtime/tutor/tutor.eo.utf-8 +++ b/runtime/tutor/tutor.eo.utf-8 @@ -1,5 +1,5 @@ ============================================================================== -= B o n v e n o n al la I n s t r u i l o de V I M - Versio 1.7.eo.2 = += B o n v e n o n al la I n s t r u i l o de V I M - Versio 1.7.eo.3 = ============================================================================== Vim estas tre potenca redaktilo, kiu havas multajn komandojn, tro da ili @@ -149,6 +149,7 @@ RIMARKO: Trairante la instruilon, ne provu memori, lernu per la uzo. !! RIMARKO: AntaÅ­ ol plenumi iun suban paÅon ajn, legu la tutan lecionon!! 1. Eliru el la instruilo kiel vi faris en la leciono 1.2: :q! + AÅ­, se vi havas atingon al alia terminalo, faru tion, kio sekvas tie. 2. Ĉe la Åelinvito, tajpu ĉi tiun komandon: vim tutor 'vim' estas la komando por lanĉi la redaktilon Vim, 'tutor' estas la @@ -159,7 +160,8 @@ RIMARKO: Trairante la instruilon, ne provu memori, lernu per la uzo. 4. Konservu la dosieron kun ÅanÄoj kaj eliru el Vim per: :wq - 5. Relanĉu la instruilon vimtutor kaj moviÄu suben al la sekvanta resumo. + 5. Se vi eliris la instruilon vimtutor en paÅo 1, restartu la intruilon + vimtutor kaj moviÄu suben al la sekvanta resumo. 6. Post kiam vi legis la suprajn paÅojn, kaj komprenis ilin: faru ilin. @@ -413,7 +415,7 @@ RIMARKO: Premo de nur la movo en Normala reÄimo sen operatoro movos 5. Nun moviÄu al la leciono 3.3. -Rimarko: Memoru, ke vi devus lerni per uzo, kaj ne per memorado. +RIMARKO: Memoru, ke vi devus lerni per uzo, kaj ne per memorado. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -908,7 +910,7 @@ RIMARKO: Se vi deziras ignori usklecon por nur unu serĉa komando, uzu \c ** Ebligu kapablojn de Vim ** Vim havas multe pli da kapabloj ol Vi, sed la plej multaj estas defaÅ­lte - malÅaltitaj. Por ekuzi la kapablojn, vi devas krei dosieron "vimrc. + malÅaltitaj. Por ekuzi la kapablojn, vi devas krei dosieron "vimrc". 1. Ekredaktu la dosieron "vimrc". Tio dependas de via sistemo: :e ~/.vimrc por Unikso @@ -969,7 +971,7 @@ RIMARKO: Kompletigo funkcias por multaj komandoj. Nur provu premi CTRL-D kaj ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tio konkludas la instruilon de Vim. Äœi celis doni mallongan superrigardon - de la redaktilo Vim, nur tio kio sufiĉas por ebligi al vi facilan uzon de + de la redaktilo Vim, nur tion kio sufiĉas por ebligi al vi facilan uzon de la redaktilo. Estas nepre nekompleta, ĉar Vim havas multajn multajn pliajn komandojn. Legu la manlibron: ":help user-manual". @@ -984,6 +986,6 @@ RIMARKO: Kompletigo funkcias por multaj komandoj. Nur provu premi CTRL-D kaj Tradukita en Esperanto de Dominique Pellé, 2008-04-01 RetpoÅto: dominique.pelle@gmail.com - Lasta ÅanÄo: 2009-02-01 + Lasta ÅanÄo: 2010-05-23 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/runtime/tutor/tutor.fr b/runtime/tutor/tutor.fr index e321754576..abb53d18f7 100644 --- a/runtime/tutor/tutor.fr +++ b/runtime/tutor/tutor.fr @@ -1,5 +1,5 @@ =============================================================================== -= B i e n v e n u e dans le T u t o r i e l de V I M - Version 1.7.fr.1 = += B i e n v e n u e dans le T u t o r i e l de V I M - Version 1.7.fr.2 = =============================================================================== Vim est un éditeur très puissant qui a trop de commandes pour pouvoir @@ -67,7 +67,7 @@ NOTE : Les touches fl 4. Si vous avez mémorisé ces étapes et êtes confiant, effectuez les étapes 1 à 3 pour sortir puis rentrer dans l'éditeur. -NOTE : :q! annule tous le changements que vous avez fait. Dans +NOTE : :q! annule tous les changements que vous avez fait. Dans quelques leçons, vous apprendrez à enregistrer les changements. 5. Déplacez le curseur à la Leçon 1.3. @@ -401,7 +401,7 @@ NOTE : Le seul appui d'un mouvement en mode Normal, sans commande, d 2. Tapez dd pour effacer la ligne et la placer dans un registre de Vim. - 3. Déplacez le curseur sur la ligne c) au dessus où vous voulez remettre la + 3. Déplacez le curseur sur la ligne c) au-dessus où vous voulez remettre la ligne effacée. 4. En mode Normal, tapez p pour remettre la ligne en dessous du curseur. @@ -486,7 +486,7 @@ Notez que ce efface le mot et vous place ensuite en mode Insertion. ---> La fin de cette ligne doit être rendue identique à la seconde. ---> La fin de cette ligne doit être corrigée avec la commande c$ . -NOTE : Vous pouvez utilisez la touche Retour Arrière pour corriger les +NOTE : Vous pouvez utiliser la touche Retour Arrière pour corriger les erreurs lorsque vous tapez. @@ -722,14 +722,14 @@ NOTE : L'appui de v d ** Pour insérer le contenu d'un fichier, tapez :r FICHIER ** - 1. Placez le curseur juste au dessus de cette ligne. + 1. Placez le curseur juste au-dessus de cette ligne. NOTE : Après avoir exécuté l'étape 2 vous verrez du texte de la Leçon 5.3. Puis déplacez vous vers le bas pour voir cette leçon à nouveau. 2. Maintenant récupérez votre fichier TEST en utilisant la commande :r TEST où TEST est le nom de votre fichier. - Le fichier que vous récupérez est placé au dessous de la ligne du curseur. + Le fichier que vous récupérez est placé au-dessous de la ligne du curseur. 4. Pour vérifier que le fichier a bien été inséré, remontez et vérifiez qu'il y a maintenant deux copies de la Leçon 5.3, l'originale et celle @@ -779,7 +779,7 @@ NOTE : Vous pouvez aussi lire la sortie d'une commande externe. Par exemple, ---> En tapant o le curseur se met sur la ligne ouverte, en mode Insertion. - 4. Pour ouvrir une ligne au DESSUS du curseur, tapez simplement un O + 4. Pour ouvrir une ligne au-DESSUS du curseur, tapez simplement un O majuscule, plutôt qu'un o minuscule. Faites un essai sur la ligne ci-dessous. @@ -849,7 +849,7 @@ NOTE : Le mode Remplacement est comme le mode Insertion, mais tous les 3. Tapez y pour copier le texte en surbrillance. - 4. Déplacez la curseur à la fin de la ligne suivante : j$ + 4. Déplacez le curseur à la fin de la ligne suivante : j$ 5. Tapez p pour coller le texte. Puis tapez : un second <Échap> . @@ -893,7 +893,7 @@ NOTE : Si vous voulez ignorer la casse uniquement pour une recherche, utilisez 1. Taper o ouvre une ligne SOUS le curseur et démarre le mode Insertion. - Taper O ouvre une ligne au DESSUS du curseur. + Taper O ouvre une ligne au-DESSUS du curseur. 2. Taper a pour insérer du texte APRÈS le curseur. Taper A pour insérer du texte après la fin de ligne. @@ -985,7 +985,7 @@ NOTE : Si vous voulez ignorer la casse uniquement pour une recherche, utilisez 7 Appuyez . Vim va compléter le nom (s'il est unique). -NOTE : Le complètement fonctionne pour de nombreuse commandes. Essayez +NOTE : Le complètement fonctionne pour de nombreuses commandes. Essayez d'appuyer CTRL-D et . C'est utile en particulier pour :help . @@ -1034,5 +1034,5 @@ NOTE : Le compl Dernières mises à jour par Dominique Pellé. E-mail : dominique.pelle@gmail.com - Last Change : 2008 Nov 23 + Last Change : 2010 May 23 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/runtime/tutor/tutor.fr.utf-8 b/runtime/tutor/tutor.fr.utf-8 index 1b015105d9..24d8bfa00f 100644 --- a/runtime/tutor/tutor.fr.utf-8 +++ b/runtime/tutor/tutor.fr.utf-8 @@ -1,5 +1,5 @@ =============================================================================== -= B i e n v e n u e dans le T u t o r i e l de V I M - Version 1.7.fr.1 = += B i e n v e n u e dans le T u t o r i e l de V I M - Version 1.7.fr.2 = =============================================================================== Vim est un éditeur très puissant qui a trop de commandes pour pouvoir @@ -67,7 +67,7 @@ NOTE : Les touches fléchées devraient également fonctionner. Mais en utilisan 4. Si vous avez mémorisé ces étapes et êtes confiant, effectuez les étapes 1 à 3 pour sortir puis rentrer dans l'éditeur. -NOTE : :q! annule tous le changements que vous avez fait. Dans +NOTE : :q! annule tous les changements que vous avez fait. Dans quelques leçons, vous apprendrez à enregistrer les changements. 5. Déplacez le curseur à la Leçon 1.3. @@ -401,7 +401,7 @@ NOTE : Le seul appui d'un mouvement en mode Normal, sans commande, déplace le 2. Tapez dd pour effacer la ligne et la placer dans un registre de Vim. - 3. Déplacez le curseur sur la ligne c) au dessus où vous voulez remettre la + 3. Déplacez le curseur sur la ligne c) au-dessus où vous voulez remettre la ligne effacée. 4. En mode Normal, tapez p pour remettre la ligne en dessous du curseur. @@ -486,7 +486,7 @@ Notez que ce efface le mot et vous place ensuite en mode Insertion. ---> La fin de cette ligne doit être rendue identique à la seconde. ---> La fin de cette ligne doit être corrigée avec la commande c$ . -NOTE : Vous pouvez utilisez la touche Retour Arrière pour corriger les +NOTE : Vous pouvez utiliser la touche Retour Arrière pour corriger les erreurs lorsque vous tapez. @@ -722,14 +722,14 @@ NOTE : L'appui de v démarre la sélection Visuelle. Vous pouvez déplacer le ** Pour insérer le contenu d'un fichier, tapez :r FICHIER ** - 1. Placez le curseur juste au dessus de cette ligne. + 1. Placez le curseur juste au-dessus de cette ligne. NOTE : Après avoir exécuté l'étape 2 vous verrez du texte de la Leçon 5.3. Puis déplacez vous vers le bas pour voir cette leçon à nouveau. 2. Maintenant récupérez votre fichier TEST en utilisant la commande :r TEST où TEST est le nom de votre fichier. - Le fichier que vous récupérez est placé au dessous de la ligne du curseur. + Le fichier que vous récupérez est placé au-dessous de la ligne du curseur. 4. Pour vérifier que le fichier a bien été inséré, remontez et vérifiez qu'il y a maintenant deux copies de la Leçon 5.3, l'originale et celle @@ -779,7 +779,7 @@ NOTE : Vous pouvez aussi lire la sortie d'une commande externe. Par exemple, ---> En tapant o le curseur se met sur la ligne ouverte, en mode Insertion. - 4. Pour ouvrir une ligne au DESSUS du curseur, tapez simplement un O + 4. Pour ouvrir une ligne au-DESSUS du curseur, tapez simplement un O majuscule, plutôt qu'un o minuscule. Faites un essai sur la ligne ci-dessous. @@ -849,7 +849,7 @@ NOTE : Le mode Remplacement est comme le mode Insertion, mais tous les 3. Tapez y pour copier le texte en surbrillance. - 4. Déplacez la curseur à la fin de la ligne suivante : j$ + 4. Déplacez le curseur à la fin de la ligne suivante : j$ 5. Tapez p pour coller le texte. Puis tapez : un second <Échap> . @@ -893,7 +893,7 @@ NOTE : Si vous voulez ignorer la casse uniquement pour une recherche, utilisez 1. Taper o ouvre une ligne SOUS le curseur et démarre le mode Insertion. - Taper O ouvre une ligne au DESSUS du curseur. + Taper O ouvre une ligne au-DESSUS du curseur. 2. Taper a pour insérer du texte APRÈS le curseur. Taper A pour insérer du texte après la fin de ligne. @@ -985,7 +985,7 @@ NOTE : Si vous voulez ignorer la casse uniquement pour une recherche, utilisez 7 Appuyez . Vim va compléter le nom (s'il est unique). -NOTE : Le complètement fonctionne pour de nombreuse commandes. Essayez +NOTE : Le complètement fonctionne pour de nombreuses commandes. Essayez d'appuyer CTRL-D et . C'est utile en particulier pour :help . @@ -1034,5 +1034,5 @@ NOTE : Le complètement fonctionne pour de nombreuse commandes. Essayez Dernières mises à jour par Dominique Pellé. E-mail : dominique.pelle@gmail.com - Last Change : 2008 Nov 23 + Last Change : 2010 May 23 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/blowfish.c b/src/blowfish.c index d47f463056..f0b97b7b90 100644 --- a/src/blowfish.c +++ b/src/blowfish.c @@ -402,22 +402,40 @@ bf_d_cblock(block) } #endif +/* + * Initialize the crypt method using "password" as the encryption key and + * "salt[salt_len]" as the salt. + */ void -bf_key_init(password) +bf_key_init(password, salt, salt_len) char_u *password; + char_u *salt; + int salt_len; { int i, j, keypos = 0; UINT32_T val, data_l, data_r; char_u *key; int keylen; - key = sha256_key(password); - keylen = (int)STRLEN(key); + /* Process the key 1000 times. + * See http://en.wikipedia.org/wiki/Key_strengthening. */ + key = sha256_key(password, salt, salt_len); + for (i = 0; i < 1000; i++) + key = sha256_key(key, salt, salt_len); + + /* Convert the key from 64 hex chars to 32 binary chars. */ + keylen = (int)STRLEN(key) / 2; if (keylen == 0) { EMSG(_("E831: bf_key_init() called with empty password")); return; } + for (i = 0; i < keylen; i++) + { + sscanf((char *)&key[i * 2], "%2x", &j); + key[i] = j; + } + for (i = 0; i < 256; ++i) { sbx[0][i] = sbi[0][i]; @@ -475,9 +493,10 @@ bf_check_tables(ipa, sbi, val) typedef struct { char_u password[64]; - char_u plaintxt[8]; - char_u cryptxt[8]; - char_u badcryptxt[8]; /* cryptxt when big/little endian is wrong */ + char_u salt[9]; + char_u plaintxt[9]; + char_u cryptxt[9]; + char_u badcryptxt[9]; /* cryptxt when big/little endian is wrong */ UINT32_T keysum; } struct_bf_test_data; @@ -488,10 +507,11 @@ typedef struct { static struct_bf_test_data bf_test_data[] = { { "password", + "salt", "plaintxt", - "\x55\xca\x56\x3a\xef\xe1\x9c\x73", /* cryptxt */ - "\x47\xd9\x67\x49\x91\xc5\x9a\x95", /* badcryptxt */ - 0x5de01bdbu, /* keysum */ + "\xad\x3d\xfa\x7f\xe8\xea\x40\xf6", /* cryptxt */ + "\x72\x50\x3b\x38\x10\x60\x22\xa7", /* badcryptxt */ + 0x56701b5du /* keysum */ }, }; @@ -519,7 +539,9 @@ bf_self_test() bn = ARRAY_LENGTH(bf_test_data); for (i = 0; i < bn; i++) { - bf_key_init((char_u *)(bf_test_data[i].password)); + bf_key_init((char_u *)(bf_test_data[i].password), + bf_test_data[i].salt, + (int)STRLEN(bf_test_data[i].salt)); if (!bf_check_tables(pax, sbx, bf_test_data[i].keysum)) err++; diff --git a/src/fileio.c b/src/fileio.c index bc629f39e6..bfc11d0d95 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -37,7 +37,12 @@ static char *crypt_magic[] = {"VimCrypt~01!", "VimCrypt~02!"}; static char crypt_magic_head[] = "VimCrypt~"; # define CRYPT_MAGIC_LEN 12 /* must be multiple of 4! */ + +/* For blowfish, after the magic header, we store 8 bytes of salt and then 8 + * bytes of seed (initialisation vector). */ +static int crypt_salt_len[] = {0, 8}; static int crypt_seed_len[] = {0, 8}; +#define CRYPT_SALT_LEN_MAX 8 #define CRYPT_SEED_LEN_MAX 8 #endif @@ -1441,6 +1446,7 @@ retry: if ((filesize == 0 # ifdef FEAT_CRYPT || (filesize == (CRYPT_MAGIC_LEN + + crypt_salt_len[use_crypt_method] + crypt_seed_len[use_crypt_method]) && cryptkey != NULL) # endif @@ -2488,7 +2494,9 @@ failed: #ifdef FEAT_CRYPT if (cryptkey != NULL) msg_add_lines(c, (long)linecnt, filesize - - CRYPT_MAGIC_LEN - crypt_seed_len[use_crypt_method]); + - CRYPT_MAGIC_LEN + - crypt_salt_len[use_crypt_method] + - crypt_seed_len[use_crypt_method]); else #endif msg_add_lines(c, (long)linecnt, filesize); @@ -2841,7 +2849,7 @@ get_crypt_method(ptr, len) for (i = 0; i < (int)(sizeof(crypt_magic) / sizeof(crypt_magic[0])); i++) { - if (len < (CRYPT_MAGIC_LEN + crypt_seed_len[i])) + if (len < (CRYPT_MAGIC_LEN + crypt_salt_len[i] + crypt_seed_len[i])) continue; if (memcmp(ptr, crypt_magic[i], CRYPT_MAGIC_LEN) == 0) return i; @@ -2903,19 +2911,20 @@ check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile, did_ask) if (cryptkey != NULL) { int seed_len = crypt_seed_len[method]; + int salt_len = crypt_salt_len[method]; if (method == 0) crypt_init_keys(cryptkey); else { - bf_key_init(cryptkey); - bf_ofb_init(ptr + CRYPT_MAGIC_LEN, seed_len); + bf_key_init(cryptkey, ptr + CRYPT_MAGIC_LEN, salt_len); + bf_ofb_init(ptr + CRYPT_MAGIC_LEN + salt_len, seed_len); } /* Remove magic number from the text */ - *filesizep += CRYPT_MAGIC_LEN + seed_len; - *sizep -= CRYPT_MAGIC_LEN + seed_len; - mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN + seed_len, (size_t)*sizep); + *filesizep += CRYPT_MAGIC_LEN + salt_len + seed_len; + *sizep -= CRYPT_MAGIC_LEN + salt_len + seed_len; + mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN + salt_len + seed_len, (size_t)*sizep); } } /* When starting to edit a new file which does not have encryption, clear @@ -2935,12 +2944,15 @@ prepare_crypt_read(fp) FILE *fp; { int method; - char_u buffer[CRYPT_MAGIC_LEN + CRYPT_SEED_LEN_MAX + 2]; + char_u buffer[CRYPT_MAGIC_LEN + CRYPT_SALT_LEN_MAX + + CRYPT_SEED_LEN_MAX + 2]; if (fread(buffer, CRYPT_MAGIC_LEN, 1, fp) != 1) return FAIL; method = get_crypt_method((char *)buffer, - CRYPT_MAGIC_LEN + CRYPT_SEED_LEN_MAX); + CRYPT_MAGIC_LEN + + CRYPT_SEED_LEN_MAX + + CRYPT_SALT_LEN_MAX); if (method < 0 || method != curbuf->b_p_cm) return FAIL; @@ -2948,12 +2960,13 @@ prepare_crypt_read(fp) crypt_init_keys(curbuf->b_p_key); else { + int salt_len = crypt_salt_len[method]; int seed_len = crypt_seed_len[method]; - if (fread(buffer, seed_len, 1, fp) != 1) + if (fread(buffer, salt_len + seed_len, 1, fp) != 1) return FAIL; - bf_key_init(curbuf->b_p_key); - bf_ofb_init(buffer, seed_len); + bf_key_init(curbuf->b_p_key, buffer, salt_len); + bf_ofb_init(buffer + salt_len, seed_len); } return OK; } @@ -2969,8 +2982,12 @@ prepare_crypt_write(buf, lenp) { char_u *header; int seed_len = crypt_seed_len[buf->b_p_cm]; + int salt_len = crypt_salt_len[buf->b_p_cm]; + char_u *salt; + char_u *seed; - header = alloc_clear(CRYPT_MAGIC_LEN + CRYPT_SEED_LEN_MAX + 2); + header = alloc_clear(CRYPT_MAGIC_LEN + CRYPT_SALT_LEN_MAX + + CRYPT_SEED_LEN_MAX + 2); if (header != NULL) { use_crypt_method = buf->b_p_cm; /* select pkzip or blowfish */ @@ -2980,27 +2997,32 @@ prepare_crypt_write(buf, lenp) crypt_init_keys(buf->b_p_key); else { - /* Using blowfish, add seed. */ - sha2_seed(header + CRYPT_MAGIC_LEN, seed_len); /* create iv */ - bf_ofb_init(header + CRYPT_MAGIC_LEN, seed_len); - bf_key_init(buf->b_p_key); + /* Using blowfish, add salt and seed. */ + salt = header + CRYPT_MAGIC_LEN; + seed = salt + salt_len; + sha2_seed(salt, salt_len, seed, seed_len); + bf_key_init(buf->b_p_key, salt, salt_len); + bf_ofb_init(seed, seed_len); } } - *lenp = CRYPT_MAGIC_LEN + seed_len; + *lenp = CRYPT_MAGIC_LEN + salt_len + seed_len; return header; } +#endif /* FEAT_CRYPT */ + /* * Like fwrite() but crypt the bytes when 'key' is set. * Returns 1 if successful. */ size_t fwrite_crypt(buf, ptr, len, fp) - buf_T *buf; + buf_T *buf UNUSED; char_u *ptr; size_t len; FILE *fp; { +#ifdef FEAT_CRYPT char_u *copy; char_u small_buf[100]; size_t i; @@ -3020,6 +3042,9 @@ fwrite_crypt(buf, ptr, len, fp) if (copy != small_buf) vim_free(copy); return i; +#else + return fwrite(ptr, len, (size_t)1, fp); +#endif } /* @@ -3028,19 +3053,20 @@ fwrite_crypt(buf, ptr, len, fp) */ char_u * read_string_decrypt(buf, fd, len) - buf_T *buf; + buf_T *buf UNUSED; FILE *fd; int len; { char_u *ptr; ptr = read_string(fd, len); +#ifdef FEAT_CRYPT if (ptr != NULL || *buf->b_p_key != NUL) crypt_decode(ptr, len); +#endif return ptr; } -#endif /* FEAT_CRYPT */ #ifdef UNIX static void diff --git a/src/po/eo.po b/src/po/eo.po index 7ea2e69dd4..23543ebda9 100644 --- a/src/po/eo.po +++ b/src/po/eo.po @@ -23,14 +23,29 @@ msgid "" msgstr "" "Project-Id-Version: Vim(Esperanto)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-02-16 21:54+0100\n" -"PO-Revision-Date: 2010-02-16 21:56+0100\n" +"POT-Creation-Date: 2010-06-12 07:15+0200\n" +"PO-Revision-Date: 2010-06-12 08:24+0200\n" "Last-Translator: Dominique PELLÉ \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +msgid "E831: bf_key_init() called with empty password" +msgstr "E831: bf_key_init() alvokita kun malplena pasvorto" + +msgid "E820: sizeof(uint32_t) != 4" +msgstr "E820: sizeof(uint32_t) != 4" + +msgid "E817: Blowfish big/little endian use wrong" +msgstr "E817: Misuzo de pezkomenca/pezfina en blowfish" + +msgid "E818: sha256 test failed" +msgstr "E818: Testo de sha256 fiaskis" + +msgid "E819: Blowfish test failed" +msgstr "E819: Testo de blowfish fiaskis" + msgid "E82: Cannot allocate any buffer, exiting..." msgstr "E82: Ne eblas disponigi iun ajn bufron, nun eliras..." @@ -749,7 +764,6 @@ msgstr "daÅ­rigas en %s" msgid "E133: :return not inside a function" msgstr "E133: \":return\" ekster funkcio" -#, c-format msgid "" "\n" "# global variables:\n" @@ -1039,7 +1053,7 @@ msgid " (NOT FOUND)" msgstr " (NETROVITA)" msgid " (not supported)" -msgstr " (nesubtenita)" +msgstr " (nesubtenata)" msgid "[Deleted]" msgstr "[ForviÅita]" @@ -1070,8 +1084,8 @@ msgstr "Neniu kontrolpunkto estas difinita" msgid "%3d %s %s line %ld" msgstr "%3d %s %s linio %ld" -msgid "E750: First use :profile start " -msgstr "E750: Uzu unue \":profile start \"" +msgid "E750: First use \":profile start {fname}\"" +msgstr "E750: Uzu unue \":profile start {dosiernomo}\"" #, c-format msgid "Save changes to \"%s\"?" @@ -1096,10 +1110,6 @@ msgstr "E164: Ne eblas iri antaÅ­ ol la unuan dosieron" msgid "E165: Cannot go beyond last file" msgstr "E165: Ne eblas iri preter la lastan dosieron" -#, c-format -msgid "E666: compiler not supported: %s" -msgstr "E666: kompililo nesubtenita: %s" - #, c-format msgid "Searching for \"%s\" in \"%s\"" msgstr "Serĉado de \"%s\" en \"%s\"" @@ -1279,6 +1289,9 @@ msgstr "" msgid "E467: Custom completion requires a function argument" msgstr "E467: Uzula kompletigo bezonas funkcian argumenton" +msgid "unknown" +msgstr "nekonata" + #, c-format msgid "E185: Cannot find color scheme %s" msgstr "E185: Ne eblas trovi agordaron de koloroj %s" @@ -1645,6 +1658,9 @@ msgstr "Konverto kun 'charconvert' fiaskis" msgid "can't read output of 'charconvert'" msgstr "ne eblas legi la eligon de 'charconvert'" +msgid "E821: File is encrypted with unknown method" +msgstr "E821: Dosiero estas ĉifrata per nekonata metodo" + msgid "E676: No matching autocommands for acwrite buffer" msgstr "E676: Neniu kongrua aÅ­tokomando por la bufro acwrite" @@ -1792,6 +1808,10 @@ msgstr "%ld linioj, " msgid "1 character" msgstr "1 signo" +#, c-format +msgid "%lld characters" +msgstr "%lld signoj" + #, c-format msgid "%ld characters" msgstr "%ld signoj" @@ -2169,7 +2189,7 @@ msgstr "E671: Ne eblas trovi titolon de fenestro \"%s\"" #, c-format msgid "E243: Argument not supported: \"-%s\"; Use the OLE version." -msgstr "E243: Ne subtenita argumento: \"-%s\"; Uzu la version OLE." +msgstr "E243: Ne subtenata argumento: \"-%s\"; Uzu la version OLE." msgid "E672: Unable to open window inside MDI application" msgstr "E672: Ne eblas malfermi fenestron interne de aplikaĵo MDI" @@ -2321,7 +2341,7 @@ msgstr "E618: \"%s\" ne estas dosiero de PostSkripta rimedo" #, c-format msgid "E619: file \"%s\" is not a supported PostScript resource file" -msgstr "E619: \"%s\" ne estas subtenita dosiero de PostSkripta rimedo" +msgstr "E619: \"%s\" ne estas subtenata dosiero de PostSkripta rimedo" #, c-format msgid "E621: \"%s\" resource file has wrong version" @@ -2441,14 +2461,14 @@ msgstr "E623: Ne eblis naskigi procezon cscope" msgid "E567: no cscope connections" msgstr "E567: neniu konekto al cscope" -#, c-format -msgid "E259: no matches found for cscope query %s of %s" -msgstr "E259: neniu kongruo trovita por serĉo per cscope %s de %s" - #, c-format msgid "E469: invalid cscopequickfix flag %c for %c" msgstr "E469: nevalida flago cscopequickfix %c de %c" +#, c-format +msgid "E259: no matches found for cscope query %s of %s" +msgstr "E259: neniu kongruo trovita por serĉo per cscope %s de %s" + msgid "cscope commands:\n" msgstr "komandoj de cscope:\n" @@ -2880,6 +2900,9 @@ msgstr "Nevalida argumento por" msgid "%d files to edit\n" msgstr "%d redaktendaj dosieroj\n" +msgid "netbeans is not supported with this GUI\n" +msgstr "netbeans ne estas subtenata kun tiu grafika interfaco\n" + msgid "This Vim was not compiled with the diff feature." msgstr "Tiu Vim ne estis kompilita kun la kompara eblo." @@ -2971,7 +2994,7 @@ msgid "--\t\t\tOnly file names after this" msgstr "--\t\t\tNur dosiernomoj malantaÅ­ tio" msgid "--literal\t\tDon't expand wildcards" -msgstr "--literal\t\tNe ekspansii ĵokerojn" +msgstr "--literal\t\tNe malvolvi ĵokerojn" msgid "-register\t\tRegister this gvim for OLE" msgstr "-register\t\tRegistri tiun gvim al OLE" @@ -3397,7 +3420,7 @@ msgid "E296: Seek error in swap file write" msgstr "E296: Eraro de enpoziciigo dum skribo de permutodosiero .swp" msgid "E297: Write error in swap file" -msgstr "E297: Eraro de skribo en permutodosiero .swp" +msgstr "E297: Skriberaro en permutodosiero .swp" msgid "E300: Swap file already exists (symlink attack?)" msgstr "E300: Permutodosiero .swp jam ekzistas (ĉu atako per simbola ligilo?)" @@ -3537,14 +3560,20 @@ msgstr "" "\n" "(Indas konservi tiun dosieron per alia nomo\n" -msgid "and run diff with the original file to check for changes)\n" -msgstr "kaj lanĉi diff kun la originala dosiero por kontroli la ÅanÄojn)\n" +msgid "and run diff with the original file to check for changes)" +msgstr "kaj lanĉi diff kun la originala dosiero por kontroli la ÅanÄojn)" + +msgid "Recovery completed. Buffer contents equals file contents." +msgstr "" +"RestaÅ­ro finiÄis. La enhavo de la bufro samas kun la enhavo de la dosiero." msgid "" -"Delete the .swp file afterwards.\n" +"\n" +"You may want to delete the .swp file now.\n" "\n" msgstr "" -"Poste forviÅi la permutodosieron .swp.\n" +"\n" +"La dosiero .swp nun forviÅindas.\n" "\n" #. use msg() to start the scrolling properly @@ -4074,6 +4103,9 @@ msgstr "lego el kontaktoskatolo de Netbeans" msgid "E658: NetBeans connection lost for buffer %ld" msgstr "E658: Konekto de NetBeans perdita por bufro %ld" +msgid "E511: netbeans already connected" +msgstr "E511: nebeans jam konektata" + msgid "E505: " msgstr "E505: " @@ -4236,7 +4268,7 @@ msgid "E518: Unknown option" msgstr "E518: Nekonata opcio" msgid "E519: Option not supported" -msgstr "E519: Opcio ne subtenita" +msgstr "E519: Opcio ne subtenata" msgid "E520: Not allowed in a modeline" msgstr "E520: Ne permesita en reÄimlinio" @@ -4312,7 +4344,7 @@ msgid "E537: 'commentstring' must be empty or contain %s" msgstr "E537: 'commentstring' devas esti malplena aÅ­ enhavi %s" msgid "E538: No mouse support" -msgstr "E538: Neniu muso subtenita" +msgstr "E538: Neniu muso subtenata" msgid "E540: Unclosed expression sequence" msgstr "E540: '}' mankas" @@ -4637,7 +4669,7 @@ msgstr "E374: Mankas ] en formata ĉeno" #, c-format msgid "E375: Unsupported %%%c in format string" -msgstr "E375: Nesubtenita %%%c en formata ĉeno" +msgstr "E375: Nesubtenata %%%c en formata ĉeno" #, c-format msgid "E376: Invalid %%%c in format string prefix" @@ -4949,11 +4981,11 @@ msgid "E772: Spell file is for newer version of Vim" msgstr "E772: Literuma dosiero estas por pli nova versio de Vim" msgid "E770: Unsupported section in spell file" -msgstr "E770: Nesubtenita sekcio en literuma dosiero" +msgstr "E770: Nesubtenata sekcio en literuma dosiero" #, c-format msgid "Warning: region %s not supported" -msgstr "Averto: regiono %s ne subtenita" +msgstr "Averto: regiono %s ne subtenata" #, c-format msgid "Reading affix file %s ..." @@ -4965,11 +4997,11 @@ msgstr "Malsukceso dum konverto de vorto en %s linio %d: %s" #, c-format msgid "Conversion in %s not supported: from %s to %s" -msgstr "Konverto en %s nesubtenita: de %s al %s" +msgstr "Konverto en %s nesubtenata: de %s al %s" #, c-format msgid "Conversion in %s not supported" -msgstr "Konverto en %s nesubtenita" +msgstr "Konverto en %s nesubtenata" #, c-format msgid "Invalid value for FLAG in %s line %d: %s" @@ -5189,7 +5221,7 @@ msgid "E751: Output file name must not have region name" msgstr "E751: Nomo de eliga dosiero ne devas havi nomon de regiono" msgid "E754: Only up to 8 regions supported" -msgstr "E754: Nur 8 regionoj subtenitaj" +msgstr "E754: Nur 8 regionoj subtenataj" #, c-format msgid "E755: Invalid region in %s" @@ -5589,6 +5621,75 @@ msgstr "Uzis CUT_BUFFER0 anstataÅ­ malplenan apartigon" msgid "No undo possible; continue anyway" msgstr "Malfaro neebla; daÅ­rigi tamene" +#, c-format +msgid "E828: Cannot open undo file for writing: %s" +msgstr "E828: Ne eblas malfermi la malfaran dosieron por skribi: %s" + +#, c-format +msgid "E825: Corrupted undo file (%s): %s" +msgstr "E825: Difektita malfara dosiero (%s): %s" + +msgid "Cannot write undo file in any directory in 'undodir'" +msgstr "Ne eblis skribi malfaran dosieron en iu dosiero ajn de 'undodir'" + +#, c-format +msgid "Will not overwrite with undo file, cannot read: %s" +msgstr "Ne superkribos malfaran dosieron, ne eblis legi: %s" + +#, c-format +msgid "Will not overwrite, this is not an undo file: %s" +msgstr "Ne superskribos, tio ne estas malfara dosiero: %s" + +msgid "Skipping undo file write, nothing to undo" +msgstr "Preterpasas skribon de malfara dosiero, nenio por malfari" + +#, c-format +msgid "Writing undo file: %s" +msgstr "Skribas malfaran dosieron: %s" + +#, c-format +msgid "E829: write error in undo file: %s" +msgstr "E829: Skriberaro en malfara dosiero: %s" + +#, c-format +msgid "Not reading undo file, owner differs: %s" +msgstr "Ne legas malfaran dosieron, posedanto malsamas: %s" + +#, c-format +msgid "Reading undo file: %s" +msgstr "Legado de de malfara dosiero: %s" + +#, c-format +msgid "E822: Cannot open undo file for reading: %s" +msgstr "E822: Ne eblas malfermi malfaran dosieron por legi: %s" + +#, c-format +msgid "E823: Not an undo file: %s" +msgstr "E823: Ne estas malfara dosiero: %s" + +#, c-format +msgid "E832: Non-encrypted file has encrypted undo file: %s" +msgstr "E832: Ne ĉifrata dosiero havas ĉifratan malfaran dosieron: %s" + +#, c-format +msgid "E826: Undo file decryption failed: %s" +msgstr "E826: Malĉifrado de malfara dosiero fiaskis: %s" + +#, c-format +msgid "E827: Undo file is encrypted: %s" +msgstr "E827: Malfara dosiero estas ĉifrata: %s" + +#, c-format +msgid "E824: Incompatible undo file: %s" +msgstr "E824: Malkongrua malfara dosiero: %s" + +msgid "File contents changed, cannot use undo info" +msgstr "Enhavo de dosiero ÅanÄiÄis, ne eblas uzi malfarajn infomojn" + +#, c-format +msgid "Finished reading undo file %s" +msgstr "Finis legi malfaran dosieron %s" + msgid "Already at oldest change" msgstr "Jam al la plej malnova ÅanÄo" @@ -5596,8 +5697,8 @@ msgid "Already at newest change" msgstr "Jam al la plej nova ÅanÄo" #, c-format -msgid "Undo number %ld not found" -msgstr "Malfaro numero %ld netrovita" +msgid "E830: Undo number %ld not found" +msgstr "E830: Malfara numero %ld netrovita" msgid "E438: u_undo: line numbers wrong" msgstr "E438: u_undo: nevalidaj numeroj de linioj" @@ -6318,7 +6419,7 @@ msgid "E523: Not allowed here" msgstr "E523: Ne permesita tie" msgid "E359: Screen mode setting not supported" -msgstr "E359: ReÄimo de ekrano ne subtenita" +msgstr "E359: ReÄimo de ekrano ne subtenata" msgid "E49: Invalid scroll size" msgstr "E49: Nevalida grando de rulumo" @@ -6354,7 +6455,7 @@ msgid "E78: Unknown mark" msgstr "E78: Nekonata marko" msgid "E79: Cannot expand wildcards" -msgstr "E79: Ne eblas ekspansi ĵokerojn" +msgstr "E79: Ne eblas malvolvi ĵokerojn" msgid "E591: 'winheight' cannot be smaller than 'winminheight'" msgstr "E591: 'winheight' ne rajtas esti malpli ol 'winminheight'" diff --git a/src/po/fr.po b/src/po/fr.po index b341489c87..0c6f69b24b 100644 --- a/src/po/fr.po +++ b/src/po/fr.po @@ -15,14 +15,29 @@ msgid "" msgstr "" "Project-Id-Version: Vim(Français)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-02-16 21:54+0100\n" -"PO-Revision-Date: 2010-02-16 22:10+0100\n" +"POT-Creation-Date: 2010-06-12 07:15+0200\n" +"PO-Revision-Date: 2010-06-12 07:56+0200\n" "Last-Translator: Dominique Pellé \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO_8859-15\n" "Content-Transfer-Encoding: 8bit\n" +msgid "E831: bf_key_init() called with empty password" +msgstr "E831: bf_key_init() appelée avec un mot de passe vide" + +msgid "E820: sizeof(uint32_t) != 4" +msgstr "E820: sizeof(uint32_t) != 4" + +msgid "E817: Blowfish big/little endian use wrong" +msgstr "E817: petit/gros boutisme incorrect dans blowfish" + +msgid "E818: sha256 test failed" +msgstr "E818: le test de sha256 a échoué" + +msgid "E819: Blowfish test failed" +msgstr "E819: le test de blowfish a échoué" + # AB - Il faut respecter l'esprit plus que la lettre. msgid "E82: Cannot allocate any buffer, exiting..." msgstr "E82: Aucun tampon ne peut être alloué, Vim doit s'arrêter" @@ -590,7 +605,7 @@ msgid "E723: Missing end of Dictionary '}': %s" msgstr "E723: Il manque '}' à la fin du Dictionnaire %s" msgid "E724: variable nested too deep for displaying" -msgstr "E724: variable trop imbriquée pour être afficher" +msgstr "E724: variable trop imbriquée pour être affichée" #, c-format msgid "E740: Too many arguments for function %s" @@ -840,7 +855,6 @@ msgstr "E133: :return en dehors d'une fonction" # AB - La version française est capitalisée pour être en accord avec les autres # commentaires enregistrés dans le fichier viminfo. -#, c-format msgid "" "\n" "# global variables:\n" @@ -1113,7 +1127,7 @@ msgstr "E148: :global doit # qui est utilisé. #, c-format msgid "Pattern found in every line: %s" -msgstr "Motif trouvé dans toutes les ligne : %s" +msgstr "Motif trouvé dans toutes les lignes : %s" # AB - Ne pas traduire le dollar. # AB - Ce message n'est volontairement pas traduit. En effet, il fait partie @@ -1251,8 +1265,8 @@ msgstr "Aucun point d'arr msgid "%3d %s %s line %ld" msgstr "%3d %s %s ligne %ld" -msgid "E750: First use :profile start " -msgstr "E750: Utilisez d'abord :profile start " +msgid "E750: First use \":profile start {fname}\"" +msgstr "E750: Utilisez d'abord \":profile start {nomfichier}\"" # AB - "changes to" est redondant et a été omis de la version française. #, c-format @@ -1465,6 +1479,9 @@ msgstr "E468: Seul le compl msgid "E467: Custom completion requires a function argument" msgstr "E467: Le complètement personnalisé requiert une fonction en argument" +msgid "unknown" +msgstr "inconnu" + #, c-format msgid "E185: Cannot find color scheme %s" msgstr "E185: Impossible de trouver le jeu de couleurs %s" @@ -1732,7 +1749,7 @@ msgid "E198: cmd_pchar beyond the command length" msgstr "E198: cmd_pchar au-delà de la longueur de la commande" msgid "E199: Active window or buffer deleted" -msgstr "E199: Tampon ou fenêtre active effacé(e)" +msgstr "E199: Fenêtre ou tampon actif effacé" msgid "E812: Autocommands changed buffer or buffer name" msgstr "E812: Des autocommandes on changé le tampon ou le nom du tampon" @@ -1830,6 +1847,9 @@ msgstr "La conversion avec 'charconvert' a msgid "can't read output of 'charconvert'" msgstr "Impossible de lire la sortie de 'charconvert'" +msgid "E821: File is encrypted with unknown method" +msgstr "E821: Le fichier est chiffré avec une méthode inconnue" + msgid "E676: No matching autocommands for acwrite buffer" msgstr "E676: Pas d'autocommande correspondante pour le tampon acwrite" @@ -1898,15 +1918,15 @@ msgstr "E512: Erreur de fermeture de fichier" msgid "E513: write error, conversion failed (make 'fenc' empty to override)" msgstr "" -"E513: Erreur d'écriture, échec de conversion (videz 'fenc' pour passer " -"outre)" +"E513: Erreur d'écriture, échec de conversion (videz 'fenc' pour passer outre)" #, c-format msgid "" "E513: write error, conversion failed in line %ld (make 'fenc' empty to " "override)" msgstr "" -"E513: Erreur d'écriture, échec de conversion à la ligne %ld (videz 'fenc' pour passer outre)" +"E513: Erreur d'écriture, échec de conversion à la ligne %ld (videz 'fenc' " +"pour passer outre)" msgid "E514: write error (file system full?)" msgstr "E514: erreur d'écriture (système de fichiers plein ?)" @@ -1986,6 +2006,10 @@ msgstr "%ld lignes, " msgid "1 character" msgstr "1 caractère" +#, c-format +msgid "%lld characters" +msgstr "%lld caractères" + #, c-format msgid "%ld characters" msgstr "%ld caractères" @@ -2657,15 +2681,15 @@ msgstr "E623: Impossible d'engendrer le processus cscope" msgid "E567: no cscope connections" msgstr "E567: Aucune connexion cscope" +#, c-format +msgid "E469: invalid cscopequickfix flag %c for %c" +msgstr "E469: Drapeau cscopequickfix %c invalide pour %c" + # DB - todo #, c-format msgid "E259: no matches found for cscope query %s of %s" msgstr "E259: aucune correspondance trouvée pour la requête cscope %s de %s" -#, c-format -msgid "E469: invalid cscopequickfix flag %c for %c" -msgstr "E469: Drapeau cscopequickfix %c invalide pour %c" - msgid "cscope commands:\n" msgstr "commandes cscope :\n" @@ -3097,6 +3121,9 @@ msgstr "Argument invalide pour" msgid "%d files to edit\n" msgstr "%d fichiers à éditer\n" +msgid "netbeans is not supported with this GUI\n" +msgstr "netbeans n'est pas supporté avec cette interface graphique\n" + msgid "This Vim was not compiled with the diff feature." msgstr "Ce Vim n'a pas été compilé avec la fonctionnalité diff" @@ -3371,7 +3398,9 @@ msgid "--servername \tSend to/become the Vim server " msgstr "--servername \tEnvoyer au/devenir le serveur Vim nommé " msgid "--startuptime \tWrite startup timing messages to " -msgstr "--startuptime \tÉcrire les messages d'horodatage au démarrage dans " +msgstr "" +"--startuptime \tÉcrire les messages d'horodatage au démarrage dans " +"" msgid "-i \t\tUse instead of .viminfo" msgstr "-i \t\tUtiliser au lieu du viminfo habituel" @@ -3759,15 +3788,20 @@ msgstr "" "\n" "(Vous voudrez peut-être enregistrer ce fichier sous un autre nom\n" -msgid "and run diff with the original file to check for changes)\n" +msgid "and run diff with the original file to check for changes)" msgstr "" -"et lancer diff avec le fichier original pour repérer les changements)\n" +"et lancer diff avec le fichier original pour repérer les changements)" + +msgid "Recovery completed. Buffer contents equals file contents." +msgstr "Récupération achevée. Le contenu du tampon est identique au contenu du fichier." msgid "" -"Delete the .swp file afterwards.\n" +"\n" +"You may want to delete the .swp file now.\n" "\n" msgstr "" -"Effacez ensuite le fichier .swp.\n" +"\n" +"Il est conseillé d'effacer maintenant le fichier .swp.\n" "\n" #. use msg() to start the scrolling properly @@ -4299,6 +4333,9 @@ msgstr "read sur la socket Netbeans" msgid "E658: NetBeans connection lost for buffer %ld" msgstr "E658: Connexion NetBeans perdue pour le tampon %ld" +msgid "E511: netbeans already connected" +msgstr "E511: netbeans déjà connecté" + msgid "E505: " msgstr "E505: " @@ -5376,7 +5413,7 @@ msgstr "Trop de r #, c-format msgid "/ line ignored in %s line %d: %s" -msgstr "Ligne / ignorée dans %s ligen %d : %s" +msgstr "Ligne / ignorée dans %s ligne %d : %s" #, c-format msgid "Invalid region nr in %s line %d: %s" @@ -5599,7 +5636,7 @@ msgid "E399: Not enough arguments: syntax region %s" msgstr "E399: Pas assez d'arguments : syntax region %s" msgid "E400: No cluster specified" -msgstr "E400: Aucun grappe spécifiée" +msgstr "E400: Aucune grappe spécifiée" #, c-format msgid "E401: Pattern delimiter not found: %s" @@ -5834,6 +5871,77 @@ msgstr "CUT_BUFFER0 utilis msgid "No undo possible; continue anyway" msgstr "Annulation impossible ; continuer" +#, c-format +msgid "E828: Cannot open undo file for writing: %s" +msgstr "E828: Impossible d'ouvrir le fichier d'annulations en écriture : %s" + +#, c-format +msgid "E825: Corrupted undo file (%s): %s" +msgstr "E825: Fichier d'annulations corrompu (%s) : %s" + +msgid "Cannot write undo file in any directory in 'undodir'" +msgstr "Impossible d'écrire le fichier d'annulations dans n'importe " +"quel répertoire de 'undodir'" + +#, c-format +msgid "Will not overwrite with undo file, cannot read: %s" +msgstr "Le fichier d'annulations de sera pas écrasé, impossible de lire : %s" + +#, c-format +msgid "Will not overwrite, this is not an undo file: %s" +msgstr "Fichier ne sera pas écrasé, ce n'est pas un fichier d'annulations : %s" + +msgid "Skipping undo file write, nothing to undo" +msgstr "Le fichier d'annulations n'est pas écrit, rien à annuler" + +#, c-format +msgid "Writing undo file: %s" +msgstr "Écriture du fichier d'annulations : %s" + +#, c-format +msgid "E829: write error in undo file: %s" +msgstr "E829: Erreur d'écriture dans le fichier d'annulations : %s" + +#, c-format +msgid "Not reading undo file, owner differs: %s" +msgstr "Le fichier d'annulations n'est pas lu, propriétaire différent : %s" + +#, c-format +msgid "Reading undo file: %s" +msgstr "Lecture du fichier d'annulations : %s..." + +#, c-format +msgid "E822: Cannot open undo file for reading: %s" +msgstr "E822: Impossible d'ouvrir le fichier d'annulations en lecture : %s" + +#, c-format +msgid "E823: Not an undo file: %s" +msgstr "E823: Ce n'est pas un fichier d'annulations : %s" + +#, c-format +msgid "E832: Non-encrypted file has encrypted undo file: %s" +msgstr "E832: Fichier non-chiffré a un fichier d'annulations chiffré : %s" + +#, c-format +msgid "E826: Undo file decryption failed: %s" +msgstr "E826: Déchiffrage du fichier d'annulation a échoué : %s" + +#, c-format +msgid "E827: Undo file is encrypted: %s" +msgstr "E827: Le fichier d'annulations est chiffré : %s" + +#, c-format +msgid "E824: Incompatible undo file: %s" +msgstr "E824: Fichier d'annulations incompatible : %s" + +msgid "File contents changed, cannot use undo info" +msgstr "Le contenu du fichier a changé, impossible d'utiliser les " +"informations d'annulation" + +#, c-format +msgid "Finished reading undo file %s" +msgstr "Fin de lecture du fichier d'annulations %s" + msgid "Already at oldest change" msgstr "Déjà à la modification la plus ancienne" @@ -5841,8 +5949,8 @@ msgid "Already at newest change" msgstr "Déjà à la modification la plus récente" #, c-format -msgid "Undo number %ld not found" -msgstr "L'annulation n° %ld introuvable" +msgid "E830: Undo number %ld not found" +msgstr "E830: Annulation n° %ld introuvable" msgid "E438: u_undo: line numbers wrong" msgstr "E438: u_undo : numéros de ligne erronés" @@ -6535,7 +6643,7 @@ msgid "E776: No location list" msgstr "E776: Aucune liste d'emplacements" msgid "E43: Damaged match string" -msgstr "E43: Le chaîne de recherche est endommagée" +msgstr "E43: La chaîne de recherche est endommagée" msgid "E44: Corrupted regexp program" msgstr "E44: L'automate de regexp est corrompu" @@ -6650,9 +6758,3 @@ msgstr "La recherche a atteint le HAUT, et continue en BAS" msgid "search hit BOTTOM, continuing at TOP" msgstr "La recherche a atteint le BAS, et continue en HAUT" - -#~ msgid "E569: maximum number of cscope connections reached" -#~ msgstr "E569: nombre maximum de connexions cscope atteint" - -#~ msgid "[NL found]" -#~ msgstr "[NL trouvé]" diff --git a/src/proto.h b/src/proto.h index 2b248a5e34..3313656150 100644 --- a/src/proto.h +++ b/src/proto.h @@ -149,7 +149,7 @@ void qsort __ARGS((void *base, size_t elm_count, size_t elm_size, int (*cmp)(con # endif # include "regexp.pro" # include "screen.pro" -# ifdef FEAT_CRYPT +# if defined(FEAT_CRYPT) || defined(FEAT_PERSISTENT_UNDO) # include "sha256.pro" # endif # include "search.pro" diff --git a/src/proto/blowfish.pro b/src/proto/blowfish.pro index da3560e78f..ba18176fbc 100644 --- a/src/proto/blowfish.pro +++ b/src/proto/blowfish.pro @@ -1,5 +1,5 @@ /* blowfish.c */ -void bf_key_init __ARGS((char_u *password)); +void bf_key_init __ARGS((char_u *password, char_u *salt, int salt_len)); void bf_ofb_init __ARGS((char_u *iv, int iv_len)); void bf_crypt_encode __ARGS((char_u *from, size_t len, char_u *to)); void bf_crypt_decode __ARGS((char_u *ptr, long len)); diff --git a/src/proto/sha256.pro b/src/proto/sha256.pro index c5237f439f..651a0a0afe 100644 --- a/src/proto/sha256.pro +++ b/src/proto/sha256.pro @@ -2,7 +2,7 @@ void sha256_start __ARGS((context_sha256_T *ctx)); void sha256_update __ARGS((context_sha256_T *ctx, char_u *input, UINT32_T length)); void sha256_finish __ARGS((context_sha256_T *ctx, char_u digest[32])); -char_u *sha256_key __ARGS((char_u *buf)); +char_u *sha256_key __ARGS((char_u *buf, char_u *salt, int salt_len)); int sha256_self_test __ARGS((void)); -void sha2_seed __ARGS((char_u header[], int header_len)); +void sha2_seed __ARGS((char_u header[], int header_len, char_u salt[], int salt_len)); /* vim: set ft=c : */ diff --git a/src/sha256.c b/src/sha256.c index 0f9585623e..c24e8b8f83 100644 --- a/src/sha256.c +++ b/src/sha256.c @@ -23,9 +23,6 @@ #if defined(FEAT_CRYPT) || defined(FEAT_PERSISTENT_UNDO) static void sha256_process __ARGS((context_sha256_T *ctx, char_u data[64])); -static char_u *sha256_bytes __ARGS((char_u *buf, int buflen)); -static unsigned int get_some_time __ARGS((void)); - #define GET_UINT32(n, b, i) \ { \ @@ -271,14 +268,22 @@ sha256_finish(ctx, digest) PUT_UINT32(ctx->state[6], digest, 24); PUT_UINT32(ctx->state[7], digest, 28); } +#endif /* FEAT_CRYPT || FEAT_PERSISTENT_UNDO */ + +#if defined(FEAT_CRYPT) || defined(PROTO) +static char_u *sha256_bytes __ARGS((char_u *buf, int buf_len, char_u *salt, int salt_len)); +static unsigned int get_some_time __ARGS((void)); /* - * Returns hex digest of "buf[buflen]" in a static array. + * Returns hex digest of "buf[buf_len]" in a static array. + * if "salt" is not NULL also do "salt[salt_len]". */ static char_u * -sha256_bytes(buf, buflen) +sha256_bytes(buf, buf_len, salt, salt_len) char_u *buf; - int buflen; + int buf_len; + char_u *salt; + int salt_len; { char_u sha256sum[32]; static char_u hexit[65]; @@ -288,7 +293,9 @@ sha256_bytes(buf, buflen) sha256_self_test(); sha256_start(&ctx); - sha256_update(&ctx, buf, buflen); + sha256_update(&ctx, buf, buf_len); + if (salt != NULL) + sha256_update(&ctx, salt, salt_len); sha256_finish(&ctx, sha256sum); for (j = 0; j < 32; j++) sprintf((char *)hexit + j * 2, "%02x", sha256sum[j]); @@ -300,14 +307,16 @@ sha256_bytes(buf, buflen) * Returns sha256(buf) as 64 hex chars in static array. */ char_u * -sha256_key(buf) +sha256_key(buf, salt, salt_len) char_u *buf; + char_u *salt; + int salt_len; { /* No passwd means don't encrypt */ if (buf == NULL || *buf == NUL) return (char_u *)""; - return sha256_bytes(buf, (int)STRLEN(buf)); + return sha256_bytes(buf, (int)STRLEN(buf), salt, salt_len); } /* @@ -354,7 +363,8 @@ sha256_self_test() if (i < 2) { hexit = sha256_bytes((char_u *)sha_self_test_msg[i], - (int)STRLEN(sha_self_test_msg[i])); + (int)STRLEN(sha_self_test_msg[i]), + NULL, 0); STRCPY(output, hexit); } else @@ -380,29 +390,32 @@ sha256_self_test() static unsigned int get_some_time() { -#ifdef HAVE_GETTIMEOFDAY +# ifdef HAVE_GETTIMEOFDAY struct timeval tv; /* Using usec makes it less predictable. */ gettimeofday(&tv, NULL); return (unsigned int)(tv.tv_sec + tv.tv_usec); -#else +# else return (unsigned int)time(NULL); -#endif +# endif } /* * set header = sha2_seed(random_data); */ void -sha2_seed(header, header_len) - char_u header[]; +sha2_seed(header, header_len, salt, salt_len) + char_u *header; int header_len; + char_u *salt; + int salt_len; { int i; static char_u random_data[1000]; char_u sha256sum[32]; context_sha256_T ctx; + srand(get_some_time()); for (i = 0; i < (int)sizeof(random_data) - 1; i++) @@ -411,8 +424,13 @@ sha2_seed(header, header_len) sha256_update(&ctx, (char_u *)random_data, sizeof(random_data)); sha256_finish(&ctx, sha256sum); + /* put first block into header. */ for (i = 0; i < header_len; i++) header[i] = sha256sum[i % sizeof(sha256sum)]; + + /* put remaining block into salt. */ + for (i = 0; i < salt_len; i++) + salt[i] = sha256sum[(i + header_len) % sizeof(sha256sum)]; } -#endif /* FEAT_CRYPT || FEAT_PERSISTENT_UNDO */ +#endif /* FEAT_CRYPT */ diff --git a/src/testdir/test71.in b/src/testdir/test71.in index 717b66026a..56dee55741 100644 --- a/src/testdir/test71.in +++ b/src/testdir/test71.in @@ -71,5 +71,5 @@ VimCrypt~01!lV' end of cm=0 bytes start of cm=1 bytes -VimCrypt~02!¨Ò9ZšÙ¢èì”F¼èÃ[,ì”F¼ƒ€z¼Ö軂 y¾Ô( +VimCrypt~02!k)¾—#ÝSœõ=ºàÈ#¥M´†JÃAÍ¥M´†!€›õáÒ‚˜÷ Ú end of cm=1 bytes From b89b824c419b5275ae5c384ccf1ad75966323dbc Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 14 Jun 2010 01:39:13 +0200 Subject: [PATCH 04/11] Fix tiny build, move functions to undo.c. --HG-- branch : vim73 --- runtime/doc/todo.txt | 11 +++----- src/fileio.c | 57 ----------------------------------------- src/proto/fileio.pro | 2 -- src/undo.c | 60 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 63 insertions(+), 67 deletions(-) diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index f898c0297b..73f4d51d14 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1088,19 +1088,19 @@ Vim 7.3: - using NSIS 2.46: install on Windows 7 works, but no "Edit with Vim" menu. Use register_shell_extension()? (George Reilly, 2010 May 26) Ron's version: http://dev.ronware.org/p/vim/finfo?name=gvim.nsi -- Update for crypt code to use salt. (Mohsin May 30) - Make the strengthen_key value 10000, equivalent to crypting 10 Kbyte of - text. - Also crypt the swap file, each block separately. Change mf_write() and mf_read(). - How to get b_p_key to these functions? -> Store buf_T pointer in mfp. - - Generate a seed for the swapfile, put it in block 0. + - Generate a salt and seed for the swapfile, put it in block 0. - For each block, use password + seed + byte offset to crypt/decrypt. - When changing the password need to read back with the old password and write again with the new one. - Fill the gaps in the block with random bytes, otherwise it's easy to check for correct password by finding NUL bytes. - Verify recovery works. +- Patch for conceal feature and 'foldcolumn'. (Dominique Pelle, 2010 Jun 10, + second patch) +- patch for conceal feature and 'modifiable'. (Dominique Pelle, 2010 Jun 9) - undofile: keep markers where the file was written/read, so that it's easy to go back to a saved version of the file: ":earlier 1f" (f for file)? Also add ":earlier 1d" (d for day). @@ -1108,9 +1108,6 @@ Vim 7.3: Show "file saved" marker in :undolist Function to get undo tree: undotree(). List of lists. Each entry is a dictionary: {'nr': 2, 'time': 1234, 'saved': 1} -- Patch for conceal feature and 'foldcolumn'. (Dominique Pelle, 2010 Jun 10, - second patch) -- patch for conceal feature and 'modifiable'. (Dominique Pelle, 2010 Jun 9) - Remove support for GTK 1? Patch by James Vega, Jun 11. Patches to include: - Patch for Lisp support with ECL (Mikael Jansson, 2008 Oct 25) diff --git a/src/fileio.c b/src/fileio.c index bfc11d0d95..aad76170ef 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -3011,63 +3011,6 @@ prepare_crypt_write(buf, lenp) #endif /* FEAT_CRYPT */ -/* - * Like fwrite() but crypt the bytes when 'key' is set. - * Returns 1 if successful. - */ - size_t -fwrite_crypt(buf, ptr, len, fp) - buf_T *buf UNUSED; - char_u *ptr; - size_t len; - FILE *fp; -{ -#ifdef FEAT_CRYPT - char_u *copy; - char_u small_buf[100]; - size_t i; - - if (*buf->b_p_key == NUL) - return fwrite(ptr, len, (size_t)1, fp); - if (len < 100) - copy = small_buf; /* no malloc()/free() for short strings */ - else - { - copy = lalloc(len, FALSE); - if (copy == NULL) - return 0; - } - crypt_encode(ptr, len, copy); - i = fwrite(copy, len, (size_t)1, fp); - if (copy != small_buf) - vim_free(copy); - return i; -#else - return fwrite(ptr, len, (size_t)1, fp); -#endif -} - -/* - * Read a string of length "len" from "fd". - * When 'key' is set decrypt the bytes. - */ - char_u * -read_string_decrypt(buf, fd, len) - buf_T *buf UNUSED; - FILE *fd; - int len; -{ - char_u *ptr; - - ptr = read_string(fd, len); -#ifdef FEAT_CRYPT - if (ptr != NULL || *buf->b_p_key != NUL) - crypt_decode(ptr, len); -#endif - return ptr; -} - - #ifdef UNIX static void set_file_time(fname, atime, mtime) diff --git a/src/proto/fileio.pro b/src/proto/fileio.pro index 75285dfef3..88d3c27ea1 100644 --- a/src/proto/fileio.pro +++ b/src/proto/fileio.pro @@ -4,8 +4,6 @@ int readfile __ARGS((char_u *fname, char_u *sfname, linenr_T from, linenr_T line int prep_exarg __ARGS((exarg_T *eap, buf_T *buf)); int prepare_crypt_read __ARGS((FILE *fp)); char_u *prepare_crypt_write __ARGS((buf_T *buf, int *lenp)); -size_t fwrite_crypt __ARGS((buf_T *buf, char_u *ptr, size_t len, FILE *fp)); -char_u *read_string_decrypt __ARGS((buf_T *buf, FILE *fd, int len)); int check_file_readonly __ARGS((char_u *fname, int perm)); int buf_write __ARGS((buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_T end, exarg_T *eap, int append, int forceit, int reset_changed, int filtering)); void msg_add_fname __ARGS((buf_T *buf, char_u *fname)); diff --git a/src/undo.c b/src/undo.c index 592604ff35..07412acc5c 100644 --- a/src/undo.c +++ b/src/undo.c @@ -102,6 +102,8 @@ static void u_freeentry __ARGS((u_entry_T *, long)); #ifdef FEAT_PERSISTENT_UNDO static void corruption_error __ARGS((char *msg, char_u *file_name)); static void u_free_uhp __ARGS((u_header_T *uhp)); +static size_t fwrite_crypt __ARGS((buf_T *buf UNUSED, char_u *ptr, size_t len, FILE *fp)); +static char_u *read_string_decrypt __ARGS((buf_T *buf UNUSED, FILE *fd, int len)); static int serialize_header __ARGS((FILE *fp, buf_T *buf, char_u *hash)); static int serialize_uhp __ARGS((FILE *fp, buf_T *buf, u_header_T *uhp)); static u_header_T *unserialize_uhp __ARGS((FILE *fp, char_u *file_name)); @@ -661,7 +663,7 @@ nomem: return FAIL; } -#ifdef FEAT_PERSISTENT_UNDO +#if defined(FEAT_PERSISTENT_UNDO) || defined(PROTO) # define UF_START_MAGIC "Vim\237UnDo\345" /* magic at start of undofile */ # define UF_START_MAGIC_LEN 9 @@ -801,6 +803,62 @@ u_free_uhp(uhp) vim_free(uhp); } +/* + * Like fwrite() but crypt the bytes when 'key' is set. + * Returns 1 if successful. + */ + static size_t +fwrite_crypt(buf, ptr, len, fp) + buf_T *buf UNUSED; + char_u *ptr; + size_t len; + FILE *fp; +{ +#ifdef FEAT_CRYPT + char_u *copy; + char_u small_buf[100]; + size_t i; + + if (*buf->b_p_key == NUL) + return fwrite(ptr, len, (size_t)1, fp); + if (len < 100) + copy = small_buf; /* no malloc()/free() for short strings */ + else + { + copy = lalloc(len, FALSE); + if (copy == NULL) + return 0; + } + crypt_encode(ptr, len, copy); + i = fwrite(copy, len, (size_t)1, fp); + if (copy != small_buf) + vim_free(copy); + return i; +#else + return fwrite(ptr, len, (size_t)1, fp); +#endif +} + +/* + * Read a string of length "len" from "fd". + * When 'key' is set decrypt the bytes. + */ + static char_u * +read_string_decrypt(buf, fd, len) + buf_T *buf UNUSED; + FILE *fd; + int len; +{ + char_u *ptr; + + ptr = read_string(fd, len); +#ifdef FEAT_CRYPT + if (ptr != NULL || *buf->b_p_key != NUL) + crypt_decode(ptr, len); +#endif + return ptr; +} + static int serialize_header(fp, buf, hash) FILE *fp; From 1a0457e4311ee1c222323d3be53f6fba607a8395 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 21 Jun 2010 06:15:46 +0200 Subject: [PATCH 05/11] Crypt the swapfile. --HG-- branch : vim73 --- runtime/doc/editing.txt | 10 +- runtime/doc/helphelp.txt | 22 +- runtime/doc/recover.txt | 39 +++ runtime/doc/tags | 4 +- runtime/doc/todo.txt | 22 +- runtime/doc/usr_11.txt | 2 + runtime/syntax/c.vim | 2 +- src/blowfish.c | 42 ++- src/fileio.c | 43 ++- src/globals.h | 4 + src/main.c | 2 +- src/memfile.c | 54 +++- src/memline.c | 599 +++++++++++++++++++++++++++++++++------ src/misc2.c | 55 ++++ src/option.c | 17 +- src/proto/blowfish.pro | 2 + src/proto/memline.pro | 5 +- src/proto/misc2.pro | 2 + src/sha256.c | 8 +- src/structs.h | 17 +- src/testdir/test72.in | 2 +- src/undo.c | 22 ++ src/workshop.c | 4 +- 23 files changed, 824 insertions(+), 155 deletions(-) diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt index a10e8220a7..a89d8bb8de 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1332,10 +1332,12 @@ There are a few things to remember when editing binary files: Vim is able to write files encrypted, and read them back. The encrypted text cannot be read without the right key. -Note: The swapfile and text in memory is not encrypted. A system -administrator will be able to see your text while you are editing it. -When filtering text with ":!filter" or using ":w !command" the text is not -encrypted, this may reveal it to others. +The text in the swap file and the undo file is also encrypted. + +Note: The text in memory is not encrypted. A system administrator may be able +to see your text while you are editing it. When filtering text with +":!filter" or using ":w !command" the text is not encrypted, this may reveal +it to others. The 'viminfo' file is not encrypted. WARNING: If you make a typo when entering the key and then write the file and exit, the text will be lost! diff --git a/runtime/doc/helphelp.txt b/runtime/doc/helphelp.txt index eea639fd21..8fa0a2ddc4 100644 --- a/runtime/doc/helphelp.txt +++ b/runtime/doc/helphelp.txt @@ -119,9 +119,9 @@ Help on help files *helphelp* *:lh* *:lhelpgrep* :lh[elpgrep] {pattern}[@xx] Same as ":helpgrep", except the location list is used - instead of the quickfix list. If the help window is + instead of the quickfix list. If the help window is already opened, then the location list for that window - is used. Otherwise, a new help window is opened and + is used. Otherwise, a new help window is opened and the location list for that window is set. The location list for the current window is not changed. @@ -281,9 +281,9 @@ The first line in a help file should have the following format: *helpfile_name.txt* For Vim version 7.3 Last change: 2010 June 4 -The first field is a link to the help file name. The second field describes -the applicable Vim version. The last field specifies the last modification -date of the file. Each field is separated by a tab. +The first field is a link to the help file name. The second field describes +the applicable Vim version. The last field specifies the last modification +date of the file. Each field is separated by a tab. At the bottom of the help file, place a Vim modeline to set the 'textwidth' and 'tabstop' options and the 'filetype' to 'help'. Never set a global option @@ -295,30 +295,30 @@ TAGS To define a help tag, place the name between asterisks (*tag-name*). The tag-name should be different from all the Vim help tag names and ideally -should begin with the name of the Vim plugin. The tag name is usually right +should begin with the name of the Vim plugin. The tag name is usually right aligned on a line. When referring to an existing help tag and to create a hot-link, place the name between two bars (|) eg. |help-writing|. When referring to a Vim option in the help file, place the option name between -two single quotes. eg. 'statusline' +two single quotes, eg. 'statusline' HIGHLIGHTING -To define a column heading, use a tilde character at the end of the line. This -will highlight the column heading in a different color. E.g. +To define a column heading, use a tilde character at the end of the line. +This will highlight the column heading in a different color. E.g. Column heading~ To separate sections in a help file, place a series of '=' characters in a -line starting from the first column. The section separator line is highlighted +line starting from the first column. The section separator line is highlighted differently. To quote a block of ex-commands verbatim, place a greater than (>) character at the end of the line before the block and a less than (<) character as the -first non-blank on a line following the block. Any line starting in column 1 +first non-blank on a line following the block. Any line starting in column 1 also implicitly stops the block of ex-commands before it. E.g. > function Example_Func() echo "Example" diff --git a/runtime/doc/recover.txt b/runtime/doc/recover.txt index fd960eb121..f088c0824c 100644 --- a/runtime/doc/recover.txt +++ b/runtime/doc/recover.txt @@ -188,4 +188,43 @@ will continue to get warning messages that the ".swp" file already exists. {Vi: recovers in another way and sends mail if there is something to recover} + +ENCRYPTION AND THE SWAP FILE *:recover-crypt* + +When the text file is encrypted the swap file is encrypted as well. This +makes recovery a bit more complicated. When recovering from a swap file and +encryption has been used, you will be asked to enter one or two crypt keys. + +If the text file does not exist you will only be asked to enter the crypt key +for the swap file. + +If the text file does exist, it may be encrypted in a different way than the +swap file. You will be asked for the crypt key twice: + + Need encryption key for "/tmp/tt" ~ + Enter encryption key: ****** ~ + "/tmp/tt" [crypted] 23200L, 522129C ~ + Using swap file "/tmp/.tt.swp" ~ + Original file "/tmp/tt" ~ + Swap file is encrypted: "/tmp/.tt.swp" ~ + If you entered a new crypt key but did not write the text file, ~ + enter the new crypt key. ~ + If you wrote the text file after changing the crypt key press enter ~ + to use the same key for text file and swap file ~ + Enter encryption key: ~ + +You can be in one of these two situations: + +1. The encryption key was not changed, or after changing the key the text file + was written. You will be prompted for the crypt key twice. The second + time you can simply press Enter. That means the same key is used for the + text file and the swap file. +2. You entered a new encryption key, but did not save the text file. Vim will + then use the new key for the swap file, and the text file will still be + encrypted with the old key. At the second prompt enter the new key. + +Note that after recovery the key of the swap file will be used for the text +file. Thus if you write the text file, you need to use that new key. + + vim:tw=78:ts=8:ft=help:norl: diff --git a/runtime/doc/tags b/runtime/doc/tags index ec4c8abc96..936cb5e386 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -2577,6 +2577,7 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME* :read! insert.txt /*:read!* :rec recover.txt /*:rec* :recover recover.txt /*:recover* +:recover-crypt recover.txt /*:recover-crypt* :red undo.txt /*:red* :redi various.txt /*:redi* :redir various.txt /*:redir* @@ -6914,7 +6915,6 @@ os_unix.txt os_unix.txt /*os_unix.txt* os_vms.txt os_vms.txt /*os_vms.txt* os_win32.txt os_win32.txt /*os_win32.txt* other-features vi_diff.txt /*other-features* -ownsyntax eval.txt /*ownsyntax* p change.txt /*p* page-down intro.txt /*page-down* page-up intro.txt /*page-up* @@ -8220,7 +8220,7 @@ vt100-cursor-keys term.txt /*vt100-cursor-keys* vt100-function-keys term.txt /*vt100-function-keys* w motion.txt /*w* w32-clientserver remote.txt /*w32-clientserver* -w:ownsyntax-variable eval.txt /*w:ownsyntax-variable* +w:current_syntax syntax.txt /*w:current_syntax* w:var eval.txt /*w:var* warningmsg-variable eval.txt /*warningmsg-variable* white-space pattern.txt /*white-space* diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index 73f4d51d14..78ad818aec 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1088,18 +1088,16 @@ Vim 7.3: - using NSIS 2.46: install on Windows 7 works, but no "Edit with Vim" menu. Use register_shell_extension()? (George Reilly, 2010 May 26) Ron's version: http://dev.ronware.org/p/vim/finfo?name=gvim.nsi -- Also crypt the swap file, each block separately. Change mf_write() and - mf_read(). - - How to get b_p_key to these functions? -> Store buf_T pointer in mfp. - - Generate a salt and seed for the swapfile, put it in block 0. - - For each block, use password + seed + byte offset to crypt/decrypt. - - When changing the password need to read back with the old password and - write again with the new one. - - Fill the gaps in the block with random bytes, otherwise it's easy to - check for correct password by finding NUL bytes. - - Verify recovery works. +- Also crypt the swap file, each block separately: + - When changing the password or 'cryptmethod' need to read back with the + old password and write again with the new one. + Problem: when the file is not written, key differs between text file and + swap file! +- Patch for :ownsyntax completion (Dominique Pelle, 2010 Jun 20) - Patch for conceal feature and 'foldcolumn'. (Dominique Pelle, 2010 Jun 10, second patch) + Also patch from Vince, 2010 Jun 15. And another June 16. + However: more generic patch on the way. - patch for conceal feature and 'modifiable'. (Dominique Pelle, 2010 Jun 9) - undofile: keep markers where the file was written/read, so that it's easy to go back to a saved version of the file: ":earlier 1f" (f for file)? @@ -1110,6 +1108,7 @@ Vim 7.3: dictionary: {'nr': 2, 'time': 1234, 'saved': 1} - Remove support for GTK 1? Patch by James Vega, Jun 11. Patches to include: +- Patch for X clibboard CurrentTime, (Fries, 2010 Jun 20) - Patch for Lisp support with ECL (Mikael Jansson, 2008 Oct 25) - Minor patches from Dominique Pelle, 2010 May 15 - Gvimext patch to support wide file names. (Szabolcs Horvat 2008 Sep 10) @@ -1117,8 +1116,9 @@ Patches to include: - Patch to support clipboard for Mac terminal. (Jjgod Jiang, 2009 Aug 1) - Patch to support :browse for more commands. (Lech Lorens, 2009 Jul 18) - Patch to improve javascript indenting. (Hari Kumar G, 2010 May 22) +- Patch to use return value of 'formatexpr'. (James Vega, 2010 Jun 16) - Patch to make CTRL-L work better with 'ignorecase' and 'smarcase'. (Martin - Toft, 2010 Jun 8) + Toft, 2010 Jun 8, Jun 16) - Patch to add diff functionality to 2html.vim. (Christian Brabandt, 2009 Dec 15) - Win32: patch for better font scaling. (George Reilly, 2009 Mar 26) diff --git a/runtime/doc/usr_11.txt b/runtime/doc/usr_11.txt index c6c75b1bf9..4c40408057 100644 --- a/runtime/doc/usr_11.txt +++ b/runtime/doc/usr_11.txt @@ -283,6 +283,8 @@ machines. Therefore, don't rely on Vim always warning you. If you really don't want to see this message, you can add the 'A' flag to the 'shortmess' option. But it's very unusual that you need this. +For remarks about encryption and the swap file, see |:recover-crypt|. + ============================================================================== *11.4* Further reading diff --git a/runtime/syntax/c.vim b/runtime/syntax/c.vim index 94562127c2..a0b94ae973 100644 --- a/runtime/syntax/c.vim +++ b/runtime/syntax/c.vim @@ -270,7 +270,7 @@ if !exists("c_no_c99") " ISO C99 endif " Accept %: for # (C99) -syn region cPreCondit start="^\s*\(%:\|#\)\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" contains=cComment,cCommentL,cCppString,cCharacter,cCppParen,cParenError,cNumbers,cCommentError,cSpaceError +syn region cPreCondit start="^\s*\(%:\|#\)\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" keepend contains=cComment,cCommentL,cCppString,cCharacter,cCppParen,cParenError,cNumbers,cCommentError,cSpaceError syn match cPreCondit display "^\s*\(%:\|#\)\s*\(else\|endif\)\>" if !exists("c_no_if0") if !exists("c_no_if0_fold") diff --git a/src/blowfish.c b/src/blowfish.c index f0b97b7b90..c8e68d2244 100644 --- a/src/blowfish.c +++ b/src/blowfish.c @@ -436,13 +436,7 @@ bf_key_init(password, salt, salt_len) key[i] = j; } - for (i = 0; i < 256; ++i) - { - sbx[0][i] = sbi[0][i]; - sbx[1][i] = sbi[1][i]; - sbx[2][i] = sbi[2][i]; - sbx[3][i] = sbi[3][i]; - } + mch_memmove(sbx, sbi, 4 * 4 * 256); for (i = 0; i < 18; ++i) { @@ -655,6 +649,40 @@ bf_crypt_init_keys(passwd) } } +static int save_randbyte_offset; +static int save_update_offset; +static char_u save_ofb_buffer[BF_OFB_LEN]; +static UINT32_T save_pax[18]; +static UINT32_T save_sbx[4][256]; + +/* + * Save the current crypt state. Can only be used once before + * bf_crypt_restore(). + */ + void +bf_crypt_save() +{ + save_randbyte_offset = randbyte_offset; + save_update_offset = update_offset; + mch_memmove(save_ofb_buffer, ofb_buffer, BF_OFB_LEN); + mch_memmove(save_pax, pax, 4 * 18); + mch_memmove(save_sbx, sbx, 4 * 4 * 256); +} + +/* + * Restore the current crypt state. Can only be used after + * bf_crypt_save(). + */ + void +bf_crypt_restore() +{ + randbyte_offset = save_randbyte_offset; + update_offset = save_update_offset; + mch_memmove(ofb_buffer, save_ofb_buffer, BF_OFB_LEN); + mch_memmove(pax, save_pax, 4 * 18); + mch_memmove(sbx, save_sbx, 4 * 4 * 256); +} + /* * Run a test to check if the encryption works as expected. * Give an error and return FAIL when not. diff --git a/src/fileio.c b/src/fileio.c index aad76170ef..b099461675 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -64,7 +64,7 @@ static void check_marks_read __ARGS((void)); #endif #ifdef FEAT_CRYPT static int get_crypt_method __ARGS((char *ptr, int len)); -static char_u *check_for_cryptkey __ARGS((char_u *cryptkey, char_u *ptr, long *sizep, off_t *filesizep, int newfile, int *did_ask)); +static char_u *check_for_cryptkey __ARGS((char_u *cryptkey, char_u *ptr, long *sizep, off_t *filesizep, int newfile, char_u *fname, int *did_ask)); #endif #ifdef UNIX static void set_file_time __ARGS((char_u *fname, time_t atime, time_t mtime)); @@ -995,6 +995,13 @@ retry: #endif } +#ifdef FEAT_CRYPT + if (cryptkey != NULL) + /* Need to reset the state, but keep the key, don't want to ask for it + * again. */ + crypt_pop_state(); +#endif + /* * When retrying with another "fenc" and the first time "fileformat" * will be reset. @@ -1426,7 +1433,8 @@ retry: */ if (filesize == 0) cryptkey = check_for_cryptkey(cryptkey, ptr, &size, - &filesize, newfile, &did_ask_for_key); + &filesize, newfile, sfname, + &did_ask_for_key); /* * Decrypt the read bytes. */ @@ -2277,8 +2285,14 @@ failed: save_file_ff(curbuf); /* remember the current file format */ #ifdef FEAT_CRYPT - if (cryptkey != curbuf->b_p_key) - free_crypt_key(cryptkey); + if (cryptkey != NULL) + { + crypt_pop_state(); + if (cryptkey != curbuf->b_p_key) + free_crypt_key(cryptkey); + /* don't set cryptkey to NULL, it's used below as a flag that + * encryption was used */ + } #endif #ifdef FEAT_MBYTE @@ -2869,12 +2883,13 @@ get_crypt_method(ptr, len) * Return the (new) encryption key, NULL for no encryption. */ static char_u * -check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile, did_ask) +check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile, fname, did_ask) char_u *cryptkey; /* previous encryption key or NULL */ char_u *ptr; /* pointer to read bytes */ long *sizep; /* length of read bytes */ off_t *filesizep; /* nr of bytes used from file */ int newfile; /* editing a new buffer */ + char_u *fname; /* file name to display */ int *did_ask; /* flag: whether already asked for key */ { int method = get_crypt_method((char *)ptr, *sizep); @@ -2882,7 +2897,6 @@ check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile, did_ask) if (method >= 0) { curbuf->b_p_cm = method; - use_crypt_method = method; if (method > 0) (void)blowfish_self_test(); if (cryptkey == NULL && !*did_ask) @@ -2895,6 +2909,8 @@ check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile, did_ask) * option and don't free it. bf needs hash of the key saved. * Don't ask for the key again when first time Enter was hit. * Happens when retrying to detect encoding. */ + smsg((char_u *)_(need_key_msg), fname); + msg_scroll = TRUE; cryptkey = get_crypt_key(newfile, FALSE); *did_ask = TRUE; @@ -2913,6 +2929,8 @@ check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile, did_ask) int seed_len = crypt_seed_len[method]; int salt_len = crypt_salt_len[method]; + crypt_push_state(); + use_crypt_method = method; if (method == 0) crypt_init_keys(cryptkey); else @@ -2924,7 +2942,8 @@ check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile, did_ask) /* Remove magic number from the text */ *filesizep += CRYPT_MAGIC_LEN + salt_len + seed_len; *sizep -= CRYPT_MAGIC_LEN + salt_len + seed_len; - mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN + salt_len + seed_len, (size_t)*sizep); + mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN + salt_len + seed_len, + (size_t)*sizep); } } /* When starting to edit a new file which does not have encryption, clear @@ -2956,6 +2975,7 @@ prepare_crypt_read(fp) if (method < 0 || method != curbuf->b_p_cm) return FAIL; + crypt_push_state(); if (method == 0) crypt_init_keys(curbuf->b_p_key); else @@ -2974,6 +2994,8 @@ prepare_crypt_read(fp) /* * Prepare for writing encrypted bytes for buffer "buf". * Returns a pointer to an allocated header of length "*lenp". + * When out of memory returns NULL. + * Otherwise calls crypt_push_state(), call crypt_pop_state() later. */ char_u * prepare_crypt_write(buf, lenp) @@ -2990,6 +3012,7 @@ prepare_crypt_write(buf, lenp) + CRYPT_SEED_LEN_MAX + 2); if (header != NULL) { + crypt_push_state(); use_crypt_method = buf->b_p_cm; /* select pkzip or blowfish */ vim_strncpy(header, (char_u *)crypt_magic[use_crypt_method], CRYPT_MAGIC_LEN); @@ -4404,7 +4427,7 @@ restore_backup: write_info.bw_fd = fd; #ifdef FEAT_CRYPT - if (*buf->b_p_key && !filtering) + if (*buf->b_p_key != NUL && !filtering) { char_u *header; int header_len; @@ -4674,6 +4697,10 @@ restore_backup: if (!backup_copy) mch_set_acl(wfname, acl); #endif +#ifdef FEAT_CRYPT + if (wb_flags & FIO_ENCRYPTED) + crypt_pop_state(); +#endif #if defined(FEAT_MBYTE) && defined(FEAT_EVAL) diff --git a/src/globals.h b/src/globals.h index f4ec25713c..c9bfc1fe87 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1564,6 +1564,10 @@ EXTERN short disallow_gui INIT(= FALSE); EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM")); EXTERN char bot_top_msg[] INIT(= N_("search hit BOTTOM, continuing at TOP")); +#ifdef FEAT_CRYPT +EXTERN char need_key_msg[] INIT(= N_("Need encryption key for \"%s\"")); +#endif + /* * Comms. with the session manager (XSMP) */ diff --git a/src/main.c b/src/main.c index f4e1fde195..0f29255864 100644 --- a/src/main.c +++ b/src/main.c @@ -595,7 +595,7 @@ main */ if (recoverymode && fname == NULL) { - recover_names(NULL, TRUE, 0); + recover_names(NULL, TRUE, 0, NULL); mch_exit(0); } diff --git a/src/memfile.c b/src/memfile.c index 5412a61456..c6f5fdf8d0 100644 --- a/src/memfile.c +++ b/src/memfile.c @@ -85,6 +85,7 @@ static void mf_ins_free __ARGS((memfile_T *, bhdr_T *)); static bhdr_T *mf_rem_free __ARGS((memfile_T *)); static int mf_read __ARGS((memfile_T *, bhdr_T *)); static int mf_write __ARGS((memfile_T *, bhdr_T *)); +static int mf_write_block __ARGS((memfile_T *mfp, bhdr_T *hp, off_t offset, unsigned size)); static int mf_trans_add __ARGS((memfile_T *, bhdr_T *)); static void mf_do_open __ARGS((memfile_T *, char_u *, int)); @@ -161,6 +162,9 @@ mf_open(fname, flags) mfp->mf_trans[i] = NULL; /* trans lists are empty */ } mfp->mf_page_size = MEMFILE_PAGE_SIZE; +#ifdef FEAT_CRYPT + mfp->mf_old_key = NULL; +#endif #ifdef USE_FSTATFS /* @@ -422,7 +426,7 @@ mf_new(mfp, negative, page_count) } /* - * get existing block 'nr' with 'page_count' pages + * Get existing block "nr" with "page_count" pages. * * Note: The caller should first check a negative nr with mf_trans_del() */ @@ -1050,6 +1054,13 @@ mf_read(mfp, hp) PERROR(_("E295: Read error in swap file")); return FAIL; } + +#ifdef FEAT_CRYPT + /* Decrypt if 'key' is set and this is a data block. */ + if (*mfp->mf_buffer->b_p_key != NUL) + ml_decrypt_data(mfp, hp->bh_data, offset, size); +#endif + return OK; } @@ -1107,8 +1118,7 @@ mf_write(mfp, hp) else page_count = hp2->bh_page_count; size = page_size * page_count; - if ((unsigned)vim_write(mfp->mf_fd, - (hp2 == NULL ? hp : hp2)->bh_data, size) != size) + if (mf_write_block(mfp, hp2 == NULL ? hp : hp2, offset, size) == FAIL) { /* * Avoid repeating the error message, this mostly happens when the @@ -1133,6 +1143,42 @@ mf_write(mfp, hp) return OK; } +/* + * Write block "hp" with data size "size" to file "mfp->mf_fd". + * Takes care of encryption. + * Return FAIL or OK. + */ + static int +mf_write_block(mfp, hp, offset, size) + memfile_T *mfp; + bhdr_T *hp; + off_t offset UNUSED; + unsigned size; +{ + char_u *data = hp->bh_data; + int result = OK; + +#ifdef FEAT_CRYPT + /* Encrypt if 'key' is set and this is a data block. */ + if (*mfp->mf_buffer->b_p_key != NUL) + { + data = ml_encrypt_data(mfp, data, offset, size); + if (data == NULL) + return FAIL; + } +#endif + + if ((unsigned)vim_write(mfp->mf_fd, data, size) != size) + result = FAIL; + +#ifdef FEAT_CRYPT + if (data != hp->bh_data) + vim_free(data); +#endif + + return result; +} + /* * Make block number for *hp positive and add it to the translation list * @@ -1156,7 +1202,7 @@ mf_trans_add(mfp, hp) return FAIL; /* - * get a new number for the block. + * Get a new number for the block. * If the first item in the free list has sufficient pages, use its number * Otherwise use mf_blocknr_max. */ diff --git a/src/memline.c b/src/memline.c index d9043dce63..75800b15bd 100644 --- a/src/memline.c +++ b/src/memline.c @@ -65,10 +65,12 @@ typedef struct pointer_block PTR_BL; /* contents of a pointer block */ typedef struct data_block DATA_BL; /* contents of a data block */ typedef struct pointer_entry PTR_EN; /* block/line-count pair */ -#define DATA_ID (('d' << 8) + 'a') /* data block id */ -#define PTR_ID (('p' << 8) + 't') /* pointer block id */ -#define BLOCK0_ID0 'b' /* block 0 id 0 */ -#define BLOCK0_ID1 '0' /* block 0 id 1 */ +#define DATA_ID (('d' << 8) + 'a') /* data block id */ +#define PTR_ID (('p' << 8) + 't') /* pointer block id */ +#define BLOCK0_ID0 'b' /* block 0 id 0 */ +#define BLOCK0_ID1 '0' /* block 0 id 1 */ +#define BLOCK0_ID1_C0 'c' /* block 0 id 1 'cm' 0 */ +#define BLOCK0_ID1_C1 'C' /* block 0 id 1 'cm' 1 */ /* * pointer to a block, used in a pointer block @@ -128,7 +130,8 @@ struct data_block #define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE) /* size of data block header */ #define B0_FNAME_SIZE_ORG 900 /* what it was in older versions */ -#define B0_FNAME_SIZE 898 +#define B0_FNAME_SIZE_NOCRYPT 898 /* 2 bytes used for other things */ +#define B0_FNAME_SIZE_CRYPT 890 /* 10 bytes used for other things */ #define B0_UNAME_SIZE 40 #define B0_HNAME_SIZE 40 /* @@ -155,7 +158,8 @@ struct data_block */ struct block0 { - char_u b0_id[2]; /* id for block 0: BLOCK0_ID0 and BLOCK0_ID1 */ + char_u b0_id[2]; /* id for block 0: BLOCK0_ID0 and BLOCK0_ID1, + * BLOCK0_ID1_C0, BLOCK0_ID1_C1 */ char_u b0_version[10]; /* Vim version string */ char_u b0_page_size[4];/* number of bytes per page */ char_u b0_mtime[4]; /* last modification time of file */ @@ -177,12 +181,18 @@ struct block0 * when there is room, for very long file names it's omitted. */ #define B0_DIRTY 0x55 -#define b0_dirty b0_fname[B0_FNAME_SIZE_ORG-1] +#define b0_dirty b0_fname[B0_FNAME_SIZE_ORG - 1] /* * The b0_flags field is new in Vim 7.0. */ -#define b0_flags b0_fname[B0_FNAME_SIZE_ORG-2] +#define b0_flags b0_fname[B0_FNAME_SIZE_ORG - 2] + +/* + * Crypt seed goes here, 8 bytes. New in Vim 7.3. + * Without encryption these bytes may be used for 'fenc'. + */ +#define b0_seed b0_fname[B0_FNAME_SIZE_ORG - 2 - MF_SEED_LEN] /* The lowest two bits contain the fileformat. Zero means it's not set * (compatible with Vim 6.x), otherwise it's EOL_UNIX + 1, EOL_DOS + 1 or @@ -216,7 +226,18 @@ static linenr_T lowest_marked = 0; #define ML_FLUSH 0x02 /* flush locked block */ #define ML_SIMPLE(x) (x & 0x10) /* DEL, INS or FIND */ -static void ml_upd_block0 __ARGS((buf_T *buf, int set_fname)); +/* argument for ml_upd_block0() */ +typedef enum { + UB_FNAME = 0 /* update timestamp and filename */ + , UB_SAME_DIR /* update the B0_SAME_DIR flag */ + , UB_CRYPT /* update crypt key */ +} upd_block0_T; + +#ifdef FEAT_CRYPT +static void ml_set_b0_crypt __ARGS((buf_T *buf, ZERO_BL *b0p)); +#endif +static int ml_check_b0_id __ARGS((ZERO_BL *b0p)); +static void ml_upd_block0 __ARGS((buf_T *buf, upd_block0_T what)); static void set_b0_fname __ARGS((ZERO_BL *, buf_T *buf)); static void set_b0_dir_flag __ARGS((ZERO_BL *b0p, buf_T *buf)); #ifdef FEAT_MBYTE @@ -242,6 +263,9 @@ static long char_to_long __ARGS((char_u *)); #if defined(UNIX) || defined(WIN3264) static char_u *make_percent_swname __ARGS((char_u *dir, char_u *name)); #endif +#ifdef FEAT_CRYPT +static void ml_crypt_prepare __ARGS((memfile_T *mfp, off_t offset, int reading)); +#endif #ifdef FEAT_BYTEOFF static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype)); #endif @@ -264,7 +288,7 @@ ml_open(buf) /* * init fields in memline struct */ - buf->b_ml.ml_stack_size = 0; /* no stack yet */ + buf->b_ml.ml_stack_size = 0; /* no stack yet */ buf->b_ml.ml_stack = NULL; /* no stack yet */ buf->b_ml.ml_stack_top = 0; /* nothing in the stack */ buf->b_ml.ml_locked = NULL; /* no cached block */ @@ -289,6 +313,9 @@ ml_open(buf) goto error; buf->b_ml.ml_mfp = mfp; +#ifdef FEAT_CRYPT + mfp->mf_buffer = buf; +#endif buf->b_ml.ml_flags = ML_EMPTY; buf->b_ml.ml_line_count = 1; #ifdef FEAT_LINEBREAK @@ -336,12 +363,16 @@ ml_open(buf) mch_get_host_name(b0p->b0_hname, B0_HNAME_SIZE); b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL; long_to_char(mch_get_pid(), b0p->b0_pid); +#ifdef FEAT_CRYPT + if (*buf->b_p_key != NUL) + ml_set_b0_crypt(buf, b0p); +#endif } /* * Always sync block number 0 to disk, so we can check the file name in - * the swap file in findswapname(). Don't do this for help files though - * and spell buffer though. + * the swap file in findswapname(). Don't do this for a help files or + * a spell buffer though. * Only works when there's a swapfile, otherwise it's done when the file * is created. */ @@ -397,6 +428,165 @@ error: return FAIL; } +#if defined(FEAT_CRYPT) || defined(PROTO) +/* + * Prepare encryption for "buf" with block 0 "b0p". + */ + static void +ml_set_b0_crypt(buf, b0p) + buf_T *buf; + ZERO_BL *b0p; +{ + if (*buf->b_p_key == NUL) + b0p->b0_id[1] = BLOCK0_ID1; + else + { + if (buf->b_p_cm == 0) + b0p->b0_id[1] = BLOCK0_ID1_C0; + else + { + b0p->b0_id[1] = BLOCK0_ID1_C1; + /* Generate a seed and store it in block 0 and in the memfile. */ + sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0); + mch_memmove(buf->b_ml.ml_mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN); + } + } +} + +/* + * Called after the crypt key or 'cryptmethod' was changed for "buf". + * Will apply this to the swapfile. + * "old_key" is the previous key. It is equal to buf->b_p_key when + * 'cryptmethod' is changed. + * "old_cm" is the previous 'cryptmethod'. It is equal to buf->b_p_cm when + * 'key' is changed. + */ + void +ml_set_crypt_key(buf, old_key, old_cm) + buf_T *buf; + char_u *old_key; + int old_cm; +{ + memfile_T *mfp = buf->b_ml.ml_mfp; + bhdr_T *hp; + int page_count; + int idx; + long error; + infoptr_T *ip; + PTR_BL *pp; + DATA_BL *dp; + blocknr_T bnum; + int top; + + if (mfp == NULL || mfp->mf_fd < 0) + return; /* no memfile yet, nothing to do */ + + /* Set the key, method and seed to be used for reading, these must be the + * old values. */ + mfp->mf_old_key = old_key; + mfp->mf_old_cm = old_cm; + if (old_cm > 0) + mch_memmove(mfp->mf_old_seed, mfp->mf_seed, MF_SEED_LEN); + + /* Update block 0 with the crypt flag and may set a new seed. */ + ml_upd_block0(buf, UB_CRYPT); + + if (mfp->mf_infile_count > 2) + { + /* + * Need to read back all data blocks from disk, decrypt them with the + * old key/method and mark them to be written. The algorithm is + * similar to what happens in ml_recover(), but we skip negative block + * numbers. + */ + ml_flush_line(buf); /* flush buffered line */ + (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */ + + hp = NULL; + bnum = 1; /* start with block 1 */ + page_count = 1; /* which is 1 page */ + idx = 0; /* start with first index in block 1 */ + error = 0; + buf->b_ml.ml_stack_top = 0; + buf->b_ml.ml_stack = NULL; + buf->b_ml.ml_stack_size = 0; /* no stack yet */ + + for ( ; !got_int; line_breakcheck()) + { + if (hp != NULL) + mf_put(mfp, hp, FALSE, FALSE); /* release previous block */ + + /* get the block (pointer or data) */ + if ((hp = mf_get(mfp, (blocknr_T)bnum, page_count)) == NULL) + { + if (bnum == 1) + break; + ++error; + } + else + { + pp = (PTR_BL *)(hp->bh_data); + if (pp->pb_id == PTR_ID) /* it is a pointer block */ + { + if (pp->pb_count == 0) + { + /* empty block? */ + ++error; + } + else if (idx < (int)pp->pb_count) /* go a block deeper */ + { + if (pp->pb_pointer[idx].pe_bnum < 0) + { + /* Skip data block with negative block number. */ + ++idx; /* get same block again for next index */ + continue; + } + + /* going one block deeper in the tree, new entry in + * stack */ + if ((top = ml_add_stack(buf)) < 0) + { + ++error; + break; /* out of memory */ + } + ip = &(buf->b_ml.ml_stack[top]); + ip->ip_bnum = bnum; + ip->ip_index = idx; + + bnum = pp->pb_pointer[idx].pe_bnum; + page_count = pp->pb_pointer[idx].pe_page_count; + continue; + } + } + else /* not a pointer block */ + { + dp = (DATA_BL *)(hp->bh_data); + if (dp->db_id != DATA_ID) /* block id wrong */ + ++error; + else + { + /* It is a data block, need to write it back to disk. */ + mf_put(mfp, hp, TRUE, FALSE); + hp = NULL; + } + } + } + + if (buf->b_ml.ml_stack_top == 0) /* finished */ + break; + + /* go one block up in the tree */ + ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]); + bnum = ip->ip_bnum; + idx = ip->ip_index + 1; /* go to next index */ + page_count = 1; + } + } + + mfp->mf_old_key = NULL; +} +#endif + /* * ml_setname() is called when the file name of "buf" has been changed. * It may rename the swap file. @@ -475,7 +665,7 @@ ml_setname(buf) #else mf_set_ffname(mfp); #endif - ml_upd_block0(buf, FALSE); + ml_upd_block0(buf, UB_SAME_DIR); break; } vim_free(fname); /* this fname didn't work, try another */ @@ -569,7 +759,7 @@ ml_open_file(buf) */ mf_fullname(mfp); #endif - ml_upd_block0(buf, FALSE); + ml_upd_block0(buf, UB_SAME_DIR); /* Flush block zero, so others can read it */ if (mf_sync(mfp, MFS_ZERO) == OK) @@ -680,16 +870,32 @@ ml_close_notmod() ml_timestamp(buf) buf_T *buf; { - ml_upd_block0(buf, TRUE); + ml_upd_block0(buf, UB_FNAME); +} + +/* + * Return FAIL when the ID of "b0p" is wrong. + */ + static int +ml_check_b0_id(b0p) + ZERO_BL *b0p; +{ + if (b0p->b0_id[0] != BLOCK0_ID0 + || (b0p->b0_id[1] != BLOCK0_ID1 + && b0p->b0_id[1] != BLOCK0_ID1_C0 + && b0p->b0_id[1] != BLOCK0_ID1_C1) + ) + return FAIL; + return OK; } /* * Update the timestamp or the B0_SAME_DIR flag of the .swp file. */ static void -ml_upd_block0(buf, set_fname) +ml_upd_block0(buf, what) buf_T *buf; - int set_fname; + upd_block0_T what; { memfile_T *mfp; bhdr_T *hp; @@ -699,13 +905,17 @@ ml_upd_block0(buf, set_fname) if (mfp == NULL || (hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL) return; b0p = (ZERO_BL *)(hp->bh_data); - if (b0p->b0_id[0] != BLOCK0_ID0 || b0p->b0_id[1] != BLOCK0_ID1) + if (ml_check_b0_id(b0p) == FAIL) EMSG(_("E304: ml_upd_block0(): Didn't get block 0??")); else { - if (set_fname) + if (what == UB_FNAME) set_b0_fname(b0p, buf); - else +#ifdef FEAT_CRYPT + else if (what == UB_CRYPT) + ml_set_b0_crypt(buf, b0p); +#endif + else /* what == UB_SAME_DIR */ set_b0_dir_flag(b0p, buf); } mf_put(mfp, hp, TRUE, FALSE); @@ -731,7 +941,7 @@ set_b0_fname(b0p, buf) /* Systems that cannot translate "~user" back into a path: copy the * file name unmodified. Do use slashes instead of backslashes for * portability. */ - vim_strncpy(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE - 1); + vim_strncpy(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE_CRYPT - 1); # ifdef BACKSLASH_IN_FILENAME forward_slash(b0p->b0_fname); # endif @@ -746,14 +956,16 @@ set_b0_fname(b0p, buf) * First replace home dir path with "~/" with home_replace(). * Then insert the user name to get "~user/". */ - home_replace(NULL, buf->b_ffname, b0p->b0_fname, B0_FNAME_SIZE, TRUE); + home_replace(NULL, buf->b_ffname, b0p->b0_fname, + B0_FNAME_SIZE_CRYPT, TRUE); if (b0p->b0_fname[0] == '~') { flen = STRLEN(b0p->b0_fname); /* If there is no user name or it is too long, don't use "~/" */ if (get_user_name(uname, B0_UNAME_SIZE) == FAIL - || (ulen = STRLEN(uname)) + flen > B0_FNAME_SIZE - 1) - vim_strncpy(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE - 1); + || (ulen = STRLEN(uname)) + flen > B0_FNAME_SIZE_CRYPT - 1) + vim_strncpy(b0p->b0_fname, buf->b_ffname, + B0_FNAME_SIZE_CRYPT - 1); else { mch_memmove(b0p->b0_fname + ulen + 1, b0p->b0_fname + 1, flen); @@ -816,15 +1028,24 @@ add_b0_fenc(b0p, buf) buf_T *buf; { int n; + int size = B0_FNAME_SIZE_NOCRYPT; + +# ifdef FEAT_CRYPT + /* Without encryption use the same offset as in Vim 7.2 to be compatible. + * With encryption it's OK to move elsewhere, the swap file is not + * compatible anyway. */ + if (*buf->b_p_key != NUL) + size = B0_FNAME_SIZE_CRYPT; +# endif n = (int)STRLEN(buf->b_p_fenc); - if (STRLEN(b0p->b0_fname) + n + 1 > B0_FNAME_SIZE) + if ((int)STRLEN(b0p->b0_fname) + n + 1 > size) b0p->b0_flags &= ~B0_HAS_FENC; else { - mch_memmove((char *)b0p->b0_fname + B0_FNAME_SIZE - n, + mch_memmove((char *)b0p->b0_fname + size - n, (char *)buf->b_p_fenc, (size_t)n); - *(b0p->b0_fname + B0_FNAME_SIZE - n - 1) = NUL; + *(b0p->b0_fname + size - n - 1) = NUL; b0p->b0_flags |= B0_HAS_FENC; } } @@ -832,7 +1053,7 @@ add_b0_fenc(b0p, buf) /* - * try to recover curbuf from the .swp file + * Try to recover curbuf from the .swp file. */ void ml_recover() @@ -840,10 +1061,14 @@ ml_recover() buf_T *buf = NULL; memfile_T *mfp = NULL; char_u *fname; + char_u *fname_used = NULL; bhdr_T *hp = NULL; ZERO_BL *b0p; int b0_ff; char_u *b0_fenc = NULL; +#ifdef FEAT_CRYPT + int b0_cm = -1; +#endif PTR_BL *pp; DATA_BL *dp; infoptr_T *ip; @@ -892,14 +1117,14 @@ ml_recover() && ASCII_ISALPHA(fname[len - 1])) { directly = TRUE; - fname = vim_strsave(fname); /* make a copy for mf_open() */ + fname_used = vim_strsave(fname); /* make a copy for mf_open() */ } else { directly = FALSE; /* count the number of matching swap files */ - len = recover_names(&fname, FALSE, 0); + len = recover_names(fname, FALSE, 0, NULL); if (len == 0) /* no swap files found */ { EMSG2(_("E305: No swap file found for %s"), fname); @@ -910,7 +1135,7 @@ ml_recover() else /* several swap files found, choose */ { /* list the names of the swap files */ - (void)recover_names(&fname, TRUE, 0); + (void)recover_names(fname, TRUE, 0, NULL); msg_putchar('\n'); MSG_PUTS(_("Enter number of swap file to use (0 to quit): ")); i = get_number(FALSE, NULL); @@ -918,28 +1143,26 @@ ml_recover() goto theend; } /* get the swap file name that will be used */ - (void)recover_names(&fname, FALSE, i); + (void)recover_names(fname, FALSE, i, &fname_used); } - if (fname == NULL) + if (fname_used == NULL) goto theend; /* out of memory */ /* When called from main() still need to initialize storage structure */ if (called_from_main && ml_open(curbuf) == FAIL) getout(1); -/* - * allocate a buffer structure (only the memline in it is really used) - */ + /* + * Allocate a buffer structure for the swap file that is used for recovery. + * Only the memline in it is really used. + */ buf = (buf_T *)alloc((unsigned)sizeof(buf_T)); if (buf == NULL) - { - vim_free(fname); goto theend; - } -/* - * init fields in memline struct - */ + /* + * init fields in memline struct + */ buf->b_ml.ml_stack_size = 0; /* no stack yet */ buf->b_ml.ml_stack = NULL; /* no stack yet */ buf->b_ml.ml_stack_top = 0; /* nothing in the stack */ @@ -947,23 +1170,24 @@ ml_recover() buf->b_ml.ml_locked = NULL; /* no locked block */ buf->b_ml.ml_flags = 0; -/* - * open the memfile from the old swap file - */ - p = vim_strsave(fname); /* save fname for the message - (mf_open() may free fname) */ - mfp = mf_open(fname, O_RDONLY); /* consumes fname! */ + /* + * open the memfile from the old swap file + */ + p = vim_strsave(fname_used); /* save "fname_used" for the message: + mf_open() will consume "fname_used"! */ + mfp = mf_open(fname_used, O_RDONLY); + fname_used = p; if (mfp == NULL || mfp->mf_fd < 0) { - if (p != NULL) - { - EMSG2(_("E306: Cannot open %s"), p); - vim_free(p); - } + if (fname_used != NULL) + EMSG2(_("E306: Cannot open %s"), fname_used); goto theend; } - vim_free(p); buf->b_ml.ml_mfp = mfp; +#ifdef FEAT_CRYPT + mfp->mf_buffer = buf; + buf->b_p_key = empty_option; +#endif /* * The page size set in mf_open() might be different from the page size @@ -973,16 +1197,15 @@ ml_recover() */ mfp->mf_page_size = MIN_SWAP_PAGE_SIZE; -/* - * try to read block 0 - */ + /* + * try to read block 0 + */ if ((hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL) { msg_start(); MSG_PUTS_ATTR(_("Unable to read block 0 from "), attr | MSG_HIST); msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST); - MSG_PUTS_ATTR( - _("\nMaybe no changes were made or Vim did not update the swap file."), + MSG_PUTS_ATTR(_("\nMaybe no changes were made or Vim did not update the swap file."), attr | MSG_HIST); msg_end(); goto theend; @@ -998,7 +1221,7 @@ ml_recover() msg_end(); goto theend; } - if (b0p->b0_id[0] != BLOCK0_ID0 || b0p->b0_id[1] != BLOCK0_ID1) + if (ml_check_b0_id(b0p) == FAIL) { EMSG2(_("E307: %s does not look like a Vim swap file"), mfp->mf_fname); goto theend; @@ -1024,6 +1247,22 @@ ml_recover() goto theend; } +#ifdef FEAT_CRYPT + if (b0p->b0_id[1] == BLOCK0_ID1_C0) + buf->b_p_cm = b0_cm = 0; + else if (b0p->b0_id[1] == BLOCK0_ID1_C1) + { + buf->b_p_cm = b0_cm = 1; + mch_memmove(mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN); + } +#else + if (b0p->b0_id[1] != BLOCK0_ID1) + { + EMSG2(_("E000: %s is encrypted and this version of Vim does not support encryption"), mfp->mf_fname); + goto theend; + } +#endif + /* * If we guessed the wrong page size, we have to recalculate the * highest block number in the file. @@ -1058,9 +1297,9 @@ ml_recover() b0p = (ZERO_BL *)(hp->bh_data); } -/* - * If .swp file name given directly, use name from swap file for buffer. - */ + /* + * If .swp file name given directly, use name from swap file for buffer. + */ if (directly) { expand_env(b0p->b0_fname, NameBuff, MAXPATHL); @@ -1078,9 +1317,9 @@ ml_recover() smsg((char_u *)_("Original file \"%s\""), NameBuff); msg_putchar('\n'); -/* - * check date of swap file and original file - */ + /* + * check date of swap file and original file + */ mtime = char_to_long(b0p->b0_mtime); if (curbuf->b_ffname != NULL && mch_stat((char *)curbuf->b_ffname, &org_stat) != -1 @@ -1096,10 +1335,16 @@ ml_recover() b0_ff = (b0p->b0_flags & B0_FF_MASK); if (b0p->b0_flags & B0_HAS_FENC) { - for (p = b0p->b0_fname + B0_FNAME_SIZE; - p > b0p->b0_fname && p[-1] != NUL; --p) + int size = B0_FNAME_SIZE_NOCRYPT; + +#ifdef FEAT_CRYPT + /* Use the same size as in add_b0_fenc(). */ + if (b0p->b0_id[1] != BLOCK0_ID1) + size = B0_FNAME_SIZE_CRYPT; +#endif + for (p = b0p->b0_fname + size; p > b0p->b0_fname && p[-1] != NUL; --p) ; - b0_fenc = vim_strnsave(p, (int)(b0p->b0_fname + B0_FNAME_SIZE - p)); + b0_fenc = vim_strnsave(p, (int)(b0p->b0_fname + size - p)); } mf_put(mfp, hp, FALSE, FALSE); /* release block 0 */ @@ -1115,11 +1360,40 @@ ml_recover() /* * Try reading the original file to obtain the values of 'fileformat', * 'fileencoding', etc. Ignore errors. The text itself is not used. + * When the file is encrypted the user is asked to enter the key. */ if (curbuf->b_ffname != NULL) orig_file_status = readfile(curbuf->b_ffname, NULL, (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW); +#ifdef FEAT_CRYPT + if (b0_cm >= 0) + { + /* Need to ask the user for the crypt key. If this fails we continue + * without a key, will probably get garbage text. */ + if (*curbuf->b_p_key != NUL) + { + smsg((char_u *)_("Swap file is encrypted: \"%s\""), fname_used); + MSG_PUTS(_("\nIf you entered a new crypt key but did not write the text file,")); + MSG_PUTS(_("\nenter the new crypt key.")); + MSG_PUTS(_("\nIf you wrote the text file after changing the crypt key press enter")); + MSG_PUTS(_("\nto use the same key for text file and swap file")); + } + else + smsg((char_u *)_(need_key_msg), fname_used); + buf->b_p_key = get_crypt_key(FALSE, FALSE); + if (buf->b_p_key == NULL) + buf->b_p_key = curbuf->b_p_key; + else if (*buf->b_p_key == NUL) + { + vim_free(buf->b_p_key); + buf->b_p_key = curbuf->b_p_key; + } + if (buf->b_p_key == NULL) + buf->b_p_key = empty_option; + } +#endif + /* Use the 'fileformat' and 'fileencoding' as stored in the swap file. */ if (b0_ff != 0) set_fileformat(b0_ff - 1, OPT_LOCAL); @@ -1386,9 +1660,17 @@ ml_recover() MSG_PUTS(_("\nYou may want to delete the .swp file now.\n\n")); cmdline_row = msg_row; } +#ifdef FEAT_CRYPT + if (*buf->b_p_key != NUL && STRCMP(curbuf->b_p_key, buf->b_p_key) != 0) + { + MSG_PUTS(_("Using crypt key from swap file for the text file.\n")); + set_option_value((char_u *)"key", 0L, buf->b_p_key, OPT_LOCAL); + } +#endif redraw_curbuf_later(NOT_VALID); theend: + vim_free(fname_used); recoverymode = FALSE; if (mfp != NULL) { @@ -1398,6 +1680,10 @@ theend: } if (buf != NULL) { +#ifdef FEAT_CRYPT + if (buf->b_p_key != curbuf->b_p_key) + free_string_option(buf->b_p_key); +#endif vim_free(buf->b_ml.ml_stack); vim_free(buf); } @@ -1424,10 +1710,11 @@ theend: * - find the name of the n'th swap file when recovering */ int -recover_names(fname, list, nr) - char_u **fname; /* base for swap file name */ - int list; /* when TRUE, list the swap file names */ - int nr; /* when non-zero, return nr'th swap file name */ +recover_names(fname, list, nr, fname_out) + char_u *fname; /* base for swap file name */ + int list; /* when TRUE, list the swap file names */ + int nr; /* when non-zero, return nr'th swap file name */ + char_u **fname_out; /* result when "nr" > 0 */ { int num_names; char_u *(names[6]); @@ -1447,13 +1734,13 @@ recover_names(fname, list, nr) if (fname != NULL) { #ifdef HAVE_READLINK - /* Expand symlink in the file name, because the swap file is created with - * the actual file instead of with the symlink. */ - if (resolve_symlink(*fname, fname_buf) == OK) - fname_res = fname_buf; - else + /* Expand symlink in the file name, because the swap file is created + * with the actual file instead of with the symlink. */ + if (resolve_symlink(fname, fname_buf) == OK) + fname_res = fname_buf; + else #endif - fname_res = *fname; + fname_res = fname; } if (list) @@ -1480,7 +1767,7 @@ recover_names(fname, list, nr) if (dir_name[0] == '.' && dir_name[1] == NUL) /* check current dir */ { - if (fname == NULL || *fname == NULL) + if (fname == NULL) { #ifdef VMS names[0] = vim_strsave((char_u *)"*_sw%"); @@ -1511,7 +1798,7 @@ recover_names(fname, list, nr) } else /* check directory dir_name */ { - if (fname == NULL || *fname == NULL) + if (fname == NULL) { #ifdef VMS names[0] = concat_fnames(dir_name, (char_u *)"*_sw%", TRUE); @@ -1583,8 +1870,7 @@ recover_names(fname, list, nr) * not able to execute the shell). * Try finding a swap file by simply adding ".swp" to the file name. */ - if (*dirp == NUL && file_count + num_files == 0 - && fname != NULL && *fname != NULL) + if (*dirp == NUL && file_count + num_files == 0 && fname != NULL) { struct stat st; char_u *swapname; @@ -1637,7 +1923,8 @@ recover_names(fname, list, nr) file_count += num_files; if (nr <= file_count) { - *fname = vim_strsave(files[nr - 1 + num_files - file_count]); + *fname_out = vim_strsave( + files[nr - 1 + num_files - file_count]); dirp = (char_u *)""; /* stop searching */ } } @@ -1645,7 +1932,7 @@ recover_names(fname, list, nr) { if (dir_name[0] == '.' && dir_name[1] == NUL) { - if (fname == NULL || *fname == NULL) + if (fname == NULL) MSG_PUTS(_(" In current directory:\n")); else MSG_PUTS(_(" Using specified name:\n")); @@ -1772,7 +2059,7 @@ swapfile_info(fname) { MSG_PUTS(_(" [from Vim version 3.0]")); } - else if (b0.b0_id[0] != BLOCK0_ID0 || b0.b0_id[1] != BLOCK0_ID1) + else if (ml_check_b0_id(&b0) == FAIL) { MSG_PUTS(_(" [does not look like a Vim swap file]")); } @@ -3478,11 +3765,11 @@ ml_find_line(buf, lnum, action) error_block: mf_put(mfp, hp, FALSE, FALSE); error_noblock: -/* - * If action is ML_DELETE or ML_INSERT we have to correct the tree for - * the incremented/decremented line counts, because there won't be a line - * inserted/deleted after all. - */ + /* + * If action is ML_DELETE or ML_INSERT we have to correct the tree for + * the incremented/decremented line counts, because there won't be a line + * inserted/deleted after all. + */ if (action == ML_DELETE) ml_lineadd(buf, 1); else if (action == ML_INSERT) @@ -3505,10 +3792,10 @@ ml_add_stack(buf) top = buf->b_ml.ml_stack_top; - /* may have to increase the stack size */ + /* may have to increase the stack size */ if (top == buf->b_ml.ml_stack_size) { - CHECK(top > 0, _("Stack size increases")); /* more than 5 levels??? */ + CHECK(top > 0, _("Stack size increases")); /* more than 5 levels??? */ newstack = (infoptr_T *)alloc((unsigned)sizeof(infoptr_T) * (buf->b_ml.ml_stack_size + STACK_INCR)); @@ -4518,6 +4805,132 @@ ml_setflags(buf) } } +#if defined(FEAT_CRYPT) || defined(PROTO) +/* + * If "data" points to a data block encrypt the text in it and return a copy + * in allocated memory. Return NULL when out of memory. + * Otherwise return "data". + */ + char_u * +ml_encrypt_data(mfp, data, offset, size) + memfile_T *mfp; + char_u *data; + off_t offset; + unsigned size; +{ + DATA_BL *dp = (DATA_BL *)data; + char_u *head_end; + char_u *text_start; + char_u *new_data; + int text_len; + + if (dp->db_id != DATA_ID) + return data; + + new_data = (char_u *)alloc(size); + if (new_data == NULL) + return NULL; + head_end = (char_u *)(&dp->db_index[dp->db_line_count]); + text_start = (char_u *)dp + dp->db_txt_start; + text_len = size - dp->db_txt_start; + + /* Copy the header and the text. */ + mch_memmove(new_data, dp, head_end - (char_u *)dp); + + /* Encrypt the text. */ + crypt_push_state(); + ml_crypt_prepare(mfp, offset, FALSE); + crypt_encode(text_start, text_len, new_data + dp->db_txt_start); + crypt_pop_state(); + + /* Clear the gap. */ + if (head_end < text_start) + vim_memset(new_data + (head_end - data), 0, text_start - head_end); + + return new_data; +} + +/* + * Decrypt the text in "data" if it points to a data block. + */ + void +ml_decrypt_data(mfp, data, offset, size) + memfile_T *mfp; + char_u *data; + off_t offset; + unsigned size; +{ + DATA_BL *dp = (DATA_BL *)data; + char_u *head_end; + char_u *text_start; + int text_len; + + if (dp->db_id == DATA_ID) + { + head_end = (char_u *)(&dp->db_index[dp->db_line_count]); + text_start = (char_u *)dp + dp->db_txt_start; + text_len = dp->db_txt_end - dp->db_txt_start; + + if (head_end > text_start || dp->db_txt_start > size + || dp->db_txt_end > size) + return; /* data was messed up */ + + /* Decrypt the text in place. */ + crypt_push_state(); + ml_crypt_prepare(mfp, offset, TRUE); + crypt_decode(text_start, text_len); + crypt_pop_state(); + } +} + +/* + * Prepare for encryption/decryption, using the key, seed and offset. + */ + static void +ml_crypt_prepare(mfp, offset, reading) + memfile_T *mfp; + off_t offset; + int reading; +{ + buf_T *buf = mfp->mf_buffer; + char_u salt[50]; + int method; + char_u *key; + char_u *seed; + + if (reading && mfp->mf_old_key != NULL) + { + /* Reading back blocks with the previous key/method/seed. */ + method = mfp->mf_old_cm; + key = mfp->mf_old_key; + seed = mfp->mf_old_seed; + } + else + { + method = buf->b_p_cm; + key = buf->b_p_key; + seed = mfp->mf_seed; + } + + use_crypt_method = method; /* select pkzip or blowfish */ + if (method == 0) + { + vim_snprintf((char *)salt, sizeof(salt), "%s%ld", key, (long)offset); + crypt_init_keys(salt); + } + else + { + /* Using blowfish, add salt and seed. We use the byte offset of the + * block for the salt. */ + vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset); + bf_key_init(key, salt, STRLEN(salt)); + bf_ofb_init(seed, MF_SEED_LEN); + } +} + +#endif + + #if defined(FEAT_BYTEOFF) || defined(PROTO) #define MLCS_MAXL 800 /* max no of lines in chunk */ diff --git a/src/misc2.c b/src/misc2.c index e0eea68b52..1eb4e8a160 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -3746,6 +3746,59 @@ static ulg keys[3]; /* keys defining the pseudo-random sequence */ keys[2] = CRC32(keys[2], (int)(keys[1] >> 24)); \ } +static int crypt_busy = 0; +static ulg saved_keys[3]; +static int saved_crypt_method; + +/* + * Prepare for initializing encryption. If already doing encryption then save + * the state. + * Must always be called symmetrycally with crypt_pop_state(). + */ + void +crypt_push_state() +{ + if (crypt_busy == 1) + { + /* save the state */ + if (use_crypt_method == 0) + { + saved_keys[0] = keys[0]; + saved_keys[1] = keys[1]; + saved_keys[2] = keys[2]; + } + else + bf_crypt_save(); + saved_crypt_method = use_crypt_method; + } + else if (crypt_busy > 1) + EMSG2(_(e_intern2), "crypt_push_state()"); + ++crypt_busy; +} + +/* + * End encryption. If doing encryption before crypt_push_state() then restore + * the saved state. + * Must always be called symmetrycally with crypt_push_state(). + */ + void +crypt_pop_state() +{ + --crypt_busy; + if (crypt_busy == 1) + { + use_crypt_method = saved_crypt_method; + if (use_crypt_method == 0) + { + keys[0] = saved_keys[0]; + keys[1] = saved_keys[1]; + keys[2] = saved_keys[2]; + } + else + bf_crypt_restore(); + } +} + /* * Encrypt "from[len]" into "to[len]". * "from" and "to" can be equal to encrypt in place. @@ -3894,6 +3947,8 @@ get_crypt_key(store, twice) /* since the user typed this, no need to wait for return */ need_wait_return = FALSE; + if (msg_didout) + msg_putchar('\n'); msg_didout = FALSE; free_crypt_key(p2); diff --git a/src/option.c b/src/option.c index d06381cb84..face9fde99 100644 --- a/src/option.c +++ b/src/option.c @@ -5969,13 +5969,18 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf, } } -#if defined(FEAT_CRYPT) && defined(FEAT_CMDHIST) +#if defined(FEAT_CRYPT) /* 'cryptkey' */ else if (gvarp == &p_key) { +# if defined(FEAT_CMDHIST) /* Make sure the ":set" command doesn't show the new value in the * history. */ remove_key_from_history(); +# endif + if (STRCMP(curbuf->b_p_key, oldval) != 0) + /* Need to update the swapfile. */ + ml_set_crypt_key(curbuf, oldval, curbuf->b_p_cm); } #endif @@ -7941,15 +7946,19 @@ set_num_option(opt_idx, varp, value, errbuf, errbuflen, opt_flags) if (curbuf->b_p_cm < 0) { errmsg = e_positive; - curbuf->b_p_cm = 0; + curbuf->b_p_cm = old_value; } if (curbuf->b_p_cm > 1) { errmsg = e_invarg; - curbuf->b_p_cm = 1; + curbuf->b_p_cm = old_value; } if (curbuf->b_p_cm > 0 && blowfish_self_test() == FAIL) - curbuf->b_p_cm = 0; + curbuf->b_p_cm = old_value; + + if (curbuf->b_p_cm != old_value && *curbuf->b_p_key != NUL) + /* Need to update the swapfile. */ + ml_set_crypt_key(curbuf, curbuf->b_p_key, old_value); } #endif diff --git a/src/proto/blowfish.pro b/src/proto/blowfish.pro index ba18176fbc..51e4fa9ec5 100644 --- a/src/proto/blowfish.pro +++ b/src/proto/blowfish.pro @@ -4,5 +4,7 @@ void bf_ofb_init __ARGS((char_u *iv, int iv_len)); void bf_crypt_encode __ARGS((char_u *from, size_t len, char_u *to)); void bf_crypt_decode __ARGS((char_u *ptr, long len)); void bf_crypt_init_keys __ARGS((char_u *passwd)); +void bf_crypt_save __ARGS((void)); +void bf_crypt_restore __ARGS((void)); int blowfish_self_test __ARGS((void)); /* vim: set ft=c : */ diff --git a/src/proto/memline.pro b/src/proto/memline.pro index 4d50671298..62a3ce6408 100644 --- a/src/proto/memline.pro +++ b/src/proto/memline.pro @@ -1,5 +1,6 @@ /* memline.c */ int ml_open __ARGS((buf_T *buf)); +void ml_set_crypt_key __ARGS((buf_T *buf, char_u *old_key, int old_cm)); void ml_setname __ARGS((buf_T *buf)); void ml_open_files __ARGS((void)); void ml_open_file __ARGS((buf_T *buf)); @@ -9,7 +10,7 @@ void ml_close_all __ARGS((int del_file)); void ml_close_notmod __ARGS((void)); void ml_timestamp __ARGS((buf_T *buf)); void ml_recover __ARGS((void)); -int recover_names __ARGS((char_u **fname, int list, int nr)); +int recover_names __ARGS((char_u *fname, int list, int nr, char_u **fname_out)); void ml_sync_all __ARGS((int check_file, int check_char)); void ml_preserve __ARGS((buf_T *buf, int message)); char_u *ml_get __ARGS((linenr_T lnum)); @@ -29,6 +30,8 @@ int resolve_symlink __ARGS((char_u *fname, char_u *buf)); char_u *makeswapname __ARGS((char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name)); char_u *get_file_in_dir __ARGS((char_u *fname, char_u *dname)); void ml_setflags __ARGS((buf_T *buf)); +char_u *ml_encrypt_data __ARGS((memfile_T *mfp, char_u *data, off_t offset, unsigned size)); +void ml_decrypt_data __ARGS((memfile_T *mfp, char_u *data, off_t offset, unsigned size)); long ml_find_line_or_offset __ARGS((buf_T *buf, linenr_T lnum, long *offp)); void goto_byte __ARGS((long cnt)); /* vim: set ft=c : */ diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro index 6b292bb81f..8d3397fc12 100644 --- a/src/proto/misc2.pro +++ b/src/proto/misc2.pro @@ -80,6 +80,8 @@ int illegal_slash __ARGS((char *name)); char_u *parse_shape_opt __ARGS((int what)); int get_shape_idx __ARGS((int mouse)); void update_mouseshape __ARGS((int shape_idx)); +void crypt_push_state __ARGS((void)); +void crypt_pop_state __ARGS((void)); void crypt_encode __ARGS((char_u *from, size_t len, char_u *to)); void crypt_decode __ARGS((char_u *ptr, long len)); void crypt_init_keys __ARGS((char_u *passwd)); diff --git a/src/sha256.c b/src/sha256.c index c24e8b8f83..3379620f38 100644 --- a/src/sha256.c +++ b/src/sha256.c @@ -402,7 +402,8 @@ get_some_time() } /* - * set header = sha2_seed(random_data); + * Fill "header[header_len]" with random_data. + * Also "salt[salt_len]" when "salt" is not NULL. */ void sha2_seed(header, header_len, salt, salt_len) @@ -429,8 +430,9 @@ sha2_seed(header, header_len, salt, salt_len) header[i] = sha256sum[i % sizeof(sha256sum)]; /* put remaining block into salt. */ - for (i = 0; i < salt_len; i++) - salt[i] = sha256sum[(i + header_len) % sizeof(sha256sum)]; + if (salt != NULL) + for (i = 0; i < salt_len; i++) + salt[i] = sha256sum[(i + header_len) % sizeof(sha256sum)]; } #endif /* FEAT_CRYPT */ diff --git a/src/structs.h b/src/structs.h index 4f72f998b3..a1c7e9d9a8 100644 --- a/src/structs.h +++ b/src/structs.h @@ -392,7 +392,7 @@ struct block_hdr bhdr_T *bh_prev; /* previous block_hdr in used list */ bhdr_T *bh_hash_next; /* next block_hdr in hash list */ bhdr_T *bh_hash_prev; /* previous block_hdr in hash list */ - blocknr_T bh_bnum; /* block number */ + blocknr_T bh_bnum; /* block number */ char_u *bh_data; /* pointer to memory (for used block) */ int bh_page_count; /* number of pages in this block */ @@ -491,12 +491,15 @@ typedef struct # endif } cmdmod_T; +typedef struct file_buffer buf_T; /* forward declaration */ + /* * Simplistic hashing scheme to quickly locate the blocks in the used list. * 64 blocks are found directly (64 * 4K = 256K, most files are smaller). */ #define MEMHASHSIZE 64 #define MEMHASH(nr) ((nr) & (MEMHASHSIZE - 1)) +#define MF_SEED_LEN 8 struct memfile { @@ -516,6 +519,16 @@ struct memfile blocknr_T mf_infile_count; /* number of pages in the file */ unsigned mf_page_size; /* number of bytes in a page */ int mf_dirty; /* TRUE if there are dirty blocks */ +#ifdef FEAT_CRYPT + buf_T *mf_buffer; /* bufer this memfile is for */ + char_u mf_seed[MF_SEED_LEN]; /* seed for encryption */ + + /* Values for key, method and seed used for reading data blocks when + * updating for a newly set key or method. Only when mf_old_key != NULL. */ + char_u *mf_old_key; + int mf_old_cm; + char_u mf_old_seed[MF_SEED_LEN]; +#endif }; /* @@ -1229,8 +1242,6 @@ typedef struct { * A buffer is new if the associated file has never been loaded yet. */ -typedef struct file_buffer buf_T; - struct file_buffer { memline_T b_ml; /* associated memline (also contains line diff --git a/src/testdir/test72.in b/src/testdir/test72.in index b6c6bfab3c..ada2654b26 100644 --- a/src/testdir/test72.in +++ b/src/testdir/test72.in @@ -6,7 +6,7 @@ STARTTEST :so small.vim :" :" Test 'undofile': first a simple one-line change. -:set nocp ul=100 undofile +:set nocp ul=100 undofile nomore :e! Xtestfile ggdGithis is one line:set ul=100 :s/one/ONE/ diff --git a/src/undo.c b/src/undo.c index 07412acc5c..45a6a23078 100644 --- a/src/undo.c +++ b/src/undo.c @@ -886,7 +886,10 @@ serialize_header(fp, buf, hash) len = (int)fwrite(header, (size_t)header_len, (size_t)1, fp); vim_free(header); if (len != 1) + { + crypt_pop_state(); return FAIL; + } } else #endif @@ -1240,6 +1243,9 @@ u_write_undo(name, forceit, buf, hash) struct stat st_old; struct stat st_new; #endif +#ifdef FEAT_CRYPT + int do_crypt = FALSE; +#endif if (name == NULL) { @@ -1397,6 +1403,10 @@ u_write_undo(name, forceit, buf, hash) */ if (serialize_header(fp, buf, hash) == FAIL) goto write_error; +#ifdef FEAT_CRYPT + if (*buf->b_p_key) + do_crypt = TRUE; +#endif /* * Iteratively serialize UHPs and their UEPs from the top down. @@ -1462,6 +1472,10 @@ write_error: #endif theend: +#ifdef FEAT_CRYPT + if (do_crypt) + crypt_pop_state(); +#endif if (file_name != name) vim_free(file_name); } @@ -1505,6 +1519,9 @@ u_read_undo(name, hash, orig_name) struct stat st_orig; struct stat st_undo; #endif +#ifdef FEAT_CRYPT + int do_decrypt = FALSE; +#endif if (name == NULL) { @@ -1572,6 +1589,7 @@ u_read_undo(name, hash, orig_name) EMSG2(_("E826: Undo file decryption failed: %s"), file_name); goto error; } + do_decrypt = TRUE; #else EMSG2(_("E827: Undo file is encrypted: %s"), file_name); goto error; @@ -1776,6 +1794,10 @@ error: } theend: +#ifdef FEAT_CRYPT + if (do_decrypt) + crypt_pop_state(); +#endif if (fp != NULL) fclose(fp); if (file_name != name) diff --git a/src/workshop.c b/src/workshop.c index cd98914bcf..334e6afff8 100644 --- a/src/workshop.c +++ b/src/workshop.c @@ -1304,13 +1304,15 @@ load_window( } else { +#ifdef FEAT_WINDOWS /* buf is in a window */ if (win != curwin) { win_enter(win, False); - /* wsdebug("load_window: window endter %s\n", + /* wsdebug("load_window: window enter %s\n", win->w_buffer->b_sfname); */ } +#endif if (lnum > 0 && win->w_cursor.lnum != lnum) { warp_to_pc(lnum); From bb2f88944812f8753e427724379c8aff89dd1b3c Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 21 Jun 2010 06:24:34 +0200 Subject: [PATCH 06/11] Command line completion for :ownsyntax. (Dominique Pelle) --HG-- branch : vim73 --- runtime/doc/todo.txt | 6 ------ src/ex_docmd.c | 5 +++++ src/ex_getln.c | 9 ++++++--- src/vim.h | 3 ++- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index 78ad818aec..2405457709 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1088,12 +1088,6 @@ Vim 7.3: - using NSIS 2.46: install on Windows 7 works, but no "Edit with Vim" menu. Use register_shell_extension()? (George Reilly, 2010 May 26) Ron's version: http://dev.ronware.org/p/vim/finfo?name=gvim.nsi -- Also crypt the swap file, each block separately: - - When changing the password or 'cryptmethod' need to read back with the - old password and write again with the new one. - Problem: when the file is not written, key differs between text file and - swap file! -- Patch for :ownsyntax completion (Dominique Pelle, 2010 Jun 20) - Patch for conceal feature and 'foldcolumn'. (Dominique Pelle, 2010 Jun 10, second patch) Also patch from Vince, 2010 Jun 15. And another June 16. diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 96a3a872f0..4bb3e7861b 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3803,6 +3803,11 @@ set_one_cmd_context(xp, buff) xp->xp_pattern = arg; break; + case CMD_ownsyntax: + xp->xp_context = EXPAND_FILETYPE; + xp->xp_pattern = arg; + break; + #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \ && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE)) case CMD_language: diff --git a/src/ex_getln.c b/src/ex_getln.c index e8b6f7c4d1..e6ed44a41e 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -4108,6 +4108,7 @@ addstar(fname, len, context) if (context == EXPAND_HELP || context == EXPAND_COLORS || context == EXPAND_COMPILER + || context == EXPAND_FILETYPE || (context == EXPAND_TAGS && fname[0] == '/')) retval = vim_strnsave(fname, len); else @@ -4489,6 +4490,8 @@ ExpandFromContext(xp, pat, num_file, file, options) return ExpandRTDir(pat, num_file, file, "colors"); if (xp->xp_context == EXPAND_COMPILER) return ExpandRTDir(pat, num_file, file, "compiler"); + if (xp->xp_context == EXPAND_FILETYPE) + return ExpandRTDir(pat, num_file, file, "syntax"); # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL) if (xp->xp_context == EXPAND_USER_LIST) return ExpandUserList(xp, num_file, file); @@ -4928,15 +4931,15 @@ ExpandUserList(xp, num_file, file) #endif /* - * Expand color scheme names: 'runtimepath'/colors/{pat}.vim - * or compiler names. + * Expand color scheme, compiler or filetype names: + * 'runtimepath'/{dirname}/{pat}.vim */ static int ExpandRTDir(pat, num_file, file, dirname) char_u *pat; int *num_file; char_u ***file; - char *dirname; /* "colors" or "compiler" */ + char *dirname; /* "colors", "compiler" or "syntax" */ { char_u *all; char_u *s; diff --git a/src/vim.h b/src/vim.h index b340792012..cb2bc7da1c 100644 --- a/src/vim.h +++ b/src/vim.h @@ -769,6 +769,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname); #define EXPAND_SIGN 34 #define EXPAND_PROFILE 35 #define EXPAND_BEHAVE 36 +#define EXPAND_FILETYPE 37 /* Values for exmode_active (0 is no exmode) */ #define EXMODE_NORMAL 1 @@ -1556,7 +1557,7 @@ typedef unsigned short disptick_T; /* display tick type */ /* * Well, you won't believe it, but some S/390 machines ("host", now also known - * as zServer) us 31 bit pointers. There are also some newer machines, that + * as zServer) use 31 bit pointers. There are also some newer machines, that * use 64 bit pointers. I don't know how to distinguish between 31 and 64 bit * machines, so the best way is to assume 31 bits whenever we detect OS/390 * Unix. From bf9b503224e8b26a12448098f85f277f88f8645d Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 22 Jun 2010 05:16:38 +0200 Subject: [PATCH 07/11] Couple of small fixes for conceal feature. (Dominique Pelle) --HG-- branch : vim73 --- runtime/doc/syntax.txt | 6 ++++-- runtime/doc/todo.txt | 5 +---- src/option.c | 15 ++++++++++++--- src/screen.c | 2 +- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index b1176a0570..418b64ca2f 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -3135,8 +3135,10 @@ These arguments can be used for all three commands: conceal *conceal* *:syn-conceal* When the "conceal" argument is given, the item is marked as concealable. -Whether or not it is actually concealed depends on the setting on the -'conceallevel' option. +Whether or not it is actually concealed depends on the value of the +'conceallevel' option. If 'modifiable' option is on, concealable items +in the current line are always displayed unconcealed to be able to edit +the line. concealends *:syn-concealends* diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index 2405457709..06be30b89f 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1088,11 +1088,8 @@ Vim 7.3: - using NSIS 2.46: install on Windows 7 works, but no "Edit with Vim" menu. Use register_shell_extension()? (George Reilly, 2010 May 26) Ron's version: http://dev.ronware.org/p/vim/finfo?name=gvim.nsi -- Patch for conceal feature and 'foldcolumn'. (Dominique Pelle, 2010 Jun 10, - second patch) - Also patch from Vince, 2010 Jun 15. And another June 16. +- Patch for conceal from Vince, 2010 Jun 15. And another June 16. However: more generic patch on the way. -- patch for conceal feature and 'modifiable'. (Dominique Pelle, 2010 Jun 9) - undofile: keep markers where the file was written/read, so that it's easy to go back to a saved version of the file: ":earlier 1f" (f for file)? Also add ":earlier 1d" (d for day). diff --git a/src/option.c b/src/option.c index face9fde99..fdca36f631 100644 --- a/src/option.c +++ b/src/option.c @@ -7334,12 +7334,21 @@ set_bool_option(opt_idx, varp, value, opt_flags) #endif } -#ifdef FEAT_TITLE - /* when 'modifiable' is changed, redraw the window title */ +#if defined(FEAT_TITLE) || defined(FEAT_CONCEAL) + /* when 'modifiable' is changed, redraw the window title and + * update current line for concealable items */ else if ((int *)varp == &curbuf->b_p_ma) { +# ifdef FEAT_TITLE redraw_titles(); +# endif +# ifdef FEAT_CONCEAL + if (curwin->w_p_conceal) + update_single_line(curwin, curwin->w_cursor.lnum); +# endif } +#endif +#ifdef FEAT_TITLE /* when 'endofline' is changed, redraw the window title */ else if ((int *)varp == &curbuf->b_p_eol) { @@ -8443,7 +8452,7 @@ findoption(arg) get_option_value(name, numval, stringval, opt_flags) char_u *name; long *numval; - char_u **stringval; /* NULL when only checking existance */ + char_u **stringval; /* NULL when only checking existence */ int opt_flags; { int opt_idx; diff --git a/src/screen.c b/src/screen.c index 1753330345..f2108be23f 100644 --- a/src/screen.c +++ b/src/screen.c @@ -595,7 +595,7 @@ update_single_line(wp, lnum) int j; if (lnum >= wp->w_topline && lnum < wp->w_botline - && foldedCount(wp, lnum, NULL) == 0) + && foldedCount(wp, lnum, &win_foldinfo) == 0) { # ifdef FEAT_GUI /* Remove the cursor before starting to do anything, because scrolling From 65d14fed40417ad0fc30bb87c33495a2f09b5d04 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 22 Jun 2010 06:07:12 +0200 Subject: [PATCH 08/11] Fixes for time in clipboard request. Also fix ownership. (David Fries) --HG-- branch : vim73 --- runtime/doc/todo.txt | 9 ++--- src/gui_gtk_x11.c | 9 ++++- src/os_unix.c | 1 + src/proto/ui.pro | 1 + src/ui.c | 91 +++++++++++++++++++++++++++++++++++++------- 5 files changed, 91 insertions(+), 20 deletions(-) diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index 06be30b89f..d9351d96fe 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1088,18 +1088,17 @@ Vim 7.3: - using NSIS 2.46: install on Windows 7 works, but no "Edit with Vim" menu. Use register_shell_extension()? (George Reilly, 2010 May 26) Ron's version: http://dev.ronware.org/p/vim/finfo?name=gvim.nsi -- Patch for conceal from Vince, 2010 Jun 15. And another June 16. - However: more generic patch on the way. +- Patch for conceal feature from Vince, 2010 June 16. + Needs some more testing. - undofile: keep markers where the file was written/read, so that it's easy to go back to a saved version of the file: ":earlier 1f" (f for file)? Also add ":earlier 1d" (d for day). Something like changenr() to see the "file saved" marker? Show "file saved" marker in :undolist - Function to get undo tree: undotree(). List of lists. Each entry is a +- Function to get undo tree: undotree(). List of lists. Each entry is a dictionary: {'nr': 2, 'time': 1234, 'saved': 1} -- Remove support for GTK 1? Patch by James Vega, Jun 11. +- Remove support for GTK 1? Patch by James Vega, Jun 11 (removes too much). Patches to include: -- Patch for X clibboard CurrentTime, (Fries, 2010 Jun 20) - Patch for Lisp support with ECL (Mikael Jansson, 2008 Oct 25) - Minor patches from Dominique Pelle, 2010 May 15 - Gvimext patch to support wide file names. (Szabolcs Horvat 2008 Sep 10) diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index 2db203b855..5cbe9a3c3a 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -88,6 +88,7 @@ extern void bonobo_dock_item_set_behavior(BonoboDockItem *dock_item, BonoboDockI #ifdef HAVE_X11_SUNKEYSYM_H # include +static guint32 clipboard_event_time = CurrentTime; #endif /* @@ -996,6 +997,7 @@ key_press_event(GtkWidget *widget UNUSED, guint state; char_u *s, *d; + clipboard_event_time = event->time; key_sym = event->keyval; state = event->state; #ifndef HAVE_GTK2 /* deprecated */ @@ -1258,6 +1260,7 @@ key_release_event(GtkWidget *widget UNUSED, GdkEventKey *event, gpointer data UNUSED) { + clipboard_event_time = event->time; /* * GTK+ 2 input methods may do fancy stuff on key release events too. * With the default IM for instance, you can enter any UCS code point @@ -1870,6 +1873,8 @@ button_press_event(GtkWidget *widget, int x, y; int_u vim_modifiers; + clipboard_event_time = event->time; + /* Make sure we have focus now we've been selected */ if (gtk_socket_id != 0 && !GTK_WIDGET_HAS_FOCUS(widget)) gtk_widget_grab_focus(widget); @@ -1989,6 +1994,8 @@ button_release_event(GtkWidget *widget UNUSED, int x, y; int_u vim_modifiers; + clipboard_event_time = event->time; + /* Remove any motion "machine gun" timers used for automatic further extension of allocation areas if outside of the applications window area .*/ @@ -6883,7 +6890,7 @@ clip_mch_own_selection(VimClipboard *cbd) int success; success = gtk_selection_owner_set(gui.drawarea, cbd->gtk_sel_atom, - (guint32)GDK_CURRENT_TIME); + clipboard_event_time); gui_mch_update(); return (success) ? OK : FAIL; } diff --git a/src/os_unix.c b/src/os_unix.c index 4cb1d4a7e7..365e965f81 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -6466,6 +6466,7 @@ setup_term_clip() return; x11_setup_atoms(xterm_dpy); + x11_setup_selection(xterm_Shell); if (x11_display == NULL) x11_display = xterm_dpy; diff --git a/src/proto/ui.pro b/src/proto/ui.pro index 87cee8b92c..b022baa55d 100644 --- a/src/proto/ui.pro +++ b/src/proto/ui.pro @@ -47,6 +47,7 @@ int check_col __ARGS((int col)); int check_row __ARGS((int row)); void open_app_context __ARGS((void)); void x11_setup_atoms __ARGS((Display *dpy)); +void x11_setup_selection __ARGS((Widget myShell)); void clip_x11_request_selection __ARGS((Widget myShell, Display *dpy, VimClipboard *cbd)); void clip_x11_lose_selection __ARGS((Widget myShell, VimClipboard *cbd)); int clip_x11_own_selection __ARGS((Widget myShell, VimClipboard *cbd)); diff --git a/src/ui.c b/src/ui.c index 9ca902be62..a925def2f2 100644 --- a/src/ui.c +++ b/src/ui.c @@ -467,11 +467,15 @@ clip_own_selection(cbd) * Also want to check somehow that we are reading from the keyboard rather * than a mapping etc. */ - if (!cbd->owned && cbd->available) - { - cbd->owned = (clip_gen_own_selection(cbd) == OK); #ifdef FEAT_X11 - if (cbd == &clip_star) + /* Always own the selection, we might have lost it without being + * notified. */ + if (cbd->available) + { + int was_owned = cbd->owned; + + cbd->owned = (clip_gen_own_selection(cbd) == OK); + if (!was_owned && cbd == &clip_star) { /* May have to show a different kind of highlighting for the * selected area. There is no specific redraw command for this, @@ -483,8 +487,12 @@ clip_own_selection(cbd) && hl_attr(HLF_V) != hl_attr(HLF_VNC)) redraw_curbuf_later(INVERTED_ALL); } -#endif } +#else + /* Only own the clibpard when we didn't own it yet. */ + if (!cbd->owned && cbd->available) + cbd->owned = (clip_gen_own_selection(cbd) == OK); +#endif } void @@ -1967,6 +1975,7 @@ static Atom vimenc_atom; /* Vim's extended selection format */ static Atom compound_text_atom; static Atom text_atom; static Atom targets_atom; +static Atom timestamp_atom; /* Used to get a timestamp */ void x11_setup_atoms(dpy) @@ -1978,15 +1987,70 @@ x11_setup_atoms(dpy) #endif compound_text_atom = XInternAtom(dpy, "COMPOUND_TEXT", False); text_atom = XInternAtom(dpy, "TEXT", False); - targets_atom = XInternAtom(dpy, "TARGETS", False); + targets_atom = XInternAtom(dpy, "TARGETS", False); clip_star.sel_atom = XA_PRIMARY; - clip_plus.sel_atom = XInternAtom(dpy, "CLIPBOARD", False); + clip_plus.sel_atom = XInternAtom(dpy, "CLIPBOARD", False); + timestamp_atom = XInternAtom(dpy, "TIMESTAMP", False); } /* * X Selection stuff, for cutting and pasting text to other windows. */ +static Boolean clip_x11_convert_selection_cb __ARGS((Widget, Atom *, Atom *, Atom *, XtPointer *, long_u *, int *)); + +static void clip_x11_lose_ownership_cb __ARGS((Widget, Atom *)); + +static void clip_x11_timestamp_cb __ARGS((Widget w, XtPointer n, XEvent *event, Boolean *cont)); + +/* + * Property callback to get a timestamp for XtOwnSelection. + */ + static void +clip_x11_timestamp_cb(w, n, event, cont) + Widget w; + XtPointer n UNUSED; + XEvent *event; + Boolean *cont UNUSED; +{ + Atom actual_type; + int format; + unsigned long nitems, bytes_after; + unsigned char *prop=NULL; + XPropertyEvent *xproperty=&event->xproperty; + + /* Must be a property notify, state can't be Delete (True), has to be + * one of the supported selection types. */ + if (event->type != PropertyNotify || xproperty->state + || (xproperty->atom != clip_star.sel_atom + && xproperty->atom != clip_plus.sel_atom)) + return; + + if (XGetWindowProperty(xproperty->display, xproperty->window, + xproperty->atom, 0, 0, False, timestamp_atom, &actual_type, &format, + &nitems, &bytes_after, &prop)) + return; + + if (prop) + XFree(prop); + + /* Make sure the property type is "TIMESTAMP" and it's 32 bits. */ + if (actual_type != timestamp_atom || format != 32) + return; + + /* Get the selection, using the event timestamp. */ + XtOwnSelection(w, xproperty->atom, xproperty->time, + clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb, NULL); +} + + void +x11_setup_selection(w) + Widget w; +{ + XtAddEventHandler(w, PropertyChangeMask, False, + /*(XtEventHandler)*/clip_x11_timestamp_cb, (XtPointer)NULL); +} + static void clip_x11_request_selection_cb __ARGS((Widget, XtPointer, Atom *, Atom *, XtPointer, long_u *, int *)); static void @@ -2186,8 +2250,6 @@ clip_x11_request_selection(myShell, dpy, cbd) yank_cut_buffer0(dpy, cbd); } -static Boolean clip_x11_convert_selection_cb __ARGS((Widget, Atom *, Atom *, Atom *, XtPointer *, long_u *, int *)); - static Boolean clip_x11_convert_selection_cb(w, sel_atom, target, type, value, length, format) Widget w UNUSED; @@ -2315,8 +2377,6 @@ clip_x11_convert_selection_cb(w, sel_atom, target, type, value, length, format) return True; } -static void clip_x11_lose_ownership_cb __ARGS((Widget, Atom *)); - static void clip_x11_lose_ownership_cb(w, sel_atom) Widget w UNUSED; @@ -2341,10 +2401,13 @@ clip_x11_own_selection(myShell, cbd) Widget myShell; VimClipboard *cbd; { - if (XtOwnSelection(myShell, cbd->sel_atom, CurrentTime, - clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb, - NULL) == False) + /* Get the time by a zero-length append, clip_x11_timestamp_cb will be + * called with the current timestamp. */ + if (!XChangeProperty(XtDisplay(myShell), XtWindow(myShell), cbd->sel_atom, + timestamp_atom, 32, PropModeAppend, NULL, 0)) return FAIL; + /* Flush is required in a terminal as nothing else is doing it. */ + XFlush(XtDisplay(myShell)); return OK; } From ab473c0c5a725b7a9078f1885d8342cba894bfe6 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 22 Jun 2010 06:28:58 +0200 Subject: [PATCH 09/11] Fix compiler warnings for shadowed variables. Make 'conceal' a long instead of int. --HG-- branch : vim73 --- src/blowfish.c | 12 ++++++------ src/eval.c | 14 +++++++------- src/fold.c | 14 +++++++------- src/main.c | 8 ++++---- src/memline.c | 8 ++++---- src/netbeans.c | 12 ++++++------ src/option.c | 2 +- src/structs.h | 2 +- src/undo.c | 14 +++++++------- 9 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/blowfish.c b/src/blowfish.c index c8e68d2244..78e56991bc 100644 --- a/src/blowfish.c +++ b/src/blowfish.c @@ -39,7 +39,7 @@ typedef union { static void bf_e_block __ARGS((UINT32_T *p_xl, UINT32_T *p_xr)); static void bf_e_cblock __ARGS((char_u *block)); -static int bf_check_tables __ARGS((UINT32_T ipa[18], UINT32_T sbi[4][256], UINT32_T val)); +static int bf_check_tables __ARGS((UINT32_T a_ipa[18], UINT32_T a_sbi[4][256], UINT32_T val)); static int bf_self_test __ARGS((void)); /* Blowfish code */ @@ -469,19 +469,19 @@ bf_key_init(password, salt, salt_len) * BF Self test for corrupted tables or instructions */ static int -bf_check_tables(ipa, sbi, val) - UINT32_T ipa[18]; - UINT32_T sbi[4][256]; +bf_check_tables(a_ipa, a_sbi, val) + UINT32_T a_ipa[18]; + UINT32_T a_sbi[4][256]; UINT32_T val; { int i, j; UINT32_T c = 0; for (i = 0; i < 18; i++) - c ^= ipa[i]; + c ^= a_ipa[i]; for (i = 0; i < 4; i++) for (j = 0; j < 256; j++) - c ^= sbi[i][j]; + c ^= a_sbi[i][j]; return c == val; } diff --git a/src/eval.c b/src/eval.c index 10732ccade..7457677c1b 100644 --- a/src/eval.c +++ b/src/eval.c @@ -463,7 +463,7 @@ static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); static int find_internal_func __ARGS((char_u *name)); static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); -static int call_func __ARGS((char_u *func_name, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); +static int call_func __ARGS((char_u *funcname, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); static void emsg_funcname __ARGS((char *ermsg, char_u *name)); static int non_zero_arg __ARGS((typval_T *argvars)); @@ -8074,9 +8074,9 @@ get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, * Also returns OK when an error was encountered while executing the function. */ static int -call_func(func_name, len, rettv, argcount, argvars, firstline, lastline, +call_func(funcname, len, rettv, argcount, argvars, firstline, lastline, doesrange, evaluate, selfdict) - char_u *func_name; /* name of the function */ + char_u *funcname; /* name of the function */ int len; /* length of "name" */ typval_T *rettv; /* return value goes here */ int argcount; /* number of "argvars" */ @@ -8107,7 +8107,7 @@ call_func(func_name, len, rettv, argcount, argvars, firstline, lastline, /* Make a copy of the name, if it comes from a funcref variable it could * be changed or deleted in the called function. */ - name = vim_strnsave(func_name, len); + name = vim_strnsave(funcname, len); if (name == NULL) return ret; @@ -10114,7 +10114,7 @@ filter_map(argvars, rettv, map) int todo; char_u *ermsg = map ? (char_u *)"map()" : (char_u *)"filter()"; int save_did_emsg; - int index = 0; + int idx = 0; if (argvars[0].v_type == VAR_LIST) { @@ -10184,13 +10184,13 @@ filter_map(argvars, rettv, map) if (tv_check_lock(li->li_tv.v_lock, ermsg)) break; nli = li->li_next; - vimvars[VV_KEY].vv_nr = index; + vimvars[VV_KEY].vv_nr = idx; if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL || did_emsg) break; if (!map && rem) listitem_remove(l, li); - ++index; + ++idx; } } diff --git a/src/fold.c b/src/fold.c index c88e8f793b..800db61ba6 100644 --- a/src/fold.c +++ b/src/fold.c @@ -2265,24 +2265,24 @@ foldUpdateIEMS(wp, top, bot) if (foldlevelSyntax == getlevel) { garray_T *gap = &wp->w_folds; - fold_T *fp = NULL; + fold_T *fpn = NULL; int current_fdl = 0; linenr_T fold_start_lnum = 0; linenr_T lnum_rel = fline.lnum; while (current_fdl < fline.lvl) { - if (!foldFind(gap, lnum_rel, &fp)) + if (!foldFind(gap, lnum_rel, &fpn)) break; ++current_fdl; - fold_start_lnum += fp->fd_top; - gap = &fp->fd_nested; - lnum_rel -= fp->fd_top; + fold_start_lnum += fpn->fd_top; + gap = &fpn->fd_nested; + lnum_rel -= fpn->fd_top; } - if (fp != NULL && current_fdl == fline.lvl) + if (fpn != NULL && current_fdl == fline.lvl) { - linenr_T fold_end_lnum = fold_start_lnum + fp->fd_len; + linenr_T fold_end_lnum = fold_start_lnum + fpn->fd_len; if (fold_end_lnum > bot) bot = fold_end_lnum; diff --git a/src/main.c b/src/main.c index 0f29255864..1b2e6ee694 100644 --- a/src/main.c +++ b/src/main.c @@ -3342,8 +3342,8 @@ time_diff(then, now) } void -time_msg(msg, tv_start) - char *msg; +time_msg(mesg, tv_start) + char *mesg; void *tv_start; /* only for do_source: start time; actually (struct timeval *) */ { @@ -3352,7 +3352,7 @@ time_msg(msg, tv_start) if (time_fd != NULL) { - if (strstr(msg, "STARTING") != NULL) + if (strstr(mesg, "STARTING") != NULL) { gettimeofday(&start, NULL); prev_timeval = start; @@ -3370,7 +3370,7 @@ time_msg(msg, tv_start) fprintf(time_fd, " "); time_diff(&prev_timeval, &now); prev_timeval = now; - fprintf(time_fd, ": %s\n", msg); + fprintf(time_fd, ": %s\n", mesg); } } diff --git a/src/memline.c b/src/memline.c index 75800b15bd..c5b22e0924 100644 --- a/src/memline.c +++ b/src/memline.c @@ -1335,16 +1335,16 @@ ml_recover() b0_ff = (b0p->b0_flags & B0_FF_MASK); if (b0p->b0_flags & B0_HAS_FENC) { - int size = B0_FNAME_SIZE_NOCRYPT; + int fnsize = B0_FNAME_SIZE_NOCRYPT; #ifdef FEAT_CRYPT /* Use the same size as in add_b0_fenc(). */ if (b0p->b0_id[1] != BLOCK0_ID1) - size = B0_FNAME_SIZE_CRYPT; + fnsize = B0_FNAME_SIZE_CRYPT; #endif - for (p = b0p->b0_fname + size; p > b0p->b0_fname && p[-1] != NUL; --p) + for (p = b0p->b0_fname + fnsize; p > b0p->b0_fname && p[-1] != NUL; --p) ; - b0_fenc = vim_strnsave(p, (int)(b0p->b0_fname + size - p)); + b0_fenc = vim_strnsave(p, (int)(b0p->b0_fname + fnsize - p)); } mf_put(mfp, hp, FALSE, FALSE); /* release block 0 */ diff --git a/src/netbeans.c b/src/netbeans.c index ff191d7d2a..e674fd8222 100644 --- a/src/netbeans.c +++ b/src/netbeans.c @@ -195,7 +195,7 @@ netbeans_close(void) #define NB_DEF_PASS "changeme" static int -netbeans_connect(char *params, int abort) +netbeans_connect(char *params, int doabort) { #ifdef INET_SOCKETS struct sockaddr_in server; @@ -366,7 +366,7 @@ netbeans_connect(char *params, int abort) { nbdebug(("retrying...\n")); sleep(5); - if (!abort) + if (!doabort) { ui_breakcheck(); if (got_int) @@ -388,7 +388,7 @@ netbeans_connect(char *params, int abort) /* Get here when the server can't be found. */ nbdebug(("Cannot connect to Netbeans #2\n")); PERROR(_("Cannot connect to Netbeans #2")); - if (abort) + if (doabort) getout(1); goto theend; } @@ -398,7 +398,7 @@ netbeans_connect(char *params, int abort) { nbdebug(("Cannot connect to Netbeans\n")); PERROR(_("Cannot connect to Netbeans")); - if (abort) + if (doabort) getout(1); goto theend; } @@ -2967,7 +2967,7 @@ netbeans_gui_register(void) * Tell netbeans that the window was opened, ready for commands. */ void -netbeans_open(char *params, int abort) +netbeans_open(char *params, int doabort) { char *cmd = "0:startupDone=0\n"; @@ -2977,7 +2977,7 @@ netbeans_open(char *params, int abort) return; } - if (netbeans_connect(params, abort) != OK) + if (netbeans_connect(params, doabort) != OK) return; #ifdef FEAT_GUI netbeans_gui_register(); diff --git a/src/option.c b/src/option.c index fdca36f631..ae3c539123 100644 --- a/src/option.c +++ b/src/option.c @@ -8133,7 +8133,7 @@ set_num_option(opt_idx, varp, value, errbuf, errbuflen, opt_flags) ml_open_files(); } #ifdef FEAT_CONCEAL - else if (pp == (long *)&curwin->w_p_conceal) + else if (pp == &curwin->w_p_conceal) { if (curwin->w_p_conceal < 0) { diff --git a/src/structs.h b/src/structs.h index a1c7e9d9a8..d792c7804e 100644 --- a/src/structs.h +++ b/src/structs.h @@ -214,7 +214,7 @@ typedef struct int wo_wrap; #define w_p_wrap w_onebuf_opt.wo_wrap /* 'wrap' */ #ifdef FEAT_CONCEAL - int wo_conceal; /* 'conceal' */ + long wo_conceal; /* 'conceal' */ # define w_p_conceal w_onebuf_opt.wo_conceal #endif #ifdef FEAT_CURSORBIND diff --git a/src/undo.c b/src/undo.c index 45a6a23078..b173781535 100644 --- a/src/undo.c +++ b/src/undo.c @@ -100,7 +100,7 @@ static void u_freebranch __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp) static void u_freeentries __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp)); static void u_freeentry __ARGS((u_entry_T *, long)); #ifdef FEAT_PERSISTENT_UNDO -static void corruption_error __ARGS((char *msg, char_u *file_name)); +static void corruption_error __ARGS((char *mesg, char_u *file_name)); static void u_free_uhp __ARGS((u_header_T *uhp)); static size_t fwrite_crypt __ARGS((buf_T *buf UNUSED, char_u *ptr, size_t len, FILE *fp)); static char_u *read_string_decrypt __ARGS((buf_T *buf UNUSED, FILE *fd, int len)); @@ -779,11 +779,11 @@ u_get_undo_file_name(buf_ffname, reading) } static void -corruption_error(msg, file_name) - char *msg; +corruption_error(mesg, file_name) + char *mesg; char_u *file_name; { - EMSG3(_("E825: Corrupted undo file (%s): %s"), msg, file_name); + EMSG3(_("E825: Corrupted undo file (%s): %s"), mesg, file_name); } static void @@ -1313,13 +1313,13 @@ u_write_undo(name, forceit, buf, hash) } else { - char_u buf[UF_START_MAGIC_LEN]; + char_u mbuf[UF_START_MAGIC_LEN]; int len; - len = vim_read(fd, buf, UF_START_MAGIC_LEN); + len = vim_read(fd, mbuf, UF_START_MAGIC_LEN); close(fd); if (len < UF_START_MAGIC_LEN - || memcmp(buf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0) + || memcmp(mbuf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0) { if (name != NULL || p_verbose > 0) { From f614d1b5dd7b47787d1eaa4b9e49fc3bb2fed755 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 24 Jun 2010 05:20:13 +0200 Subject: [PATCH 10/11] Fix compiler warning. --HG-- branch : vim73 --- src/memline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/memline.c b/src/memline.c index c5b22e0924..06b30cf728 100644 --- a/src/memline.c +++ b/src/memline.c @@ -4923,7 +4923,7 @@ ml_crypt_prepare(mfp, offset, reading) /* Using blowfish, add salt and seed. We use the byte offset of the * block for the salt. */ vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset); - bf_key_init(key, salt, STRLEN(salt)); + bf_key_init(key, salt, (int)STRLEN(salt)); bf_ofb_init(seed, MF_SEED_LEN); } } From fc7edcfd4fa8eaf601a1fea6b0fb847dc2ab7b86 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 24 Jun 2010 05:39:03 +0200 Subject: [PATCH 11/11] Fix a memory leak in encryption. (Dominique Pelle) --HG-- branch : vim73 --- src/memline.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/memline.c b/src/memline.c index 06b30cf728..aa901a9144 100644 --- a/src/memline.c +++ b/src/memline.c @@ -508,6 +508,7 @@ ml_set_crypt_key(buf, old_key, old_cm) idx = 0; /* start with first index in block 1 */ error = 0; buf->b_ml.ml_stack_top = 0; + vim_free(buf->b_ml.ml_stack); buf->b_ml.ml_stack = NULL; buf->b_ml.ml_stack_size = 0; /* no stack yet */ @@ -744,8 +745,8 @@ ml_open_file(buf) { if (*dirp == NUL) break; - /* There is a small chance that between chosing the swap file name and - * creating it, another Vim creates the file. In that case the + /* There is a small chance that between choosing the swap file name + * and creating it, another Vim creates the file. In that case the * creation will fail and we will use another directory. */ fname = findswapname(buf, &dirp, NULL); /* allocates fname */ if (fname == NULL) @@ -1239,7 +1240,7 @@ ml_recover() MSG_PUTS_ATTR(_(" cannot be used on this computer.\n"), attr | MSG_HIST); MSG_PUTS_ATTR(_("The file was created on "), attr | MSG_HIST); - /* avoid going past the end of a currupted hostname */ + /* avoid going past the end of a corrupted hostname */ b0p->b0_fname[0] = NUL; MSG_PUTS_ATTR(b0p->b0_hname, attr | MSG_HIST); MSG_PUTS_ATTR(_(",\nor the file has been damaged."), attr | MSG_HIST);