Mercurial > vim
comparison src/fileio.c @ 32503:5d07e7e9580f v9.0.1583
patch 9.0.1583: get E304 when using 'cryptmethod' "xchacha20v2"
Commit: https://github.com/vim/vim/commit/3a2a60ce4a8e73594bca16814672fcc243d093ac
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat May 27 18:02:55 2023 +0100
patch 9.0.1583: get E304 when using 'cryptmethod' "xchacha20v2"
Problem: Get E304 when using 'cryptmethod' "xchacha20v2". (Steve Mynott)
Solution: Add 4th crypt method to block zero ID check. Avoid syncing a swap
file before reading the file. (closes #12433)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 27 May 2023 19:15:04 +0200 |
parents | 3d4e28569a6d |
children | a4b5a6a95005 |
comparison
equal
deleted
inserted
replaced
32502:b1bb97d879b6 | 32503:5d07e7e9580f |
---|---|
123 linenr_T lines_to_skip, | 123 linenr_T lines_to_skip, |
124 linenr_T lines_to_read, | 124 linenr_T lines_to_read, |
125 exarg_T *eap, // can be NULL! | 125 exarg_T *eap, // can be NULL! |
126 int flags) | 126 int flags) |
127 { | 127 { |
128 int retval = FAIL; // jump to "theend" instead of returning | |
128 int fd = 0; | 129 int fd = 0; |
129 int newfile = (flags & READ_NEW); | 130 int newfile = (flags & READ_NEW); |
130 int check_readonly; | 131 int check_readonly; |
131 int filtering = (flags & READ_FILTER); | 132 int filtering = (flags & READ_FILTER); |
132 int read_stdin = (flags & READ_STDIN); | 133 int read_stdin = (flags & READ_STDIN); |
237 && fname != NULL | 238 && fname != NULL |
238 && vim_strchr(p_cpo, CPO_FNAMER) != NULL | 239 && vim_strchr(p_cpo, CPO_FNAMER) != NULL |
239 && !(flags & READ_DUMMY)) | 240 && !(flags & READ_DUMMY)) |
240 { | 241 { |
241 if (set_rw_fname(fname, sfname) == FAIL) | 242 if (set_rw_fname(fname, sfname) == FAIL) |
242 return FAIL; | 243 goto theend; |
243 } | 244 } |
244 | 245 |
245 // Remember the initial values of curbuf, curbuf->b_ffname and | 246 // Remember the initial values of curbuf, curbuf->b_ffname and |
246 // curbuf->b_fname to detect whether they are altered as a result of | 247 // curbuf->b_fname to detect whether they are altered as a result of |
247 // executing nasty autocommands. Also check if "fname" and "sfname" | 248 // executing nasty autocommands. Also check if "fname" and "sfname" |
287 if (newfile) | 288 if (newfile) |
288 { | 289 { |
289 if (apply_autocmds_exarg(EVENT_BUFREADCMD, NULL, sfname, | 290 if (apply_autocmds_exarg(EVENT_BUFREADCMD, NULL, sfname, |
290 FALSE, curbuf, eap)) | 291 FALSE, curbuf, eap)) |
291 { | 292 { |
292 int status = OK; | 293 retval = OK; |
293 #ifdef FEAT_EVAL | 294 #ifdef FEAT_EVAL |
294 if (aborting()) | 295 if (aborting()) |
295 status = FAIL; | 296 retval = FAIL; |
296 #endif | 297 #endif |
297 // The BufReadCmd code usually uses ":read" to get the text and | 298 // The BufReadCmd code usually uses ":read" to get the text and |
298 // perhaps ":file" to change the buffer name. But we should | 299 // perhaps ":file" to change the buffer name. But we should |
299 // consider this to work like ":edit", thus reset the | 300 // consider this to work like ":edit", thus reset the |
300 // BF_NOTEDITED flag. Then ":write" will work to overwrite the | 301 // BF_NOTEDITED flag. Then ":write" will work to overwrite the |
301 // same file. | 302 // same file. |
302 if (status == OK) | 303 if (retval == OK) |
303 curbuf->b_flags &= ~BF_NOTEDITED; | 304 curbuf->b_flags &= ~BF_NOTEDITED; |
304 return status; | 305 goto theend; |
305 } | 306 } |
306 } | 307 } |
307 else if (apply_autocmds_exarg(EVENT_FILEREADCMD, sfname, sfname, | 308 else if (apply_autocmds_exarg(EVENT_FILEREADCMD, sfname, sfname, |
308 FALSE, NULL, eap)) | 309 FALSE, NULL, eap)) |
310 { | |
309 #ifdef FEAT_EVAL | 311 #ifdef FEAT_EVAL |
310 return aborting() ? FAIL : OK; | 312 retval = aborting() ? FAIL : OK; |
311 #else | 313 #else |
312 return OK; | 314 retval = OK; |
313 #endif | 315 #endif |
316 goto theend; | |
317 } | |
314 | 318 |
315 curbuf->b_op_start = orig_start; | 319 curbuf->b_op_start = orig_start; |
316 | 320 |
317 if (flags & READ_NOFILE) | 321 if (flags & READ_NOFILE) |
322 { | |
318 // Return NOTDONE instead of FAIL so that BufEnter can be triggered | 323 // Return NOTDONE instead of FAIL so that BufEnter can be triggered |
319 // and other operations don't fail. | 324 // and other operations don't fail. |
320 return NOTDONE; | 325 retval = NOTDONE; |
326 goto theend; | |
327 } | |
321 } | 328 } |
322 | 329 |
323 if ((shortmess(SHM_OVER) || curbuf->b_help) && p_verbose == 0) | 330 if ((shortmess(SHM_OVER) || curbuf->b_help) && p_verbose == 0) |
324 msg_scroll = FALSE; // overwrite previous file message | 331 msg_scroll = FALSE; // overwrite previous file message |
325 else | 332 else |
333 if (namelen >= MAXPATHL) | 340 if (namelen >= MAXPATHL) |
334 { | 341 { |
335 filemess(curbuf, fname, (char_u *)_("Illegal file name"), 0); | 342 filemess(curbuf, fname, (char_u *)_("Illegal file name"), 0); |
336 msg_end(); | 343 msg_end(); |
337 msg_scroll = msg_save; | 344 msg_scroll = msg_save; |
338 return FAIL; | 345 goto theend; |
339 } | 346 } |
340 | 347 |
341 // If the name ends in a path separator, we can't open it. Check here, | 348 // If the name ends in a path separator, we can't open it. Check here, |
342 // because reading the file may actually work, but then creating the | 349 // because reading the file may actually work, but then creating the |
343 // swap file may destroy it! Reported on MS-DOS and Win 95. | 350 // swap file may destroy it! Reported on MS-DOS and Win 95. |
344 if (after_pathsep(fname, fname + namelen)) | 351 if (after_pathsep(fname, fname + namelen)) |
345 { | 352 { |
346 filemess(curbuf, fname, (char_u *)_(msg_is_a_directory), 0); | 353 filemess(curbuf, fname, (char_u *)_(msg_is_a_directory), 0); |
347 msg_end(); | 354 msg_end(); |
348 msg_scroll = msg_save; | 355 msg_scroll = msg_save; |
349 return NOTDONE; | 356 retval = NOTDONE; |
357 goto theend; | |
350 } | 358 } |
351 } | 359 } |
352 | 360 |
353 if (!read_stdin && !read_buffer && !read_fifo) | 361 if (!read_stdin && !read_buffer && !read_fifo) |
354 { | 362 { |
365 && !(S_ISCHR(perm) && is_dev_fd_file(fname)) | 373 && !(S_ISCHR(perm) && is_dev_fd_file(fname)) |
366 // ... or a character special file named /dev/fd/<n> | 374 // ... or a character special file named /dev/fd/<n> |
367 # endif | 375 # endif |
368 ) | 376 ) |
369 { | 377 { |
370 int retval = FAIL; | |
371 | |
372 if (S_ISDIR(perm)) | 378 if (S_ISDIR(perm)) |
373 { | 379 { |
374 filemess(curbuf, fname, (char_u *)_(msg_is_a_directory), 0); | 380 filemess(curbuf, fname, (char_u *)_(msg_is_a_directory), 0); |
375 retval = NOTDONE; | 381 retval = NOTDONE; |
376 } | 382 } |
377 else | 383 else |
378 filemess(curbuf, fname, (char_u *)_("is not a file"), 0); | 384 filemess(curbuf, fname, (char_u *)_("is not a file"), 0); |
379 msg_end(); | 385 msg_end(); |
380 msg_scroll = msg_save; | 386 msg_scroll = msg_save; |
381 return retval; | 387 goto theend; |
382 } | 388 } |
383 #endif | 389 #endif |
384 #if defined(MSWIN) | 390 #if defined(MSWIN) |
385 /* | 391 /* |
386 * MS-Windows allows opening a device, but we will probably get stuck | 392 * MS-Windows allows opening a device, but we will probably get stuck |
389 if (!p_odev && mch_nodetype(fname) == NODE_WRITABLE) | 395 if (!p_odev && mch_nodetype(fname) == NODE_WRITABLE) |
390 { | 396 { |
391 filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option)"), 0); | 397 filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option)"), 0); |
392 msg_end(); | 398 msg_end(); |
393 msg_scroll = msg_save; | 399 msg_scroll = msg_save; |
394 return FAIL; | 400 goto theend; |
395 } | 401 } |
396 #endif | 402 #endif |
397 } | 403 } |
398 | 404 |
399 // Set default or forced 'fileformat' and 'binary'. | 405 // Set default or forced 'fileformat' and 'binary'. |
532 && (old_b_ffname != curbuf->b_ffname)) | 538 && (old_b_ffname != curbuf->b_ffname)) |
533 || (using_b_fname | 539 || (using_b_fname |
534 && (old_b_fname != curbuf->b_fname))) | 540 && (old_b_fname != curbuf->b_fname))) |
535 { | 541 { |
536 emsg(_(e_autocommands_changed_buffer_or_buffer_name)); | 542 emsg(_(e_autocommands_changed_buffer_or_buffer_name)); |
537 return FAIL; | 543 goto theend; |
538 } | 544 } |
539 } | 545 } |
540 if (dir_of_file_exists(fname)) | 546 if (dir_of_file_exists(fname)) |
541 filemess(curbuf, sfname, | 547 filemess(curbuf, sfname, |
542 (char_u *)new_file_message(), 0); | 548 (char_u *)new_file_message(), 0); |
555 FALSE, curbuf, eap); | 561 FALSE, curbuf, eap); |
556 // remember the current fileformat | 562 // remember the current fileformat |
557 save_file_ff(curbuf); | 563 save_file_ff(curbuf); |
558 | 564 |
559 #if defined(FEAT_EVAL) | 565 #if defined(FEAT_EVAL) |
560 if (aborting()) // autocmds may abort script processing | 566 if (!aborting()) // autocmds may abort script processing |
561 return FAIL; | 567 #endif |
562 #endif | 568 retval = OK; // a new file is not an error |
563 return OK; // a new file is not an error | 569 goto theend; |
564 } | 570 } |
565 else | 571 else |
566 { | 572 { |
567 filemess(curbuf, sfname, (char_u *)( | 573 filemess(curbuf, sfname, (char_u *)( |
568 # ifdef EFBIG | 574 # ifdef EFBIG |
574 _("[Permission Denied]")), 0); | 580 _("[Permission Denied]")), 0); |
575 curbuf->b_p_ro = TRUE; // must use "w!" now | 581 curbuf->b_p_ro = TRUE; // must use "w!" now |
576 } | 582 } |
577 } | 583 } |
578 | 584 |
579 return FAIL; | 585 goto theend; |
580 } | 586 } |
581 | 587 |
582 /* | 588 /* |
583 * Only set the 'ro' flag for readonly files the first time they are | 589 * Only set the 'ro' flag for readonly files the first time they are |
584 * loaded. Help files always get readonly mode | 590 * loaded. Help files always get readonly mode |
612 || (using_b_fname && (old_b_fname != curbuf->b_fname)))) | 618 || (using_b_fname && (old_b_fname != curbuf->b_fname)))) |
613 { | 619 { |
614 emsg(_(e_autocommands_changed_buffer_or_buffer_name)); | 620 emsg(_(e_autocommands_changed_buffer_or_buffer_name)); |
615 if (!read_buffer) | 621 if (!read_buffer) |
616 close(fd); | 622 close(fd); |
617 return FAIL; | 623 goto theend; |
618 } | 624 } |
619 #ifdef UNIX | 625 #ifdef UNIX |
620 // Set swap file protection bits after creating it. | 626 // Set swap file protection bits after creating it. |
621 if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL | 627 if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL |
622 && curbuf->b_ml.ml_mfp->mf_fname != NULL) | 628 && curbuf->b_ml.ml_mfp->mf_fname != NULL) |
652 // If "Quit" selected at ATTENTION dialog, don't load the file | 658 // If "Quit" selected at ATTENTION dialog, don't load the file |
653 if (swap_exists_action == SEA_QUIT) | 659 if (swap_exists_action == SEA_QUIT) |
654 { | 660 { |
655 if (!read_buffer && !read_stdin) | 661 if (!read_buffer && !read_stdin) |
656 close(fd); | 662 close(fd); |
657 return FAIL; | 663 goto theend; |
658 } | 664 } |
659 | 665 |
660 ++no_wait_return; // don't wait for return yet | 666 ++no_wait_return; // don't wait for return yet |
661 | 667 |
662 /* | 668 /* |
713 if (aborting()) // autocmds may abort script processing | 719 if (aborting()) // autocmds may abort script processing |
714 { | 720 { |
715 --no_wait_return; | 721 --no_wait_return; |
716 msg_scroll = msg_save; | 722 msg_scroll = msg_save; |
717 curbuf->b_p_ro = TRUE; // must use "w!" now | 723 curbuf->b_p_ro = TRUE; // must use "w!" now |
718 return FAIL; | 724 goto theend; |
719 } | 725 } |
720 #endif | 726 #endif |
721 /* | 727 /* |
722 * Don't allow the autocommands to change the current buffer. | 728 * Don't allow the autocommands to change the current buffer. |
723 * Try to re-open the file. | 729 * Try to re-open the file. |
735 if (fd < 0) | 741 if (fd < 0) |
736 emsg(_(e_readpre_autocommands_made_file_unreadable)); | 742 emsg(_(e_readpre_autocommands_made_file_unreadable)); |
737 else | 743 else |
738 emsg(_(e_readpre_autocommands_must_not_change_current_buffer)); | 744 emsg(_(e_readpre_autocommands_must_not_change_current_buffer)); |
739 curbuf->b_p_ro = TRUE; // must use "w!" now | 745 curbuf->b_p_ro = TRUE; // must use "w!" now |
740 return FAIL; | 746 goto theend; |
741 } | 747 } |
742 } | 748 } |
743 | 749 |
744 // Autocommands may add lines to the file, need to check if it is empty | 750 // Autocommands may add lines to the file, need to check if it is empty |
745 wasempty = (curbuf->b_ml.ml_flags & ML_EMPTY); | 751 wasempty = (curbuf->b_ml.ml_flags & ML_EMPTY); |
2459 } | 2465 } |
2460 msg_scroll = msg_save; | 2466 msg_scroll = msg_save; |
2461 #ifdef FEAT_VIMINFO | 2467 #ifdef FEAT_VIMINFO |
2462 check_marks_read(); | 2468 check_marks_read(); |
2463 #endif | 2469 #endif |
2464 return OK; // an interrupt isn't really an error | 2470 retval = OK; // an interrupt isn't really an error |
2471 goto theend; | |
2465 } | 2472 } |
2466 | 2473 |
2467 if (!filtering && !(flags & READ_DUMMY)) | 2474 if (!filtering && !(flags & READ_DUMMY)) |
2468 { | 2475 { |
2469 msg_add_fname(curbuf, sfname); // fname in IObuff with quotes | 2476 msg_add_fname(curbuf, sfname); // fname in IObuff with quotes |
2694 FALSE, NULL, eap); | 2701 FALSE, NULL, eap); |
2695 if (msg_scrolled == n) | 2702 if (msg_scrolled == n) |
2696 msg_scroll = m; | 2703 msg_scroll = m; |
2697 # ifdef FEAT_EVAL | 2704 # ifdef FEAT_EVAL |
2698 if (aborting()) // autocmds may abort script processing | 2705 if (aborting()) // autocmds may abort script processing |
2699 return FAIL; | 2706 goto theend; |
2700 # endif | 2707 # endif |
2701 } | 2708 } |
2702 | 2709 |
2703 if (recoverymode && error) | 2710 if (!(recoverymode && error)) |
2704 return FAIL; | 2711 retval = OK; |
2705 return OK; | 2712 |
2713 theend: | |
2714 if (curbuf->b_ml.ml_mfp != NULL | |
2715 && curbuf->b_ml.ml_mfp->mf_dirty == MF_DIRTY_YES_NOSYNC) | |
2716 // OK to sync the swap file now | |
2717 curbuf->b_ml.ml_mfp->mf_dirty = MF_DIRTY_YES; | |
2718 | |
2719 return retval; | |
2706 } | 2720 } |
2707 | 2721 |
2708 #if defined(OPEN_CHR_FILES) || defined(PROTO) | 2722 #if defined(OPEN_CHR_FILES) || defined(PROTO) |
2709 /* | 2723 /* |
2710 * Returns TRUE if the file name argument is of the form "/dev/fd/\d\+", | 2724 * Returns TRUE if the file name argument is of the form "/dev/fd/\d\+", |
2939 // Set the cryptmethod local to the buffer. | 2953 // Set the cryptmethod local to the buffer. |
2940 crypt_set_cm_option(curbuf, method); | 2954 crypt_set_cm_option(curbuf, method); |
2941 if (cryptkey == NULL && !*did_ask) | 2955 if (cryptkey == NULL && !*did_ask) |
2942 { | 2956 { |
2943 if (*curbuf->b_p_key) | 2957 if (*curbuf->b_p_key) |
2958 { | |
2944 cryptkey = curbuf->b_p_key; | 2959 cryptkey = curbuf->b_p_key; |
2960 crypt_check_swapfile_curbuf(); | |
2961 } | |
2945 else | 2962 else |
2946 { | 2963 { |
2947 // When newfile is TRUE, store the typed key in the 'key' | 2964 // When newfile is TRUE, store the typed key in the 'key' |
2948 // option and don't free it. bf needs hash of the key saved. | 2965 // option and don't free it. bf needs hash of the key saved. |
2949 // Don't ask for the key again when first time Enter was hit. | 2966 // Don't ask for the key again when first time Enter was hit. |