]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[console] Restore compatibility with "--key" values in existing scripts 990/head
authorMichael Brown <mcb30@ipxe.org>
Fri, 7 Jul 2023 14:05:39 +0000 (15:05 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 7 Jul 2023 14:14:00 +0000 (15:14 +0100)
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>
src/core/parseopt.c
src/include/ctype.h
src/include/ipxe/keys.h

index 1dbfc7aef81f9b33983299d9261a092f3b15cfe2..cd3b3101ce5dec43399009c82faefc157429bed5 100644 (file)
@@ -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;
 }
 
 /**
index 0d79ecd195a5dc76b5bf600af0afa4ec3677d96b..6fefd5d772c02daa7752413b20e1c269a27691cb 100644 (file)
@@ -9,6 +9,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
  *
index 23356913d983735b043542372631226d49226da9..49e65fa4c0319ecdfcb16b508c13e3e8096d59d3 100644 (file)
@@ -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