diff options
author | Michael Brown <mcb30@ipxe.org> | 2023-07-07 15:05:39 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2023-07-07 15:14:00 +0100 |
commit | c30b71ee9cc2dc2a1d2f225d99f2d70dd73de247 (patch) | |
tree | 57e80a0b4079fdcacfbc1b2082219ed0dafb3a28 | |
parent | f3036fc213b6e6cce0bf5572167b93b9e9959a3a (diff) | |
download | ipxe-c30b71ee9cc2dc2a1d2f225d99f2d70dd73de247.zip ipxe-c30b71ee9cc2dc2a1d2f225d99f2d70dd73de247.tar.gz ipxe-c30b71ee9cc2dc2a1d2f225d99f2d70dd73de247.tar.bz2 |
[console] Restore compatibility with "--key" values in existing scriptskeyvals
Commit 3ef4f7e ("[console] Avoid overlap between special keys and
Unicode characters") renumbered the special key encoding to avoid
collisions with Unicode key values outside the ASCII range. This
change broke backwards compatibility with existing scripts that
specify key values using e.g. "prompt --key" or "menu --key".
Restore compatibility with existing scripts by tweaking the special
key encoding so that the relative key value (i.e. the delta from
KEY_MIN) is numerically equal to the old pre-Unicode key value, and by
modifying parse_key() to accept a relative key value.
Reported-by: Sven Dreyer <sven@dreyer-net.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r-- | src/core/parseopt.c | 15 | ||||
-rw-r--r-- | src/include/ctype.h | 11 | ||||
-rw-r--r-- | src/include/ipxe/keys.h | 8 |
3 files changed, 31 insertions, 3 deletions
diff --git a/src/core/parseopt.c b/src/core/parseopt.c index 1dbfc7a..cd3b310 100644 --- a/src/core/parseopt.c +++ b/src/core/parseopt.c @@ -28,6 +28,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdlib.h> #include <stdio.h> #include <string.h> +#include <ctype.h> #include <errno.h> #include <getopt.h> #include <ipxe/netdevice.h> @@ -35,6 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <ipxe/settings.h> #include <ipxe/params.h> #include <ipxe/timer.h> +#include <ipxe/keys.h> #include <ipxe/parseopt.h> #include <config/branding.h> @@ -213,6 +215,7 @@ int parse_flag ( char *text __unused, int *flag ) { * @ret rc Return status code */ int parse_key ( char *text, unsigned int *key ) { + int rc; /* Interpret single characters as being a literal key character */ if ( text[0] && ! text[1] ) { @@ -221,7 +224,17 @@ int parse_key ( char *text, unsigned int *key ) { } /* Otherwise, interpret as an integer */ - return parse_integer ( text, key ); + if ( ( rc = parse_integer ( text, key ) ) < 0 ) + return rc; + + /* For backwards compatibility with existing scripts, treat + * integers between the ASCII range and special key range as + * being relative special key values. + */ + if ( ( ! isascii ( *key ) ) && ( *key < KEY_MIN ) ) + *key += KEY_MIN; + + return 0; } /** diff --git a/src/include/ctype.h b/src/include/ctype.h index 0d79ecd..6fefd5d 100644 --- a/src/include/ctype.h +++ b/src/include/ctype.h @@ -10,6 +10,17 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** + * Check if character is ASCII + * + * @v character Character + * @ret is_ascii Character is an ASCII character + */ +static inline int isascii ( int character ) { + + return ( character <= '\x7f' ); +} + +/** * Check if character is a decimal digit * * @v character ASCII character diff --git a/src/include/ipxe/keys.h b/src/include/ipxe/keys.h index 2335691..49e65fa 100644 --- a/src/include/ipxe/keys.h +++ b/src/include/ipxe/keys.h @@ -54,6 +54,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * The names are chosen to match those used by curses. The values are * chosen to facilitate easy conversion from a received ANSI escape * sequence to a KEY_XXX constant. + * + * Note that the values are exposed to iPXE commands via parse_key() + * and therefore may not be changed without breaking existing scripts. */ /** @@ -79,7 +82,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * @v terminator ANSI escape sequence terminating character * @ret key Key value */ -#define KEY_ANSI( n, terminator ) ( KEY_MIN + ( (n) << 8 ) + (terminator) ) +#define KEY_ANSI( n, terminator ) \ + ( KEY_MIN + ( ( (n) + 1 ) << 8 ) + (terminator) ) /** * Extract ANSI escape sequence numeric portion @@ -87,7 +91,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * @v key Key value (or relative key value) * @ret n ANSI escape sequence numeric portion, or 0 for none */ -#define KEY_ANSI_N( key ) ( ( (key) >> 8 ) & 0xff ) +#define KEY_ANSI_N( key ) ( ( ( (key) >> 8 ) & 0xff ) - 1 ) /** * Extract ANSI escape sequence terminating character |