tweaks: use an auxiliary variable to avoid dereferences of 'shortcut'

This is especially meant to avoid dereferences of 'shortcut' after its
linked function has been executed, because in an upcoming commit this
execution may have freed the shortcut's structure.

(For symmetry, make the same change also in do_statusbar_input(), even
though it is not needed there.)

This addresses one part of https://savannah.gnu.org/bugs/?62899.
This commit is contained in:
Benno Schulenberg 2022-08-15 09:09:28 +02:00
parent 433dd92196
commit 10b4d0c8ad
2 changed files with 38 additions and 36 deletions

View File

@ -1522,6 +1522,7 @@ void process_a_keystroke(void)
#endif
static bool give_a_hint = TRUE;
const keystruct *shortcut;
functionptrtype function;
/* Read in a keystroke, and show the cursor while waiting. */
input = get_kbinput(midwin, VISIBLE);
@ -1545,9 +1546,10 @@ void process_a_keystroke(void)
/* Check for a shortcut in the main list. */
shortcut = get_shortcut(&input);
function = (shortcut ? shortcut->func : NULL);
/* If not a command, discard anything that is not a normal character byte. */
if (shortcut == NULL) {
if (!function) {
if (input < 0x20 || input > 0xFF || meta_key)
unbound_key(input);
else if (ISSET(VIEW_MODE))
@ -1567,7 +1569,7 @@ void process_a_keystroke(void)
/* If we have a command, or if there aren't any other key codes waiting,
* it's time to insert the gathered bytes into the edit buffer. */
if ((shortcut || waiting_keycodes() == 0) && puddle != NULL) {
if ((function || waiting_keycodes() == 0) && puddle != NULL) {
puddle[depth] = '\0';
inject(puddle, depth);
@ -1577,7 +1579,7 @@ void process_a_keystroke(void)
depth = 0;
}
if (shortcut == NULL) {
if (!function) {
pletion_line = NULL;
keep_cutbuffer = FALSE;
return;
@ -1596,25 +1598,25 @@ void process_a_keystroke(void)
give_a_hint = FALSE;
/* When not cutting or copying text, drop the cutbuffer the next time. */
if (shortcut->func != cut_text) {
if (function != cut_text) {
#ifndef NANO_TINY
if (shortcut->func != copy_text && shortcut->func != zap_text)
if (function != copy_text && function != zap_text)
#endif
keep_cutbuffer = FALSE;
}
#ifdef ENABLE_WORDCOMPLETION
if (shortcut->func != complete_a_word)
if (function != complete_a_word)
pletion_line = NULL;
#endif
#ifdef ENABLE_NANORC
if (shortcut->func == (functionptrtype)implant) {
if (function == (functionptrtype)implant) {
implant(shortcut->expansion);
return;
}
#endif
#ifndef NANO_TINY
if (shortcut->func == do_toggle) {
if (function == do_toggle) {
toggle_this(shortcut->toggle);
if (shortcut->toggle == CUT_FROM_CURSOR)
keep_cutbuffer = FALSE;
@ -1633,7 +1635,7 @@ void process_a_keystroke(void)
#endif
/* Execute the function of the shortcut. */
shortcut->func();
function();
#ifndef NANO_TINY
/* When the marked region changes without Shift being held,
@ -1643,7 +1645,7 @@ void process_a_keystroke(void)
if (!shift_held && openfile->softmark &&
(openfile->current != was_current ||
openfile->current_x != was_x ||
wanted_to_move(shortcut->func))) {
wanted_to_move(function))) {
openfile->mark = NULL;
refresh_needed = TRUE;
} else if (openfile->current != was_current)
@ -1654,8 +1656,7 @@ void process_a_keystroke(void)
if (!refresh_needed && !okay_for_view(shortcut))
check_the_multis(openfile->current);
#endif
if (!refresh_needed && (shortcut->func == do_delete ||
shortcut->func == do_backspace))
if (!refresh_needed && (function == do_delete || function == do_backspace))
update_line(openfile->current, openfile->current_x);
#ifndef NANO_TINY

View File

@ -262,6 +262,7 @@ int do_statusbar_input(bool *finished)
static size_t depth = 0;
/* The length of the input buffer. */
const keystruct *shortcut;
functionptrtype function;
*finished = FALSE;
@ -286,11 +287,12 @@ int do_statusbar_input(bool *finished)
/* Check for a shortcut in the current list. */
shortcut = get_shortcut(&input);
function = (shortcut ? shortcut->func : NULL);
/* If not a command, discard anything that is not a normal character byte.
* Apart from that, only accept input when not in restricted mode, or when
* not at the "Write File" prompt, or when there is no filename yet. */
if (shortcut == NULL) {
if (!function) {
if (input < 0x20 || input > 0xFF || meta_key)
beep();
else if (!ISSET(RESTRICTED) || currmenu != MWRITEFILE ||
@ -303,7 +305,7 @@ int do_statusbar_input(bool *finished)
/* If we got a shortcut, or if there aren't any other keystrokes waiting,
* it's time to insert all characters in the input buffer (if not empty)
* into the answer, and then clear the input buffer. */
if ((shortcut || waiting_keycodes() == 0) && puddle != NULL) {
if ((function || waiting_keycodes() == 0) && puddle != NULL) {
puddle[depth] = '\0';
inject_into_answer(puddle, depth);
@ -314,60 +316,59 @@ int do_statusbar_input(bool *finished)
}
if (shortcut) {
if (shortcut->func == do_tab || shortcut->func == do_enter)
if (function == do_tab || function == do_enter)
;
#ifdef ENABLE_HISTORIES
else if (shortcut->func == get_older_item ||
shortcut->func == get_newer_item)
else if (function == get_older_item || function == get_newer_item)
;
#endif
else if (shortcut->func == do_left)
else if (function == do_left)
do_statusbar_left();
else if (shortcut->func == do_right)
else if (function == do_right)
do_statusbar_right();
#ifndef NANO_TINY
else if (shortcut->func == to_prev_word)
else if (function == to_prev_word)
do_statusbar_prev_word();
else if (shortcut->func == to_next_word)
else if (function == to_next_word)
do_statusbar_next_word();
#endif
else if (shortcut->func == do_home)
else if (function == do_home)
do_statusbar_home();
else if (shortcut->func == do_end)
else if (function == do_end)
do_statusbar_end();
/* When in restricted mode at the "Write File" prompt and the
* filename isn't blank, disallow any input and deletion. */
else if (ISSET(RESTRICTED) && currmenu == MWRITEFILE &&
openfile->filename[0] != '\0' &&
(shortcut->func == do_verbatim_input ||
shortcut->func == do_delete ||
shortcut->func == do_backspace ||
shortcut->func == cut_text ||
shortcut->func == paste_text))
(function == do_verbatim_input ||
function == do_delete ||
function == do_backspace ||
function == cut_text ||
function == paste_text))
;
#ifdef ENABLE_NANORC
else if (shortcut->func == (functionptrtype)implant)
else if (function == (functionptrtype)implant)
implant(shortcut->expansion);
#endif
else if (shortcut->func == do_verbatim_input)
else if (function == do_verbatim_input)
do_statusbar_verbatim_input();
else if (shortcut->func == do_delete)
else if (function == do_delete)
do_statusbar_delete();
else if (shortcut->func == do_backspace)
else if (function == do_backspace)
do_statusbar_backspace();
else if (shortcut->func == cut_text)
else if (function == cut_text)
lop_the_answer();
#ifndef NANO_TINY
else if (shortcut->func == copy_text)
else if (function == copy_text)
copy_the_answer();
else if (shortcut->func == paste_text) {
else if (function == paste_text) {
if (cutbuffer != NULL)
paste_into_answer();
}
#endif
else {
/* Handle some other shortcut, and indicate that we're done. */
shortcut->func();
function();
*finished = TRUE;
}
}