shared/shell: Fix not handling prompt with color properly
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 15 Oct 2024 20:40:58 +0000 (16:40 -0400)
committerWootak Jung <wootak.jung@samsung.com>
Thu, 20 Feb 2025 07:43:23 +0000 (16:43 +0900)
Colors use escape sequence that needs to be enveloped with
RL_PROMPT_START_IGNORE (\001) and RL_PROMPT_END_IGNORE (\002) in order
for readline to properly calculate the prompt length.

Fixes: https://github.com/bluez/bluez/issues/965
Signed-off-by: Anuj Jain <anuj01.jain@samsung.com>
client/main.c
client/mgmt.c
src/shared/shell.c
src/shared/shell.h
tools/bluetooth-player.c
tools/btpclientctl.c
tools/mesh-cfgclient.c
tools/mesh-gatt/util.c
tools/mesh/util.c
tools/meshctl.c
tools/obexctl.c

index 6c128ef276ade7c7809f13e2e17fe24410842bd3..6195c5a0834bef7e1fa433a2a96f06df742d0db3 100644 (file)
@@ -42,7 +42,7 @@
 #define COLORED_CHG    COLOR_YELLOW "CHG" COLOR_OFF
 #define COLORED_DEL    COLOR_RED "DEL" COLOR_OFF
 
-#define PROMPT_ON      COLOR_BLUE "[bluetooth]" COLOR_OFF "# "
+#define PROMPT_ON      "[bluetooth]# "
 #define PROMPT_OFF     "Waiting to connect to bluetoothd..."
 
 static DBusConnection *dbus_conn;
@@ -105,14 +105,14 @@ static void setup_standard_input(void)
 
 static void connect_handler(DBusConnection *connection, void *user_data)
 {
-       bt_shell_set_prompt(PROMPT_ON);
+       bt_shell_set_prompt(PROMPT_ON, COLOR_BLUE);
 }
 
 static void disconnect_handler(DBusConnection *connection, void *user_data)
 {
        bt_shell_detach();
 
-       bt_shell_set_prompt(PROMPT_OFF);
+       bt_shell_set_prompt(PROMPT_OFF, NULL);
 
        g_list_free_full(ctrl_list, proxy_leak);
        g_list_free_full(battery_proxies, proxy_leak);
@@ -332,12 +332,12 @@ static void set_default_device(GDBusProxy *proxy, const char *attribute)
        path = g_dbus_proxy_get_path(proxy);
 
        dbus_message_iter_get_basic(&iter, &desc);
-       desc = g_strdup_printf(COLOR_BLUE "[%s%s%s]" COLOR_OFF "# ", desc,
+       desc = g_strdup_printf("[%s%s%s]# ", desc,
                                attribute ? ":" : "",
                                attribute ? attribute + strlen(path) : "");
 
 done:
-       bt_shell_set_prompt(desc ? desc : PROMPT_ON);
+       bt_shell_set_prompt(desc ? desc : PROMPT_ON, COLOR_BLUE);
        g_free(desc);
 }
 
@@ -2105,9 +2105,9 @@ static void set_default_local_attribute(char *attr)
        default_local_attr = attr;
        default_attr = NULL;
 
-       desc = g_strdup_printf(COLOR_BLUE "[%s]" COLOR_OFF "# ", attr);
+       desc = g_strdup_printf("[%s]# ", attr);
 
-       bt_shell_set_prompt(desc);
+       bt_shell_set_prompt(desc, COLOR_BLUE);
        g_free(desc);
 }
 
@@ -3193,7 +3193,7 @@ int main(int argc, char *argv[])
        bt_shell_add_submenu(&advertise_monitor_menu);
        bt_shell_add_submenu(&scan_menu);
        bt_shell_add_submenu(&gatt_menu);
-       bt_shell_set_prompt(PROMPT_OFF);
+       bt_shell_set_prompt(PROMPT_OFF, NULL);
 
        if (agent_option)
                auto_register_agent = g_strdup(agent_option);
index 52d61868b12bf5a066d4574efb1c52d0284df23b..590d41d57a6dcaa0628ffb84b0ed9a0aba734200 100644 (file)
@@ -77,13 +77,11 @@ static void update_prompt(uint16_t index)
        char str[32];
 
        if (index == MGMT_INDEX_NONE)
