From: David Lawrence Ramsey Date: Fri, 11 Feb 2005 20:09:11 +0000 (+0000) Subject: port over DB's overhaul of safe_tempnam() and his changes to X-Git-Tag: v1.3.6~87 X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=1b9d3f989803ec893bd13d4b8ef5734f4a369bb1;p=nano.git port over DB's overhaul of safe_tempnam() and his changes to check_operating_dir() to make it use boolean values (plus a few more boolean-related tweaks of mine); also stop wrapping the bad_chr parameter of parse_mbchar() in #ifdefs for cleanliness, as the allow_tabcomp parameter of check_operating_dir() isn't wrapped in #ifdefs, and don't set bad_chr to TRUE when we get a null byte in a multibyte string, as it's not an invalid multibyte character git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2316 35c25a1d-7b9e-4130-9fde-d3aeb78583b8 --- diff --git a/ChangeLog b/ChangeLog index c1e790fe..ef32227c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ CVS code - - General: - - More int -> bool conversions. (DLR) + - More int -> bool conversions. (DLR and David Benbennick) - Overhaul the cutting and uncutting routines to use the partitioning code, as it greatly simplifies how they work. New functions move_to_filestruct(), copy_from_filestruct(), @@ -152,7 +152,7 @@ CVS code - - Overhaul the tab completion code and a few related functions to increase efficiency and support multibyte characters. New functions strrchrn() and is_dir(); changes to get_full_path(), - check_writable_directory(), diralphasort(), + check_writable_directory(), safe_tempnam(), diralphasort(), username_tab_completion(), cwd_tab_completion(), input_tab(), tail(), and striponedir(); removal of append_slash_if_dir() and check_wildcard_match(). (David Benbennick) DLR: Move the diff --git a/src/chars.c b/src/chars.c index df949457..64e568bc 100644 --- a/src/chars.c +++ b/src/chars.c @@ -299,36 +299,32 @@ char *make_mbchar(int chr, char *chr_mb, int *chr_mb_len) /* Parse a multibyte character from buf. Return the number of bytes * used. If chr isn't NULL, store the multibyte character in it. If - * bad_chr isn't NULL, set it to TRUE if we have a null byte or a bad - * multibyte character. If col isn't NULL, store the new display width - * in it. If *str is '\t', we expect col to have the current display - * width. */ -int parse_mbchar(const char *buf, char *chr -#ifdef NANO_WIDE - , bool *bad_chr -#endif - , size_t *col) + * bad_chr isn't NULL, set it to TRUE if we have a bad multibyte + * character. If col isn't NULL, store the new display width in it. If + * *str is '\t', we expect col to have the current display width. */ +int parse_mbchar(const char *buf, char *chr, bool *bad_chr, size_t + *col) { int buf_mb_len; assert(buf != NULL); -#ifdef NANO_WIDE if (bad_chr != NULL) *bad_chr = FALSE; +#ifdef NANO_WIDE if (!ISSET(NO_UTF8)) { /* Get the number of bytes in the multibyte character. */ buf_mb_len = mblen(buf, MB_CUR_MAX); /* If buf contains a null byte or an invalid multibyte - * character, interpret buf's first byte and set bad_chr to - * TRUE. */ + * character, set bad_chr to TRUE (if it contains the latter) + * and interpret buf's first byte. */ if (buf_mb_len <= 0) { mblen(NULL, 0); - buf_mb_len = 1; - if (bad_chr != NULL) + if (buf_mb_len < 0 && bad_chr != NULL) *bad_chr = TRUE; + buf_mb_len = 1; } /* Save the multibyte character in chr. */ @@ -407,11 +403,8 @@ size_t move_mbleft(const char *buf, size_t pos) /* There is no library function to move backward one multibyte * character. Here is the naive, O(pos) way to do it. */ while (TRUE) { - int buf_mb_len = parse_mbchar(buf + pos - pos_prev, NULL -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + int buf_mb_len = parse_mbchar(buf + pos - pos_prev, NULL, NULL, + NULL); if (pos_prev <= (size_t)buf_mb_len) break; @@ -426,11 +419,7 @@ size_t move_mbleft(const char *buf, size_t pos) * after the one at pos. */ size_t move_mbright(const char *buf, size_t pos) { - return pos + parse_mbchar(buf + pos, NULL -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + return pos + parse_mbchar(buf + pos, NULL, NULL, NULL); } #ifndef HAVE_STRCASECMP diff --git a/src/files.c b/src/files.c index 2723fc0a..c244d21d 100644 --- a/src/files.c +++ b/src/files.c @@ -1128,59 +1128,37 @@ char *check_writable_directory(const char *path) return full_path; } -/* - * This function accepts a directory name and filename prefix the same - * way that tempnam() does, determines the location for its temporary - * file the same way that tempnam() does, safely creates the temporary - * file there via mkstemp(), and returns the name of the temporary file - * the same way that tempnam() does. It does not reference the value of - * TMP_MAX because the total number of random filenames that it can - * generate using one prefix is equal to 256**6, which is a sufficiently - * large number to handle most cases. Since the behavior after tempnam() - * generates TMP_MAX random filenames is implementation-defined, my - * implementation is to go on generating random filenames regardless of - * it. - */ -char *safe_tempnam(const char *dirname, const char *filename_prefix) +/* This function acts like a call to tempnam(NULL, "nano."). The + * difference is that the number of calls is not limited by TMP_MAX. + * Instead we use mkstemp(). */ +char *safe_tempnam(void) { char *full_tempdir = NULL; const char *TMPDIR_env; int filedesc; - /* if $TMPDIR is set and non-empty, set tempdir to it, run it through - get_full_path(), and save the result in full_tempdir; otherwise, - leave full_tempdir set to NULL */ + /* If $TMPDIR is set and non-empty, set tempdir to it, run it + * through get_full_path(), and save the result in full_tempdir. + * Otherwise, leave full_tempdir set to NULL. */ TMPDIR_env = getenv("TMPDIR"); if (TMPDIR_env != NULL && TMPDIR_env[0] != '\0') full_tempdir = check_writable_directory(TMPDIR_env); - /* if $TMPDIR is blank or isn't set, or isn't a writable - directory, and dirname isn't NULL, try it; otherwise, leave - full_tempdir set to NULL */ - if (full_tempdir == NULL && dirname != NULL) - full_tempdir = check_writable_directory(dirname); - - /* if $TMPDIR is blank or isn't set, or if it isn't a writable - directory, and dirname is NULL, try P_tmpdir instead */ + /* If $TMPDIR is unset, empty, or not a writable directory, and + * full_tempdir is NULL, try P_tmpdir instead. */ if (full_tempdir == NULL) full_tempdir = check_writable_directory(P_tmpdir); - /* if P_tmpdir didn't work, use /tmp instead */ - if (full_tempdir == NULL) { - full_tempdir = charalloc(6); - strcpy(full_tempdir, "/tmp/"); - } + /* if P_tmpdir is NULL, use /tmp. */ + if (full_tempdir == NULL) + full_tempdir = mallocstrcpy(NULL, "/tmp/"); full_tempdir = charealloc(full_tempdir, strlen(full_tempdir) + 12); - - /* like tempnam(), use only the first 5 characters of the prefix */ - strncat(full_tempdir, filename_prefix, 5); - strcat(full_tempdir, "XXXXXX"); + strcat(full_tempdir, "nano.XXXXXX"); filedesc = mkstemp(full_tempdir); - /* if mkstemp succeeded, close the resulting file; afterwards, it'll be - 0 bytes long, so delete it; finally, return the filename (all that's - left of it) */ + /* If mkstemp() succeeded, close the resulting file, delete it + * (since it'll be 0 bytes long), and return the filename. */ if (filedesc != -1) { close(filedesc); unlink(full_tempdir); @@ -1188,6 +1166,7 @@ char *safe_tempnam(const char *dirname, const char *filename_prefix) } free(full_tempdir); + return NULL; } #endif /* !DISABLE_SPELLER */ @@ -1213,11 +1192,11 @@ void init_operating_dir(void) } } -/* Check to see if we're inside the operating directory. Return 0 if we - * are, or 1 otherwise. If allow_tabcomp is nonzero, allow incomplete - * names that would be matches for the operating directory, so that tab - * completion will work. */ -int check_operating_dir(const char *currpath, bool allow_tabcomp) +/* Check to see if we're inside the operating directory. Return FALSE + * if we are, or TRUE otherwise. If allow_tabcomp is TRUE, allow + * incomplete names that would be matches for the operating directory, + * so that tab completion will work. */ +bool check_operating_dir(const char *currpath, bool allow_tabcomp) { /* The char *full_operating_dir is global for mem cleanup. It * should have already been initialized by init_operating_dir(). @@ -1225,22 +1204,22 @@ int check_operating_dir(const char *currpath, bool allow_tabcomp) * properly if this is done. */ char *fullpath; - int retval = 0; + bool retval = FALSE; const char *whereami1, *whereami2 = NULL; /* If no operating directory is set, don't bother doing anything. */ if (operating_dir == NULL) - return 0; + return FALSE; assert(full_operating_dir != NULL); fullpath = get_full_path(currpath); /* fullpath == NULL means some directory in the path doesn't exist - * or is unreadable. If allow_tabcomp is zero, then currpath is + * or is unreadable. If allow_tabcomp is FALSE, then currpath is * what the user typed somewhere. We don't want to report a * non-existent directory as being outside the operating directory, - * so we return 0. If allow_tabcomp is nonzero, then currpath + * so we return FALSE. If allow_tabcomp is TRUE, then currpath * exists, but is not executable. So we say it isn't in the * operating directory. */ if (fullpath == NULL) @@ -1256,8 +1235,8 @@ int check_operating_dir(const char *currpath, bool allow_tabcomp) * (for normal usage) and vice versa (for tab completion, if we're * allowing it), we're outside the operating directory. */ if (whereami1 != fullpath && whereami2 != full_operating_dir) - retval = 1; - free(fullpath); + retval = TRUE; + free(fullpath); /* Otherwise, we're still inside it. */ return retval; @@ -1372,7 +1351,7 @@ int write_file(const char *name, bool tmp, int append, bool #ifndef DISABLE_OPERATINGDIR /* If we're writing a temporary file, we're probably going outside * the operating directory, so skip the operating directory test. */ - if (!tmp && check_operating_dir(realname, FALSE) != 0) { + if (!tmp && check_operating_dir(realname, FALSE)) { statusbar(_("Can't write outside of %s"), operating_dir); goto cleanup_and_exit; } @@ -2549,7 +2528,7 @@ char *do_browser(const char *inpath) /* Note: the selected file can be outside the operating * directory if it is .. or if it is a symlink to * directory outside the operating directory. */ - if (check_operating_dir(filelist[selected], FALSE) != 0) { + if (check_operating_dir(filelist[selected], FALSE)) { statusbar(_("Can't go outside of %s in restricted mode"), operating_dir); beep(); @@ -2625,7 +2604,7 @@ char *do_browser(const char *inpath) } #ifndef DISABLE_OPERATINGDIR - if (check_operating_dir(new_path, FALSE) != 0) { + if (check_operating_dir(new_path, FALSE)) { statusbar(_("Can't go outside of %s in restricted mode"), operating_dir); free(new_path); break; @@ -2769,7 +2748,7 @@ char *do_browse_from(const char *inpath) #ifndef DISABLE_OPERATINGDIR /* If the resulting path isn't in the operating directory, use that. */ - if (check_operating_dir(path, FALSE) != 0) + if (check_operating_dir(path, FALSE)) path = mallocstrcpy(path, operating_dir); #endif diff --git a/src/nano.c b/src/nano.c index 79dde436..07537220 100644 --- a/src/nano.c +++ b/src/nano.c @@ -1195,11 +1195,8 @@ void do_delete(void) placewewant = xplustabs(); if (current->data[current_x] != '\0') { - int char_buf_len = parse_mbchar(current->data + current_x, NULL -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + int char_buf_len = parse_mbchar(current->data + current_x, NULL, + NULL, NULL); size_t line_len = strlen(current->data + current_x); assert(current_x < strlen(current->data)); @@ -1340,11 +1337,8 @@ void do_next_word(void) /* Move forward until we find the character after the last letter of * the current word. */ while (current->data[current_x] != '\0') { - char_mb_len = parse_mbchar(current->data + current_x, char_mb -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + char_mb_len = parse_mbchar(current->data + current_x, char_mb, + NULL, NULL); /* If we've found it, stop moving forward through the current * line. */ @@ -1361,11 +1355,7 @@ void do_next_word(void) for (; current != NULL; current = current->next) { while (current->data[current_x] != '\0') { char_mb_len = parse_mbchar(current->data + current_x, - char_mb -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + char_mb, NULL, NULL); /* If we've found it, stop moving forward through the * current line. */ @@ -1412,11 +1402,8 @@ void do_prev_word(void) /* Move backward until we find the character before the first letter * of the current word. */ while (!begin_line) { - char_mb_len = parse_mbchar(current->data + current_x, char_mb -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + char_mb_len = parse_mbchar(current->data + current_x, char_mb, + NULL, NULL); /* If we've found it, stop moving backward through the current * line. */ @@ -1439,11 +1426,7 @@ void do_prev_word(void) for (; current != NULL; current = current->prev) { while (!begin_line) { char_mb_len = parse_mbchar(current->data + current_x, - char_mb -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + char_mb, NULL, NULL); /* If we've found it, stop moving backward through the * current line. */ @@ -1482,11 +1465,7 @@ void do_prev_word(void) while (!begin_line) { char_mb_len = parse_mbchar(current->data + current_x, - char_mb -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + char_mb, NULL, NULL); /* If we've found it, stop moving backward through the * current line. */ @@ -2260,7 +2239,7 @@ const char *do_alt_speller(char *tempfile_name) void do_spell(void) { int i; - char *temp = safe_tempnam(0, "nano."); + char *temp = safe_tempnam(); const char *spell_msg; if (temp == NULL) { @@ -2314,11 +2293,7 @@ size_t indent_length(const char *line) blank_mb = charalloc(mb_cur_max()); while (*line != '\0') { - blank_mb_len = parse_mbchar(line, blank_mb -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + blank_mb_len = parse_mbchar(line, blank_mb, NULL, NULL); if (!is_blank_mbchar(blank_mb)) break; @@ -2653,11 +2628,7 @@ bool breakable(const char *line, ssize_t goal) if (is_blank_char(*line)) return TRUE; - line += parse_mbchar(line, NULL -#ifdef NANO_WIDE - , NULL -#endif - , &pos); + line += parse_mbchar(line, NULL, NULL, &pos); goal -= pos; } @@ -2691,11 +2662,7 @@ ssize_t break_line(const char *line, ssize_t goal, bool force) assert(*line != '\t'); - line_len = parse_mbchar(line, NULL -#ifdef NANO_WIDE - , NULL -#endif - , &pos); + line_len = parse_mbchar(line, NULL, NULL, &pos); goal -= pos; line += line_len; @@ -3768,11 +3735,7 @@ void do_output(char *output, size_t output_len) /* Interpret the next multibyte character. If it's an invalid * multibyte character, interpret it as though it's a byte * character. */ - char_buf_len = parse_mbchar(output + i, char_buf -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + char_buf_len = parse_mbchar(output + i, char_buf, NULL, NULL); i += char_buf_len; diff --git a/src/proto.h b/src/proto.h index 1abb8a95..6dc7bcc5 100644 --- a/src/proto.h +++ b/src/proto.h @@ -173,11 +173,8 @@ wchar_t control_wrep(wchar_t c); int mbwidth(const char *c); int mb_cur_max(void); char *make_mbchar(int chr, char *chr_mb, int *chr_mb_len); -int parse_mbchar(const char *buf, char *chr -#ifdef NANO_WIDE - , bool *bad_chr -#endif - , size_t *col); +int parse_mbchar(const char *buf, char *chr, bool *bad_chr, size_t + *col); size_t move_mbleft(const char *buf, size_t pos); size_t move_mbright(const char *buf, size_t pos); #ifndef HAVE_STRCASECMP @@ -270,11 +267,11 @@ char *get_full_path(const char *origpath); #endif #ifndef DISABLE_SPELLER char *check_writable_directory(const char *path); -char *safe_tempnam(const char *dirname, const char *filename_prefix); +char *safe_tempnam(void); #endif #ifndef DISABLE_OPERATINGDIR void init_operating_dir(void); -int check_operating_dir(const char *currpath, bool allow_tabcomp); +bool check_operating_dir(const char *currpath, bool allow_tabcomp); #endif #ifndef NANO_SMALL void init_backup_dir(void); diff --git a/src/winio.c b/src/winio.c index 8553d664..08df4f21 100644 --- a/src/winio.c +++ b/src/winio.c @@ -1858,11 +1858,8 @@ void do_statusbar_backspace(void) void do_statusbar_delete(void) { if (statusbar_x < statusbar_xend) { - int char_buf_len = parse_mbchar(answer + statusbar_x, NULL -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + int char_buf_len = parse_mbchar(answer + statusbar_x, NULL, + NULL, NULL); charmove(answer + statusbar_x, answer + statusbar_x + char_buf_len, statusbar_xend - statusbar_x - @@ -1896,11 +1893,8 @@ void do_statusbar_next_word(void) /* Move forward until we find the character after the last letter of * the current word. */ while (statusbar_x < statusbar_xend) { - char_mb_len = parse_mbchar(answer + statusbar_x, char_mb -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + char_mb_len = parse_mbchar(answer + statusbar_x, char_mb, NULL, + NULL); /* If we've found it, stop moving forward through the current * line. */ @@ -1915,11 +1909,8 @@ void do_statusbar_next_word(void) current_x += char_mb_len; while (statusbar_x < statusbar_xend) { - char_mb_len = parse_mbchar(answer + statusbar_x, char_mb -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + char_mb_len = parse_mbchar(answer + statusbar_x, char_mb, NULL, + NULL); /* If we've found it, stop moving forward through the current * line. */ @@ -1945,11 +1936,8 @@ void do_statusbar_prev_word(void) /* Move backward until we find the character before the first letter * of the current word. */ while (!begin_line) { - char_mb_len = parse_mbchar(answer + statusbar_x, char_mb -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + char_mb_len = parse_mbchar(answer + statusbar_x, char_mb, NULL, + NULL); /* If we've found it, stop moving backward through the current * line. */ @@ -1970,11 +1958,8 @@ void do_statusbar_prev_word(void) statusbar_x = move_mbleft(answer, statusbar_x); while (!begin_line) { - char_mb_len = parse_mbchar(answer + statusbar_x, char_mb -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + char_mb_len = parse_mbchar(answer + statusbar_x, char_mb, NULL, + NULL); /* If we've found it, stop moving backward through the current * line. */ @@ -1996,11 +1981,8 @@ void do_statusbar_prev_word(void) statusbar_x = move_mbleft(answer, statusbar_x); while (!begin_line) { - char_mb_len = parse_mbchar(answer + statusbar_x, char_mb -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + char_mb_len = parse_mbchar(answer + statusbar_x, char_mb, + NULL, NULL); /* If we've found it, stop moving backward through the * current line. */ @@ -2075,11 +2057,7 @@ void do_statusbar_output(char *output, size_t output_len, bool /* Interpret the next multibyte character. If it's an invalid * multibyte character, interpret it as though it's a byte * character. */ - char_buf_len = parse_mbchar(output + i, char_buf -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + char_buf_len = parse_mbchar(output + i, char_buf, NULL, NULL); i += char_buf_len; @@ -2122,11 +2100,7 @@ size_t actual_x(const char *str, size_t xplus) assert(str != NULL); while (*str != '\0') { - int str_len = parse_mbchar(str, NULL -#ifdef NANO_WIDE - , NULL -#endif - , &length); + int str_len = parse_mbchar(str, NULL, NULL, &length); if (length > xplus) break; @@ -2151,11 +2125,7 @@ size_t strnlenpt(const char *str, size_t size) assert(str != NULL); while (*str != '\0') { - int str_len = parse_mbchar(str, NULL -#ifdef NANO_WIDE - , NULL -#endif - , &length); + int str_len = parse_mbchar(str, NULL, NULL, &length); str += str_len; @@ -2269,11 +2239,8 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool buf[start_index] != '\t')) { /* We don't display all of buf[start_index] since it starts to * the left of the screen. */ - buf_mb_len = parse_mbchar(buf + start_index, buf_mb -#ifdef NANO_WIDE - , NULL -#endif - , NULL); + buf_mb_len = parse_mbchar(buf + start_index, buf_mb, NULL, + NULL); if (is_cntrl_mbchar(buf_mb)) { if (column < start_col) { @@ -2307,6 +2274,8 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool buf_mb_len = parse_mbchar(buf + start_index, buf_mb #ifdef NANO_WIDE , &bad_char +#else + , NULL #endif , NULL);