commit 908663e8fc371cade9ce5768333a84f1aff10287
parent 1fb820386bf4da675d02fd4758ae90c2fd3fc3ef
Author: Benno Schulenberg <bensberg@justemail.net>
Date: Tue, 27 Dec 2016 12:20:20 +0100
input: discard a verbatim 0x0A or 0x00 byte, depending on the mode
This disallows entering a verbatim ^J (0x0A) when typing text or
search terms, and disallows a verbatim ^@ (0x00) when typing a
filename. Nano beeps when the disallowed code is attempted.
This addresses https://savannah.gnu.org/bugs/?49897.
Diffstat:
4 files changed, 23 insertions(+), 50 deletions(-)
diff --git a/src/nano.c b/src/nano.c
@@ -1824,17 +1824,9 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
#endif
while (i < output_len) {
- /* If control codes are allowed, encode a verbatim null as a newline,
- * and let a verbatim ^J create a whole new line. */
- if (allow_cntrls) {
- if (output[i] == '\0')
- output[i] = '\n';
- else if (output[i] == '\n') {
- do_enter();
- i++;
- continue;
- }
- }
+ /* Encode an embedded NUL byte as 0x0A. */
+ if (output[i] == '\0')
+ output[i] = '\n';
/* Get the next multibyte character. */
char_len = parse_mbchar(output + i, char_buf, NULL);
diff --git a/src/prompt.c b/src/prompt.c
@@ -104,7 +104,7 @@ int do_statusbar_input(bool *ran_func, bool *finished)
if ((have_shortcut || get_key_buffer_len() == 0) && kbinput != NULL) {
/* Inject all characters in the input buffer at once, filtering out
* control characters. */
- do_statusbar_output(kbinput, kbinput_len, TRUE, NULL);
+ do_statusbar_output(kbinput, kbinput_len, TRUE);
/* Empty the input buffer. */
kbinput_len = 0;
@@ -139,18 +139,7 @@ int do_statusbar_input(bool *ran_func, bool *finished)
s->scfunc == do_backspace))
;
else if (s->scfunc == do_verbatim_input) {
- bool got_newline = FALSE;
- /* Whether we got a verbatim ^J. */
-
- do_statusbar_verbatim_input(&got_newline);
-
- /* If we got a verbatim ^J, remove it from the input buffer,
- * fake a press of Enter, and indicate that we're done. */
- if (got_newline) {
- get_input(NULL, 1);
- input = KEY_ENTER;
- *finished = TRUE;
- }
+ do_statusbar_verbatim_input();
} else if (s->scfunc == do_cut_text_void)
do_statusbar_cut_text();
else if (s->scfunc == do_delete)
@@ -202,11 +191,10 @@ int do_statusbar_mouse(void)
}
#endif
-/* The user typed input_len multibyte characters. Add them to the
- * statusbar prompt, setting got_newline to TRUE if we got a verbatim ^J,
- * and filtering out ASCII control characters if filtering is TRUE. */
+/* The user typed input_len multibyte characters. Add them to the answer,
+ * filtering out ASCII control characters if filtering is TRUE. */
void do_statusbar_output(int *the_input, size_t input_len,
- bool filtering, bool *got_newline)
+ bool filtering)
{
char *output = charalloc(input_len + 1);
char *char_buf = charalloc(mb_cur_max());
@@ -220,18 +208,9 @@ void do_statusbar_output(int *the_input, size_t input_len,
i = 0;
while (i < input_len) {
- /* When not filtering, convert nulls and stop at a newline. */
- if (!filtering) {
- if (output[i] == '\0')
- output[i] = '\n';
- else if (output[i] == '\n') {
- /* Put back the rest of the characters for reparsing,
- * indicate that we got a ^J and get out. */
- unparse_kbinput(output + i, input_len - i);
- *got_newline = TRUE;
- return;
- }
- }
+ /* Encode any NUL byte as 0x0A. */
+ if (output[i] == '\0')
+ output[i] = '\n';
/* Interpret the next multibyte character. */
char_len = parse_mbchar(output + i, char_buf, NULL);
@@ -369,19 +348,15 @@ void do_statusbar_prev_word(void)
}
#endif /* !NANO_TINY */
-/* Get verbatim input, setting got_newline to TRUE if we get a ^J as
- * part of the verbatim input. */
-void do_statusbar_verbatim_input(bool *got_newline)
+/* Get verbatim input and inject it into the answer, without filtering. */
+void do_statusbar_verbatim_input(void)
{
int *kbinput;
size_t kbinput_len;
- /* Read in all the verbatim characters. */
kbinput = get_verbatim_kbinput(bottomwin, &kbinput_len);
- /* Display all the verbatim characters at once, not filtering out
- * control characters. */
- do_statusbar_output(kbinput, kbinput_len, FALSE, got_newline);
+ do_statusbar_output(kbinput, kbinput_len, FALSE);
}
/* Return the zero-based column position of the cursor in the answer. */
diff --git a/src/proto.h b/src/proto.h
@@ -485,7 +485,7 @@ void do_output(char *output, size_t output_len, bool allow_cntrls);
int do_statusbar_mouse(void);
#endif
void do_statusbar_output(int *the_input, size_t input_len,
- bool filtering, bool *got_newline);
+ bool filtering);
void do_statusbar_home(void);
void do_statusbar_end(void);
void do_statusbar_left(void);
@@ -497,7 +497,7 @@ void do_statusbar_cut_text(void);
void do_statusbar_prev_word(void);
void do_statusbar_next_word(void);
#endif
-void do_statusbar_verbatim_input(bool *got_newline);
+void do_statusbar_verbatim_input(void);
size_t statusbar_xplustabs(void);
size_t get_statusbar_page_start(size_t start_col, size_t column);
void reinit_statusbar_x(void);
diff --git a/src/winio.c b/src/winio.c
@@ -1442,9 +1442,15 @@ int *get_verbatim_kbinput(WINDOW *win, size_t *kbinput_len)
if (!ISSET(REBIND_KEYPAD))
keypad(win, FALSE);
- /* Read in a stream of characters and interpret it if possible. */
+ /* Read in one keycode, or one or two escapes. */
retval = parse_verbatim_kbinput(win, kbinput_len);
+ /* If the code is invalid in the current mode, discard it. */
+ if ((*retval == '\n' && as_an_at) || (*retval == '\0' && !as_an_at)) {
+ *kbinput_len = 0;
+ beep();
+ }
+
/* Turn flow control characters back on if necessary and turn the
* keypad back on if necessary now that we're done. */
if (ISSET(PRESERVE))