microsoft / microsoft/terminal

Terminal sends global key event with invalid VK code

Open
#15,218 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Area-Input Issue-Bug Product-Terminal
Dominant language
C++
Stars
105k
Forks
9.6k
Avg merge
3d 17h
Merged PRs (30d)
29

Description

### Windows Terminal version

1.16.10261.0

### Windows build number

10.0.19044.1766

### Other Software

Snippet from a larger piece of software that was crashing on an assert:

```cpp
#include
#include

// Implemented following the guidelines here:
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-kbdllhookstruct

LRESULT CALLBACK key_hook(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0) {
return CallNextHookEx(0, nCode, wParam, lParam);
}

auto& event_info = *(PKBDLLHOOKSTRUCT)lParam;

// This assertion is triggering:
// assert(event_info.vkCode > 0 && event_info.vkCode < 255);

if (!(event_info.vkCode > 0 && event_info.vkCode < 255)) {
std::cerr << "!!! event_info.vkCode out of range !!!\n";
std::cerr << "event_info dump:\n";
std::cerr << " .time = " << event_info.time << "\n";
std::cerr << " .flags = " << event_info.flags << "\n";
std::cerr << " .scanCode = " << event_info.scanCode << "\n";
std::cerr << " .vkCode = " << event_info.vkCode << "\n";
std::cerr << " .dwExtraInfo = " << event_info.dwExtraInfo << "\n";
std::cerr << "wParam = " << wParam << "\n";
}

return CallNextHookEx(0, nCode, wParam, lParam);
}

int main() {
HHOOK hk = SetWindowsHookEx(WH_KEYBOARD_LL, key_hook, 0, 0);
if (!hk) {
std::cerr << "SetWindowsHookEx failed\n";
return 1;
}
for (;;) {
MSG msg;
BOOL status = GetMessage(&msg, 0, 0, 0);
if (status == -1) {
std::cerr << "fatal: GetMessage() returned -1" << std::endl;
break;
}
else if (msg.message == WM_QUIT) {
break;
}
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
UnhookWindowsHookEx(hk);
return 0;
}
```

### Steps to reproduce

1. Compile above: `cl /c /EHsc hook.cpp && link hook.obj user32.lib`
2. Run program as administrator so it can install the hook
3. Open terminal
4. Drag the single terminal tab outside of the window so it displays a cancel icon
5. Rarely, the program will print events like:

```
!!! event_info.vkCode out of range !!!
event_info dump:
.time = 196871921
.flags = 18
.scanCode = 0
.vkCode = 0
.dwExtraInfo = 0
wParam = 256
!!! event_info.vkCode out of range !!!
event_info dump:
.time = 197479750
.flags = 18
.scanCode = 0
.vkCode = 0
.dwExtraInfo = 0
wParam = 256
```

I haven't worked out how to reproduce this reliably yet. It seems to mostly occur after leaving terminal minimized for a while in the background then coming back to it then trying to drag a tab.

### Expected Behavior

MSDN states here: "`vkCode` ... must be a value in the range 1 to 254."
https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-kbdllhookstruct?redirectedfrom=MSDN

Zero is also not listed on the VK code table here:
https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes

Based on this documentation, I would either expect an event to not be caught, or for an event to be caught that has a non-zero `vkCode`.

### Actual Behavior

A key event with a VK code of zero is caught.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the hook.cpp reproduction using SetWindowsHookEx and WH_KEYBOARD_LL, then investigate the Windows Terminal path exercised while dragging a tab outside the window. The issue provides no repository file or test entry point; done would mean explaining and correcting the zero vkCode event, with coverage for the reported scenario if the behavior can be reproduced.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
cli, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.