diff options
Diffstat (limited to 'src/nvim/fileio.c')
-rw-r--r-- | src/nvim/fileio.c | 121 |
1 files changed, 70 insertions, 51 deletions
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 7abc75916c..77ddbb1eda 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -308,29 +308,30 @@ readfile ( #ifdef UNIX int swap_mode = -1; /* protection bits for swap file */ #endif - int fileformat = 0; /* end-of-line format */ - int keep_fileformat = FALSE; + int fileformat = 0; // end-of-line format + bool keep_fileformat = false; + FileInfo file_info; int file_readonly; linenr_T skip_count = 0; linenr_T read_count = 0; int msg_save = msg_scroll; linenr_T read_no_eol_lnum = 0; // non-zero lnum when last line of // last read was missing the eol - int file_rewind = false; + bool file_rewind = false; int can_retry; - linenr_T conv_error = 0; /* line nr with conversion error */ - linenr_T illegal_byte = 0; /* line nr with illegal byte */ - int keep_dest_enc = FALSE; /* don't retry when char doesn't fit - in destination encoding */ + linenr_T conv_error = 0; // line nr with conversion error + linenr_T illegal_byte = 0; // line nr with illegal byte + bool keep_dest_enc = false; // don't retry when char doesn't fit + // in destination encoding int bad_char_behavior = BAD_REPLACE; /* BAD_KEEP, BAD_DROP or character to * replace with */ char_u *tmpname = NULL; /* name of 'charconvert' output file */ int fio_flags = 0; - char_u *fenc; /* fileencoding to use */ - int fenc_alloced; /* fenc_next is in allocated memory */ - char_u *fenc_next = NULL; /* next item in 'fencs' or NULL */ - int advance_fenc = FALSE; + char_u *fenc; // fileencoding to use + bool fenc_alloced; // fenc_next is in allocated memory + char_u *fenc_next = NULL; // next item in 'fencs' or NULL + bool advance_fenc = false; long real_size = 0; # ifdef USE_ICONV iconv_t iconv_fd = (iconv_t)-1; /* descriptor for iconv() or -1 */ @@ -481,7 +482,6 @@ readfile ( if (newfile && !read_stdin && !read_buffer && !read_fifo) { // Remember time of file. - FileInfo file_info; if (os_fileinfo((char *)fname, &file_info)) { buf_store_file_info(curbuf, &file_info); curbuf->b_mtime_read = curbuf->b_mtime; @@ -627,8 +627,25 @@ readfile ( // Set swap file protection bits after creating it. if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL && curbuf->b_ml.ml_mfp->mf_fname != NULL) { - (void)os_setperm((const char *)curbuf->b_ml.ml_mfp->mf_fname, - (long)swap_mode); + const char *swap_fname = (const char *)curbuf->b_ml.ml_mfp->mf_fname; + + // If the group-read bit is set but not the world-read bit, then + // the group must be equal to the group of the original file. If + // we can't make that happen then reset the group-read bit. This + // avoids making the swap file readable to more users when the + // primary group of the user is too permissive. + if ((swap_mode & 044) == 040) { + FileInfo swap_info; + + if (os_fileinfo(swap_fname, &swap_info) + && file_info.stat.st_gid != swap_info.stat.st_gid + && os_fchown(curbuf->b_ml.ml_mfp->mf_fd, -1, file_info.stat.st_gid) + == -1) { + swap_mode &= 0600; + } + } + + (void)os_setperm(swap_fname, swap_mode); } #endif } @@ -747,11 +764,11 @@ readfile ( */ if (eap != NULL && eap->force_enc != 0) { fenc = enc_canonize(eap->cmd + eap->force_enc); - fenc_alloced = TRUE; - keep_dest_enc = TRUE; + fenc_alloced = true; + keep_dest_enc = true; } else if (curbuf->b_p_bin) { - fenc = (char_u *)""; /* binary: don't convert */ - fenc_alloced = FALSE; + fenc = (char_u *)""; // binary: don't convert + fenc_alloced = false; } else if (curbuf->b_help) { // Help files are either utf-8 or latin1. Try utf-8 first, if this // fails it must be latin1. @@ -762,12 +779,12 @@ readfile ( fenc_alloced = false; } else if (*p_fencs == NUL) { - fenc = curbuf->b_p_fenc; /* use format from buffer */ - fenc_alloced = FALSE; + fenc = curbuf->b_p_fenc; // use format from buffer + fenc_alloced = false; } else { fenc_next = p_fencs; /* try items in 'fileencodings' */ fenc = next_fenc(&fenc_next); - fenc_alloced = TRUE; + fenc_alloced = true; } /* @@ -800,10 +817,11 @@ retry: error = true; goto failed; } - /* Delete the previously read lines. */ - while (lnum > from) - ml_delete(lnum--, FALSE); - file_rewind = FALSE; + // Delete the previously read lines. + while (lnum > from) { + ml_delete(lnum--, false); + } + file_rewind = false; if (set_options) { curbuf->b_p_bomb = FALSE; curbuf->b_start_bomb = FALSE; @@ -815,9 +833,9 @@ retry: * When retrying with another "fenc" and the first time "fileformat" * will be reset. */ - if (keep_fileformat) - keep_fileformat = FALSE; - else { + if (keep_fileformat) { + keep_fileformat = false; + } else { if (eap != NULL && eap->force_ff != 0) { fileformat = get_fileformat_force(curbuf, eap); try_unix = try_dos = try_mac = FALSE; @@ -841,7 +859,7 @@ retry: /* * Try the next entry in 'fileencodings'. */ - advance_fenc = FALSE; + advance_fenc = false; if (eap != NULL && eap->force_enc != 0) { /* Conversion given with "++cc=" wasn't possible, read @@ -851,7 +869,7 @@ retry: if (fenc_alloced) xfree(fenc); fenc = (char_u *)""; - fenc_alloced = FALSE; + fenc_alloced = false; } else { if (fenc_alloced) xfree(fenc); @@ -860,7 +878,7 @@ retry: fenc_alloced = (fenc_next != NULL); } else { fenc = (char_u *)""; - fenc_alloced = FALSE; + fenc_alloced = false; } } if (tmpname != NULL) { @@ -926,8 +944,8 @@ retry: if (tmpname == NULL) { tmpname = readfile_charconvert(fname, fenc, &fd); if (tmpname == NULL) { - /* Conversion failed. Try another one. */ - advance_fenc = TRUE; + // Conversion failed. Try another one. + advance_fenc = true; if (fd < 0) { /* Re-opening the original file failed! */ EMSG(_("E202: Conversion made file unreadable!")); @@ -945,7 +963,7 @@ retry: ) { /* Conversion wanted but we can't. * Try the next conversion in 'fileencodings' */ - advance_fenc = TRUE; + advance_fenc = true; goto retry; } } @@ -1180,14 +1198,14 @@ retry: if (fio_flags == FIO_UCSBOM) { if (ccname == NULL) { - /* No BOM detected: retry with next encoding. */ - advance_fenc = TRUE; + // No BOM detected: retry with next encoding. + advance_fenc = true; } else { /* BOM detected: set "fenc" and jump back */ if (fenc_alloced) xfree(fenc); fenc = ccname; - fenc_alloced = FALSE; + fenc_alloced = false; } /* retry reading without getting new bytes or rewinding */ skip_read = TRUE; @@ -1512,9 +1530,9 @@ rewind_retry: did_iconv = TRUE; else # endif - /* use next item from 'fileencodings' */ - advance_fenc = TRUE; - file_rewind = TRUE; + // use next item from 'fileencodings' + advance_fenc = true; + file_rewind = true; goto retry; } } @@ -1648,8 +1666,8 @@ rewind_retry: fileformat = EOL_UNIX; if (set_options) set_fileformat(EOL_UNIX, OPT_LOCAL); - file_rewind = TRUE; - keep_fileformat = TRUE; + file_rewind = true; + keep_fileformat = true; goto retry; } ff_error = EOL_DOS; @@ -1760,8 +1778,8 @@ failed: if (!recoverymode) { /* need to delete the last line, which comes from the empty buffer */ if (newfile && wasempty && !(curbuf->b_ml.ml_flags & ML_EMPTY)) { - ml_delete(curbuf->b_ml.ml_line_count, FALSE); - --linecnt; + ml_delete(curbuf->b_ml.ml_line_count, false); + linecnt--; } linecnt = curbuf->b_ml.ml_line_count - linecnt; if (filesize == 0) @@ -4894,9 +4912,9 @@ static int move_lines(buf_T *frombuf, buf_T *tobuf) /* Copy the lines in "frombuf" to "tobuf". */ curbuf = tobuf; - for (lnum = 1; lnum <= frombuf->b_ml.ml_line_count; ++lnum) { - p = vim_strsave(ml_get_buf(frombuf, lnum, FALSE)); - if (ml_append(lnum - 1, p, 0, FALSE) == FAIL) { + for (lnum = 1; lnum <= frombuf->b_ml.ml_line_count; lnum++) { + p = vim_strsave(ml_get_buf(frombuf, lnum, false)); + if (ml_append(lnum - 1, p, 0, false) == FAIL) { xfree(p); retval = FAIL; break; @@ -4907,13 +4925,14 @@ static int move_lines(buf_T *frombuf, buf_T *tobuf) /* Delete all the lines in "frombuf". */ if (retval != FAIL) { curbuf = frombuf; - for (lnum = curbuf->b_ml.ml_line_count; lnum > 0; --lnum) - if (ml_delete(lnum, FALSE) == FAIL) { - /* Oops! We could try putting back the saved lines, but that - * might fail again... */ + for (lnum = curbuf->b_ml.ml_line_count; lnum > 0; lnum--) { + if (ml_delete(lnum, false) == FAIL) { + // Oops! We could try putting back the saved lines, but that + // might fail again... retval = FAIL; break; } + } } curbuf = tbuf; |