Commit 3401c0d95ffb9a9a57093ee002d24d014ffed4f8
1 parent
0fead125
Refactor and fix do_sendkey (Jan Kiszka).
Looking at the sendkey implementation, planning to enhance it with a hold time argument, I found some potential out-of-bound access and not very readable code. Here is a fix for the former and a (subjective) improvement of the latter. Signed-off-by: Jan Kiszka <jan.kiszka@web.de> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4657 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
28 additions
and
23 deletions
monitor.c
... | ... | @@ -919,33 +919,38 @@ static int get_keycode(const char *key) |
919 | 919 | return -1; |
920 | 920 | } |
921 | 921 | |
922 | -static void do_send_key(const char *string) | |
922 | +static void do_sendkey(const char *string) | |
923 | 923 | { |
924 | - char keybuf[16], *q; | |
925 | 924 | uint8_t keycodes[16]; |
926 | - const char *p; | |
927 | - int nb_keycodes, keycode, i; | |
928 | - | |
929 | - nb_keycodes = 0; | |
930 | - p = string; | |
931 | - while (*p != '\0') { | |
932 | - q = keybuf; | |
933 | - while (*p != '\0' && *p != '-') { | |
934 | - if ((q - keybuf) < sizeof(keybuf) - 1) { | |
935 | - *q++ = *p; | |
925 | + int nb_keycodes = 0; | |
926 | + char keyname_buf[16]; | |
927 | + char *separator; | |
928 | + int keyname_len, keycode, i; | |
929 | + | |
930 | + while (1) { | |
931 | + separator = strchr(string, '-'); | |
932 | + keyname_len = separator ? separator - string : strlen(string); | |
933 | + if (keyname_len > 0) { | |
934 | + pstrcpy(keyname_buf, sizeof(keyname_buf), string); | |
935 | + if (keyname_len > sizeof(keyname_buf) - 1) { | |
936 | + term_printf("invalid key: '%s...'\n", keyname_buf); | |
937 | + return; | |
936 | 938 | } |
937 | - p++; | |
938 | - } | |
939 | - *q = '\0'; | |
940 | - keycode = get_keycode(keybuf); | |
941 | - if (keycode < 0) { | |
942 | - term_printf("unknown key: '%s'\n", keybuf); | |
943 | - return; | |
939 | + if (nb_keycodes == sizeof(keycodes)) { | |
940 | + term_printf("too many keys\n"); | |
941 | + return; | |
942 | + } | |
943 | + keyname_buf[keyname_len] = 0; | |
944 | + keycode = get_keycode(keyname_buf); | |
945 | + if (keycode < 0) { | |
946 | + term_printf("unknown key: '%s'\n", keyname_buf); | |
947 | + return; | |
948 | + } | |
949 | + keycodes[nb_keycodes++] = keycode; | |
944 | 950 | } |
945 | - keycodes[nb_keycodes++] = keycode; | |
946 | - if (*p == '\0') | |
951 | + if (!separator) | |
947 | 952 | break; |
948 | - p++; | |
953 | + string = separator + 1; | |
949 | 954 | } |
950 | 955 | /* key down events */ |
951 | 956 | for(i = 0; i < nb_keycodes; i++) { |
... | ... | @@ -1347,7 +1352,7 @@ static term_cmd_t term_cmds[] = { |
1347 | 1352 | { "i", "/ii.", do_ioport_read, |
1348 | 1353 | "/fmt addr", "I/O port read" }, |
1349 | 1354 | |
1350 | - { "sendkey", "s", do_send_key, | |
1355 | + { "sendkey", "s", do_sendkey, | |
1351 | 1356 | "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" }, |
1352 | 1357 | { "system_reset", "", do_system_reset, |
1353 | 1358 | "", "reset the system" }, | ... | ... |