fix potential memory corruption problems caused by passing answer in as
the value of def in statusq(), etc. git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1695 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
Этот коммит содержится в:
родитель
dc10ecbbd6
Коммит
6aec4b85e6
15
ChangeLog
15
ChangeLog
@ -31,6 +31,13 @@ CVS code -
|
||||
and use tail() to get the filename if get_full_path() fails.
|
||||
- Port to the Tandem NonStop Kernel (nsr-tandem-nsk). (Tom
|
||||
Bates; minor tweaks by DLR)
|
||||
- Change some instances of boolean 0 and 1 to TRUE and FALSE.
|
||||
(David Benbennick)
|
||||
- Fix memory corruption problem occurring when answer is used as
|
||||
the value of def; if the realloc() of answer leads to its
|
||||
pointing to a different memory block, there will be a segfault
|
||||
when the value of def is copied into it via strcpy(). (bort,
|
||||
Christian Weisgarber, David Benbennick, and DLR)
|
||||
- files.c:
|
||||
do_insertfile()
|
||||
- Wrap one reference to NANO_EXTCMD_KEY in a NANO_SMALL #ifdef.
|
||||
@ -45,6 +52,9 @@ CVS code -
|
||||
write_marked()
|
||||
- New function used to write the current marked selection to a
|
||||
file, split out from do_writeout(). (DLR)
|
||||
do_writeout()
|
||||
- Tweak for efficiency. (David Benbennick) DLR: Modify to have
|
||||
the current answer preserved between toggles again.
|
||||
filestat()
|
||||
- Removed, as it is only called in one place and is
|
||||
redundant. (DLR)
|
||||
@ -175,6 +185,9 @@ CVS code -
|
||||
strstrwrapper()
|
||||
- Refactor for increased efficiency, and eliminate the need for
|
||||
the line_pos parameter. (David Benbennick)
|
||||
mallocstrcpy()
|
||||
- Tweak so that when src is "", "" is allocated and returned
|
||||
instead of NULL. (David Benbennick)
|
||||
- winio.c:
|
||||
get_verbatim_kbinput()
|
||||
- Set keypad() to FALSE and switch to raw mode while reading
|
||||
@ -212,6 +225,8 @@ CVS code -
|
||||
- Tweak for efficiency. (David Benbennick)
|
||||
edit_refresh()
|
||||
- Tweak for efficiency. (David Benbennick)
|
||||
statusq()
|
||||
- Rename "tabs" to "allowtabs". (David Benbennick)
|
||||
do_credits()
|
||||
- Use nanosleep() instead of usleep(). The latter is only
|
||||
standard under BSD, whereas the former is POSIX compliant.
|
||||
|
136
src/files.c
136
src/files.c
@ -406,7 +406,7 @@ char *get_next_filename(const char *name)
|
||||
buf = charalloc(strlen(name) + num_of_digits(INT_MAX) + 2);
|
||||
strcpy(buf, name);
|
||||
|
||||
while (1) {
|
||||
while (TRUE) {
|
||||
|
||||
if (stat(buf, &fs) == -1)
|
||||
return buf;
|
||||
@ -451,17 +451,17 @@ int do_insertfile(int loading_file)
|
||||
if (operating_dir != NULL && strcmp(operating_dir, "."))
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (ISSET(MULTIBUFFER))
|
||||
i = statusq(1, insertfile_list, inspath,
|
||||
i = statusq(TRUE, insertfile_list, inspath,
|
||||
#ifndef NANO_SMALL
|
||||
0,
|
||||
NULL,
|
||||
#endif
|
||||
_("File to insert into new buffer [from %s] "),
|
||||
operating_dir);
|
||||
else
|
||||
#endif
|
||||
i = statusq(1, insertfile_list, inspath,
|
||||
i = statusq(TRUE, insertfile_list, inspath,
|
||||
#ifndef NANO_SMALL
|
||||
0,
|
||||
NULL,
|
||||
#endif
|
||||
_("File to insert [from %s] "),
|
||||
operating_dir);
|
||||
@ -470,16 +470,16 @@ int do_insertfile(int loading_file)
|
||||
#endif
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (ISSET(MULTIBUFFER))
|
||||
i = statusq(1, insertfile_list, inspath,
|
||||
i = statusq(TRUE, insertfile_list, inspath,
|
||||
#ifndef NANO_SMALL
|
||||
0,
|
||||
NULL,
|
||||
#endif
|
||||
_("File to insert into new buffer [from ./] "));
|
||||
else
|
||||
#endif /* ENABLE_MULTIBUFFER */
|
||||
i = statusq(1, insertfile_list, inspath,
|
||||
i = statusq(TRUE, insertfile_list, inspath,
|
||||
#ifndef NANO_SMALL
|
||||
0,
|
||||
NULL,
|
||||
#endif
|
||||
_("File to insert [from ./] "));
|
||||
|
||||
@ -501,8 +501,12 @@ int do_insertfile(int loading_file)
|
||||
#endif /* ENABLE_MULTIBUFFER */
|
||||
|
||||
if (i == NANO_EXTCMD_KEY) {
|
||||
int ts = statusq(TRUE, extcmd_list, answer, NULL,
|
||||
char *ans = mallocstrcpy(NULL, answer);
|
||||
int ts = statusq(TRUE, extcmd_list, ans, NULL,
|
||||
_("Command to execute"));
|
||||
|
||||
free(ans);
|
||||
|
||||
if (ts == -1 || answer == NULL || answer[0] == '\0') {
|
||||
statusbar(_("Cancelled"));
|
||||
display_main_list();
|
||||
@ -1802,35 +1806,50 @@ int write_marked(const char *name, int tmp, int append, int
|
||||
}
|
||||
#endif /* !NANO_SMALL */
|
||||
|
||||
int do_writeout(const char *path, int exiting, int append)
|
||||
int do_writeout(int exiting)
|
||||
{
|
||||
int i = 0;
|
||||
int i;
|
||||
int append = 0;
|
||||
#ifdef NANO_EXTRA
|
||||
static int did_cred = 0;
|
||||
static int did_cred = FALSE;
|
||||
#endif
|
||||
|
||||
#if !defined(DISABLE_BROWSER) || !defined(DISABLE_MOUSE)
|
||||
currshortcut = writefile_list;
|
||||
#endif
|
||||
|
||||
answer = mallocstrcpy(answer, path);
|
||||
|
||||
if (exiting && ISSET(TEMP_OPT)) {
|
||||
i = -1;
|
||||
if (filename[0] != '\0') {
|
||||
i = write_file(answer, 0, 0, 0);
|
||||
display_main_list();
|
||||
return i;
|
||||
} else {
|
||||
i = write_file(filename, FALSE, 0, FALSE);
|
||||
if (i == 1) {
|
||||
/* Write succeeded. */
|
||||
display_main_list();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* No filename or the write above failed. */
|
||||
if (i == -1) {
|
||||
UNSET(TEMP_OPT);
|
||||
do_exit();
|
||||
|
||||
/* They cancelled, abort quit */
|
||||
/* They cancelled; abort quit. */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
#ifndef NANO_SMALL
|
||||
if (ISSET(MARK_ISSET) && !exiting)
|
||||
answer = mallocstrcpy(answer, "");
|
||||
else
|
||||
#endif
|
||||
answer = mallocstrcpy(answer, filename);
|
||||
|
||||
while (TRUE) {
|
||||
const char *msg;
|
||||
#ifndef NANO_SMALL
|
||||
char *ans = mallocstrcpy(NULL, answer);
|
||||
const char *formatstr, *backupstr;
|
||||
|
||||
if (ISSET(MAC_FILE))
|
||||
@ -1845,44 +1864,39 @@ int do_writeout(const char *path, int exiting, int append)
|
||||
else
|
||||
backupstr = "";
|
||||
|
||||
/* Be nice to the translation folks */
|
||||
/* Be nice to the translation folks. */
|
||||
if (ISSET(MARK_ISSET) && !exiting) {
|
||||
if (append == 2)
|
||||
i = statusq(1, writefile_list, "", 0,
|
||||
"%s%s%s", _("Prepend Selection to File"), formatstr, backupstr);
|
||||
msg = _("Prepend Selection to File");
|
||||
else if (append == 1)
|
||||
i = statusq(1, writefile_list, "", 0,
|
||||
"%s%s%s", _("Append Selection to File"), formatstr, backupstr);
|
||||
msg = _("Append Selection to File");
|
||||
else
|
||||
i = statusq(1, writefile_list, "", 0,
|
||||
"%s%s%s", _("Write Selection to File"), formatstr, backupstr);
|
||||
} else {
|
||||
if (append == 2)
|
||||
i = statusq(1, writefile_list, answer, 0,
|
||||
"%s%s%s", _("File Name to Prepend to"), formatstr, backupstr);
|
||||
else if (append == 1)
|
||||
i = statusq(1, writefile_list, answer, 0,
|
||||
"%s%s%s", _("File Name to Append to"), formatstr, backupstr);
|
||||
else
|
||||
i = statusq(1, writefile_list, answer, 0,
|
||||
"%s%s%s", _("File Name to Write"), formatstr, backupstr);
|
||||
}
|
||||
#else
|
||||
if (append == 2)
|
||||
i = statusq(1, writefile_list, answer,
|
||||
"%s", _("File Name to Prepend to"));
|
||||
else if (append == 1)
|
||||
i = statusq(1, writefile_list, answer,
|
||||
"%s", _("File Name to Append to"));
|
||||
else
|
||||
i = statusq(1, writefile_list, answer,
|
||||
"%s", _("File Name to Write"));
|
||||
msg = _("Write Selection to File");
|
||||
} else
|
||||
#endif /* !NANO_SMALL */
|
||||
if (append == 2)
|
||||
msg = _("File Name to Prepend to");
|
||||
else if (append == 1)
|
||||
msg = _("File Name to Append to");
|
||||
else
|
||||
msg = _("File Name to Write");
|
||||
|
||||
i = statusq(TRUE, writefile_list,
|
||||
#ifndef NANO_SMALL
|
||||
ans, NULL, "%s%s%s", msg, formatstr, backupstr
|
||||
#else
|
||||
filename, "%s", msg
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
free(ans);
|
||||
#endif
|
||||
|
||||
if (i == -1) {
|
||||
statusbar(_("Cancelled"));
|
||||
display_main_list();
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_BROWSER
|
||||
@ -1926,7 +1940,7 @@ int do_writeout(const char *path, int exiting, int append)
|
||||
if (exiting && !ISSET(TEMP_OPT) && !strcasecmp(answer, "zzy")
|
||||
&& !did_cred) {
|
||||
do_credits();
|
||||
did_cred = 1;
|
||||
did_cred = TRUE;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
@ -1934,7 +1948,7 @@ int do_writeout(const char *path, int exiting, int append)
|
||||
struct stat st;
|
||||
|
||||
if (!stat(answer, &st)) {
|
||||
i = do_yesno(0, _("File exists, OVERWRITE ?"));
|
||||
i = do_yesno(FALSE, _("File exists, OVERWRITE ?"));
|
||||
if (i == 0 || i == -1)
|
||||
continue;
|
||||
} else if (filename[0] != '\0'
|
||||
@ -1942,7 +1956,7 @@ int do_writeout(const char *path, int exiting, int append)
|
||||
&& (!ISSET(MARK_ISSET) || exiting)
|
||||
#endif
|
||||
) {
|
||||
i = do_yesno(0, _("Save file under DIFFERENT NAME ?"));
|
||||
i = do_yesno(FALSE, _("Save file under DIFFERENT NAME ?"));
|
||||
if (i == 0 || i == -1)
|
||||
continue;
|
||||
}
|
||||
@ -1952,25 +1966,25 @@ int do_writeout(const char *path, int exiting, int append)
|
||||
/* Here's where we allow the selected text to be written to
|
||||
* a separate file. */
|
||||
if (ISSET(MARK_ISSET) && !exiting)
|
||||
i = write_marked(answer, 0, append, 1);
|
||||
i = write_marked(answer, FALSE, append, FALSE);
|
||||
else
|
||||
#endif /* !NANO_SMALL */
|
||||
i = write_file(answer, 0, append, 0);
|
||||
i = write_file(answer, FALSE, append, FALSE);
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
/* If we're not about to exit, update the current entry in
|
||||
the open_files structure. */
|
||||
* the open_files structure. */
|
||||
if (!exiting)
|
||||
add_open_file(1);
|
||||
#endif
|
||||
display_main_list();
|
||||
return i;
|
||||
} /* while (1) */
|
||||
} /* while (TRUE) */
|
||||
}
|
||||
|
||||
int do_writeout_void(void)
|
||||
{
|
||||
return do_writeout(filename, 0, 0);
|
||||
return do_writeout(FALSE);
|
||||
}
|
||||
|
||||
/* Return a malloc()ed string containing the actual directory, used
|
||||
@ -2338,7 +2352,7 @@ char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list)
|
||||
pos <= strlen(matches[0]); pos++)
|
||||
tmp++;
|
||||
|
||||
while (1) {
|
||||
while (TRUE) {
|
||||
match_matches = 0;
|
||||
|
||||
for (i = 0; i < num_matches; i++) {
|
||||
@ -2752,9 +2766,9 @@ char *do_browser(const char *inpath)
|
||||
case 'G': /* Pico compatibility */
|
||||
case 'g':
|
||||
curs_set(1);
|
||||
j = statusq(0, gotodir_list, "",
|
||||
j = statusq(FALSE, gotodir_list, "",
|
||||
#ifndef NANO_SMALL
|
||||
0,
|
||||
NULL,
|
||||
#endif
|
||||
_("Goto Directory"));
|
||||
bottombars(browser_list);
|
||||
|
@ -1511,7 +1511,7 @@ int do_int_spell_fix(const char *word)
|
||||
do_replace_highlight(TRUE, word);
|
||||
|
||||
/* Allow the replace word to be corrected. */
|
||||
i = statusq(0, spell_list, word,
|
||||
i = statusq(FALSE, spell_list, word,
|
||||
#ifndef NANO_SMALL
|
||||
NULL,
|
||||
#endif
|
||||
@ -2739,14 +2739,14 @@ int do_exit(void)
|
||||
if (ISSET(TEMP_OPT))
|
||||
i = 1;
|
||||
else
|
||||
i = do_yesno(0, _("Save modified buffer (ANSWERING \"No\" WILL DESTROY CHANGES) ? "));
|
||||
i = do_yesno(FALSE, _("Save modified buffer (ANSWERING \"No\" WILL DESTROY CHANGES) ? "));
|
||||
|
||||
#ifdef DEBUG
|
||||
dump_buffer(fileage);
|
||||
#endif
|
||||
|
||||
if (i == 1) {
|
||||
if (do_writeout(filename, 1, 0) > 0) {
|
||||
if (do_writeout(TRUE) > 0) {
|
||||
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
if (!close_open_file()) {
|
||||
@ -3528,7 +3528,7 @@ int main(int argc, char *argv[])
|
||||
edit_refresh();
|
||||
reset_cursor();
|
||||
|
||||
while (1) {
|
||||
while (TRUE) {
|
||||
keyhandled = 0;
|
||||
|
||||
if (ISSET(CONSTUPDATE))
|
||||
|
@ -190,7 +190,7 @@ int write_file(const char *name, int tmp, int append, int nonamechange);
|
||||
int write_marked(const char *name, int tmp, int append, int
|
||||
nonamechange);
|
||||
#endif
|
||||
int do_writeout(const char *path, int exiting, int append);
|
||||
int do_writeout(int exiting);
|
||||
int do_writeout_void(void);
|
||||
char *real_dir_from_tilde(const char *buf);
|
||||
#ifndef DISABLE_TABCOMP
|
||||
@ -503,7 +503,7 @@ void center_cursor(void);
|
||||
void edit_refresh(void);
|
||||
void edit_refresh_clearok(void);
|
||||
void edit_update(filestruct *fileptr, topmidnone location);
|
||||
int statusq(int tabs, const shortcut *s, const char *def,
|
||||
int statusq(int allowtabs, const shortcut *s, const char *def,
|
||||
#ifndef NANO_SMALL
|
||||
historyheadtype *history_list,
|
||||
#endif
|
||||
|
27
src/search.c
27
src/search.c
@ -136,12 +136,12 @@ int search_init(int replacing)
|
||||
}
|
||||
|
||||
/* This is now one simple call. It just does a lot. */
|
||||
i = statusq(0, replacing ? replace_list : whereis_list, backupstring,
|
||||
i = statusq(FALSE, replacing ? replace_list : whereis_list,
|
||||
backupstring,
|
||||
#ifndef NANO_SMALL
|
||||
&search_history,
|
||||
#endif
|
||||
"%s%s%s%s%s%s",
|
||||
_("Search"),
|
||||
"%s%s%s%s%s%s", _("Search"),
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
/* This string is just a modifier for the search prompt; no
|
||||
@ -275,7 +275,7 @@ int findnextstr(int can_display_wrap, int wholeword, const filestruct
|
||||
rev_start = fileptr->data + (current_x + 1);
|
||||
|
||||
/* Look for needle in searchstr. */
|
||||
while (1) {
|
||||
while (TRUE) {
|
||||
found = strstrwrapper(fileptr->data, needle, rev_start);
|
||||
|
||||
if (found != NULL && (!wholeword || is_whole_word(found -
|
||||
@ -645,7 +645,7 @@ int do_replace_loop(const char *needle, const filestruct *real_current,
|
||||
curs_set(0);
|
||||
do_replace_highlight(TRUE, exp_word);
|
||||
|
||||
i = do_yesno(1, _("Replace this instance?"));
|
||||
i = do_yesno(TRUE, _("Replace this instance?"));
|
||||
|
||||
do_replace_highlight(FALSE, exp_word);
|
||||
free(exp_word);
|
||||
@ -763,11 +763,11 @@ int do_replace(void)
|
||||
last_replace = mallocstrcpy(last_replace, "");
|
||||
#endif
|
||||
|
||||
i = statusq(0, replace_list_2, last_replace,
|
||||
i = statusq(FALSE, replace_list_2, last_replace,
|
||||
#ifndef NANO_SMALL
|
||||
&replace_history,
|
||||
&replace_history,
|
||||
#endif
|
||||
_("Replace with"));
|
||||
_("Replace with"));
|
||||
|
||||
#ifndef NANO_SMALL
|
||||
/* Add this replace string to the replace history list. i == 0
|
||||
@ -813,11 +813,14 @@ int do_replace(void)
|
||||
int do_gotoline(int line, int save_pos)
|
||||
{
|
||||
if (line <= 0) { /* Ask for it */
|
||||
int st = statusq(FALSE, goto_list, line != 0 ? answer : "",
|
||||
char *ans = mallocstrcpy(NULL, answer);
|
||||
int st = statusq(FALSE, goto_list, line != 0 ? ans : "",
|
||||
#ifndef NANO_SMALL
|
||||
NULL,
|
||||
NULL,
|
||||
#endif
|
||||
_("Enter line number"));
|
||||
_("Enter line number"));
|
||||
|
||||
free(ans);
|
||||
|
||||
/* Cancel, or Enter with blank string. */
|
||||
if (st == -1 || st == -2)
|
||||
@ -918,7 +921,7 @@ int do_find_bracket(void)
|
||||
assert(ISSET(REGEXP_COMPILED));
|
||||
|
||||
search_last_line = 0;
|
||||
while (1) {
|
||||
while (TRUE) {
|
||||
if (findnextstr(FALSE, FALSE, current, current_x, regexp_pat, FALSE) != 0) {
|
||||
/* Found identical bracket. */
|
||||
if (current->data[current_x] == ch_under_cursor)
|
||||
|
11
src/utils.c
11
src/utils.c
@ -293,14 +293,11 @@ void *nrealloc(void *ptr, size_t howmuch)
|
||||
* dest = mallocstrcpy(dest, src); */
|
||||
char *mallocstrcpy(char *dest, const char *src)
|
||||
{
|
||||
if (src == dest)
|
||||
return dest;
|
||||
|
||||
if (dest != NULL)
|
||||
free(dest);
|
||||
|
||||
if (src == NULL)
|
||||
return NULL;
|
||||
src = "";
|
||||
|
||||
if (src != dest)
|
||||
free(dest);
|
||||
|
||||
dest = charalloc(strlen(src) + 1);
|
||||
strcpy(dest, src);
|
||||
|
10
src/winio.c
10
src/winio.c
@ -127,7 +127,7 @@ int get_ignored_kbinput(WINDOW *win)
|
||||
{
|
||||
int kbinput;
|
||||
|
||||
while (1) {
|
||||
while (TRUE) {
|
||||
kbinput = wgetch(win);
|
||||
switch (kbinput) {
|
||||
case ERR:
|
||||
@ -1065,7 +1065,7 @@ void nanoget_repaint(const char *buf, const char *inputbuf, size_t x)
|
||||
wattroff(bottomwin, A_REVERSE);
|
||||
}
|
||||
|
||||
/* Get the input from the kb; this should only be called from
|
||||
/* Get the input from the keyboard; this should only be called from
|
||||
* statusq(). */
|
||||
int nanogetstr(int allowtabs, const char *buf, const char *def,
|
||||
#ifndef NANO_SMALL
|
||||
@ -1671,7 +1671,7 @@ void edit_add(const filestruct *fileptr, const char *converted,
|
||||
* line not followed by an end on this line? */
|
||||
|
||||
start_col = 0;
|
||||
while (1) {
|
||||
while (TRUE) {
|
||||
start_col += startmatch.rm_so;
|
||||
startmatch.rm_eo -= startmatch.rm_so;
|
||||
if (regexec(tmpcolor->end,
|
||||
@ -2011,7 +2011,7 @@ void edit_update(filestruct *fileptr, topmidnone location)
|
||||
* want to put up by default.
|
||||
*
|
||||
* New arg tabs tells whether or not to allow tab completion. */
|
||||
int statusq(int tabs, const shortcut *s, const char *def,
|
||||
int statusq(int allowtabs, const shortcut *s, const char *def,
|
||||
#ifndef NANO_SMALL
|
||||
historyheadtype *which_history,
|
||||
#endif
|
||||
@ -2031,7 +2031,7 @@ int statusq(int tabs, const shortcut *s, const char *def,
|
||||
va_end(ap);
|
||||
foo[COLS - 4] = '\0';
|
||||
|
||||
ret = nanogetstr(tabs, foo, def,
|
||||
ret = nanogetstr(allowtabs, foo, def,
|
||||
#ifndef NANO_SMALL
|
||||
which_history,
|
||||
#endif
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user