-               snprintf(str, sizeof(str), "%s# ",
-                                       COLOR_BLUE "[mgmt]" COLOR_OFF);
+               snprintf(str, sizeof(str), "[mgmt]# ");
        else
-               snprintf(str, sizeof(str),
-                               COLOR_BLUE "[hci%u]" COLOR_OFF "# ", index);
+               snprintf(str, sizeof(str), "[hci%u]# ", index);
 
-       bt_shell_set_prompt(str);
+       bt_shell_set_prompt(str, COLOR_BLUE);
 }
 
 void mgmt_set_index(const char *arg)
@@ -859,7 +857,7 @@ static void prompt_input(const char *input, void *user_data)
                                                &prompt.addr);
                } else {
                        mgmt_confirm_neg_reply(prompt.index, &prompt.addr);
-                       bt_shell_set_prompt(PROMPT_ON);
+                       bt_shell_set_prompt(PROMPT_ON, COLOR_BLUE);
                }
                break;
        }
index f1505a84e2cf7715cf2d5bb86acd596d52f2417d..a4a4611ded6f6e5b43864c055026e46f6381ba2c 100644 (file)
@@ -749,15 +749,13 @@ void bt_shell_echo(const char *fmt, ...)
 
        va_start(args, fmt);
        ret = vasprintf(&str, fmt, args);
-       if (ret >= 0)
-               ret = asprintf(&str, COLOR_HIGHLIGHT "%s " COLOR_OFF "#", str);
        va_end(args);
 
        if (ret < 0)
                return;
 
        rl_save_prompt();
-       bt_shell_set_prompt(str);
+       bt_shell_set_prompt(str, COLOR_HIGHLIGHT);
        rl_restore_prompt();
 }
 
@@ -822,7 +820,7 @@ static void prompt_input(const char *str, bt_shell_prompt_input_func func,
        data.saved_user_data = user_data;
 
        rl_save_prompt();
-       bt_shell_set_prompt(str);
+       bt_shell_set_prompt(str, COLOR_HIGHLIGHT);
 }
 
 void bt_shell_prompt_input(const char *label, const char *msg,
@@ -1573,14 +1571,19 @@ bool bt_shell_add_submenu(const struct bt_shell_menu *menu)
        return true;
 }
 
-void bt_shell_set_prompt(const char *string)
+void bt_shell_set_prompt(const char *string, const char *color)
 {
        char *prompt;
 
        if (!data.init || data.mode)
                return;
 
-       if (asprintf(&prompt, "\001%s\002", string) < 0) {
+       /* Envelope color within RL_PROMPT_START_IGNORE (\001) and
+        * RL_PROMPT_END_IGNORE (\002) so readline can properly calculate the
+        * prompt length.
+        */
+       if (!color || asprintf(&prompt, "\001%s\002%s\001%s\002", color, string,
+                               COLOR_OFF) < 0) {
                rl_set_prompt(string);
        } else {
                rl_set_prompt(prompt);
index b03250cac80fd39796880aaa55a404792d70e1ac..e431db9f5821181a295dd26421b52f29f6887bb4 100644 (file)
@@ -66,7 +66,7 @@ bool bt_shell_add_submenu(const struct bt_shell_menu *menu);
 
 bool bt_shell_remove_submenu(const struct bt_shell_menu *menu);
 
-void bt_shell_set_prompt(const char *string);
+void bt_shell_set_prompt(const char *string, const char *color);
 
 void bt_shell_printf(const char *fmt,
                                ...) __attribute__((format(printf, 1, 2)));
index 0975754f411dce24908fc24e4188e5cef243e0f5..be73631cd544bf3588d3007e865f69cf7f39740b 100755 (executable)
 #include "src/shared/shell.h"
 #include "client/player.h"
 
-#define PROMPT_ON      COLOR_BLUE "[bluetooth]" COLOR_OFF "# "
-#define PROMPT_OFF     "[bluetooth]# "
+#define PROMPT "[bluetooth]# "
 
 static DBusConnection *dbus_conn;
 
 static void connect_handler(DBusConnection *connection, void *user_data)
 {
        bt_shell_attach(fileno(stdin));
-       bt_shell_set_prompt(PROMPT_ON);
+       bt_shell_set_prompt(PROMPT, COLOR_BLUE);
 }
 
 static void disconnect_handler(DBusConnection *connection, void *user_data)
 {
        bt_shell_detach();
-       bt_shell_set_prompt(PROMPT_OFF);
+       bt_shell_set_prompt(PROMPT, NULL);
 }
 
 int main(int argc, char *argv[])
@@ -55,7 +54,7 @@ int main(int argc, char *argv[])
        int status;
 
        bt_shell_init(argc, argv, NULL);
-       bt_shell_set_prompt(PROMPT_OFF);
+       bt_shell_set_prompt(PROMPT, NULL);
 
        dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
 
index d162298c4ba82e105b92bcd6ec7cf9f30c04290b..a055e618859c3c547a61b33e15cf4a750e934fdd 100644 (file)
@@ -2353,7 +2353,7 @@ int main(int argc, char *argv[])
        mainloop_add_fd(btpclientctl->server_fd, EPOLLIN, server_callback,
                        btpclientctl, NULL);
 
-       bt_shell_set_prompt(PROMPT_ON);
+       bt_shell_set_prompt(PROMPT_ON, COLOR_BLUE);
 
        status = bt_shell_run();
 
index 7a2989d9a9bae3234a8991a749bc9036d75f5d34..96e58d010bc60d864c7c40abbfbb1eb91edcc094 100644 (file)
@@ -40,7 +40,7 @@
 #include "tools/mesh/model.h"
 #include "tools/mesh/remote.h"
 
-#define PROMPT_ON      COLOR_BLUE "[mesh-cfgclient]" COLOR_OFF "# "
+#define PROMPT_ON      "[mesh-cfgclient]# "
 #define PROMPT_OFF     "Waiting to connect to bluetooth-meshd..."
 
 #define CFG_SRV_MODEL  0x0000
@@ -2484,7 +2484,7 @@ static void client_ready(struct l_dbus_client *client, void *user_data)
 static void client_connected(struct l_dbus *dbus, void *user_data)
 {
        bt_shell_printf("D-Bus client connected\n");
-       bt_shell_set_prompt(PROMPT_ON);
+       bt_shell_set_prompt(PROMPT_ON, COLOR_BLUE);
 }
 
 static void client_disconnected(struct l_dbus *dbus, void *user_data)
@@ -2644,7 +2644,7 @@ int main(int argc, char *argv[])
                return EXIT_FAILURE;
        }
 
-       bt_shell_set_prompt(PROMPT_OFF);
+       bt_shell_set_prompt(PROMPT_OFF, NULL);
 
        dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
 
index eb8b8eb29467571bc2526cd8b1f5012312efc622..58f240a7748e2d006ca6dbb73d4c75d61bb82539 100644 (file)
@@ -29,9 +29,9 @@ void set_menu_prompt(const char *name, const char *id)
 {
        char *prompt;
 
-       prompt = g_strdup_printf(COLOR_BLUE "[%s%s%s]" COLOR_OFF "# ", name,
+       prompt = g_strdup_printf("[%s%s%s]# ", name,
                                        id ? ": Target = " : "", id ? id : "");
-       bt_shell_set_prompt(prompt);
+       bt_shell_set_prompt(prompt, COLOR_BLUE);
        g_free(prompt);
 }
 
index dea496dbeb8c3163e1351de88f7b1def7833bb18..310aae0c63e6bd7a729eabd3b61d7aae470b3753 100644 (file)
@@ -28,9 +28,9 @@ void set_menu_prompt(const char *name, const char *id)
 {
        char *prompt;
 
-       prompt = l_strdup_printf(COLOR_BLUE "[%s%s%s]" COLOR_OFF "# ", name,
+       prompt = l_strdup_printf("[%s%s%s]# ", name,
                                        id ? ": Target = " : "", id ? id : "");
-       bt_shell_set_prompt(prompt);
+       bt_shell_set_prompt(prompt, COLOR_BLUE);
        l_free(prompt);
 }
 
index 4dcc1ad6ee966e9779864675460ba00e0e3be940..8ccd7708189ebd8d9d5290d5228ceffcdbd407d2 100644 (file)
@@ -53,7 +53,7 @@
 #define COLORED_CHG    COLOR_YELLOW "CHG" COLOR_OFF
 #define COLORED_DEL    COLOR_RED "DEL" COLOR_OFF
 
-#define PROMPT_ON      COLOR_BLUE "[meshctl]" COLOR_OFF "# "
+#define PROMPT_ON      "[meshctl]# "
 #define PROMPT_OFF     "Waiting to connect to bluetoothd..."
 
 #define MESH_PROV_DATA_IN_UUID_STR     "00002adb-0000-1000-8000-00805f9b34fb"
@@ -171,14 +171,14 @@ static void proxy_leak(gpointer data)
 
 static void connect_handler(DBusConnection *connection, void *user_data)
 {
-       bt_shell_set_prompt(PROMPT_ON);
+       bt_shell_set_prompt(PROMPT_ON, COLOR_BLUE);
 }
 
 static void disconnect_handler(DBusConnection *connection, void *user_data)
 {
        bt_shell_detach();
 
-       bt_shell_set_prompt(PROMPT_OFF);
+       bt_shell_set_prompt(PROMPT_OFF, NULL);
 
        g_list_free_full(ctrl_list, proxy_leak);
        ctrl_list = NULL;
@@ -607,7 +607,7 @@ static void set_connected_device(GDBusProxy *proxy)
                                mesh ? buf : "");
 
 done:
-       bt_shell_set_prompt(desc ? desc : PROMPT_ON);
+       bt_shell_set_prompt(desc ? desc : PROMPT_ON, COLOR_BLUE);
        g_free(desc);
 
        /* If disconnected, return to main menu */
@@ -1900,7 +1900,7 @@ int main(int argc, char *argv[])
 
        bt_shell_init(argc, argv, &opt);
        bt_shell_set_menu(&main_menu);
-       bt_shell_set_prompt(PROMPT_OFF);
+       bt_shell_set_prompt(PROMPT_OFF, NULL);
 
        if (!config_dir) {
                char *home;
index 355bc950ec132e4db0e8879b526e511c34d63864..a73c07ec59d8ce26dc5e6925034fe1714e06d7db 100755 (executable)
@@ -32,8 +32,7 @@
 #define COLORED_CHG    COLOR_YELLOW "CHG" COLOR_OFF
 #define COLORED_DEL    COLOR_RED "DEL" COLOR_OFF
 
-#define PROMPT_ON      COLOR_BLUE "[obex]" COLOR_OFF "# "
-#define PROMPT_OFF     "[obex]# "
+#define PROMPT         "[obex]# "
 
 #define OBEX_SESSION_INTERFACE "org.bluez.obex.Session1"
 #define OBEX_TRANSFER_INTERFACE "org.bluez.obex.Transfer1"
@@ -63,13 +62,13 @@ struct transfer_data {
 static void connect_handler(DBusConnection *connection, void *user_data)
 {
        bt_shell_attach(fileno(stdin));
-       bt_shell_set_prompt(PROMPT_ON);
+       bt_shell_set_prompt(PROMPT, COLOR_BLUE);
 }
 
 static void disconnect_handler(DBusConnection *connection, void *user_data)
 {
        bt_shell_detach();
-       bt_shell_set_prompt(PROMPT_OFF);
+       bt_shell_set_prompt(PROMPT, NULL);
 }
 
 static char *generic_generator(const char *text, int state, GList *source)
@@ -403,15 +402,15 @@ static void set_default_session(GDBusProxy *proxy)
        default_session = proxy;
 
        if (!g_dbus_proxy_get_property(proxy, "Destination", &iter)) {
-               desc = g_strdup(PROMPT_ON);
+               desc = g_strdup(PROMPT);
                goto done;
        }
 
        dbus_message_iter_get_basic(&iter, &desc);
-       desc = g_strdup_printf(COLOR_BLUE "[%s]" COLOR_OFF "# ", desc);
+       desc = g_strdup_printf("[%s] #", desc);
 
 done:
-       bt_shell_set_prompt(desc);
+       bt_shell_set_prompt(desc, COLOR_BLUE);
        g_free(desc);
 }
 
@@ -2151,7 +2150,7 @@ int main(int argc, char *argv[])
 
        bt_shell_init(argc, argv, NULL);
        bt_shell_set_menu(&main_menu);
-       bt_shell_set_prompt(PROMPT_OFF);
+       bt_shell_set_prompt(PROMPT, NULL);
 
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);