Fix a ConPTY startup hang with 0-param DA1 responses (#18681)

Since `WaitForDA1` would wait until `_deviceAttributes` is non-zero,
we must ensure it's actually non-zero at the end of this handler,
even if there are no parameters.

## Validation Steps Performed
* Mod the Terminal DA1 to be `\x1b[?6c`. No hang 
* Mod the Terminal DA1 to be `\x1b[?61c`. No hang 
This commit is contained in:
Leonard Hecker 2025-03-13 00:29:36 +01:00 committed by GitHub
parent 2693210ead
commit 32ae00f71a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 17 additions and 6 deletions

View File

@ -471,15 +471,22 @@ bool InputStateMachineEngine::ActionCsiDispatch(const VTID id, const VTParameter
// We catch it here and store the information for later retrieval.
if (_deviceAttributes.load(std::memory_order_relaxed) == 0)
{
til::enumset<DeviceAttribute, uint64_t> attributes;
til::enumset<DeviceAttribute, uint64_t> attributes{ DeviceAttribute::__some__ };
// The first parameter denotes the conformance level.
if (parameters.at(0).value() >= 61)
const auto len = parameters.size();
if (len >= 2 && parameters.at(0).value() >= 61)
{
parameters.subspan(1).for_each([&](auto p) {
attributes.set(static_cast<DeviceAttribute>(p));
return true;
});
// NOTE: VTParameters::for_each will replace empty spans with a single default value.
// This means we could not distinguish between no parameters and a single default parameter.
for (size_t i = 1; i < len; i++)
{
const auto value = parameters.at(i).value();
if (value > 0 && value < 64)
{
attributes.set(static_cast<DeviceAttribute>(value));
}
}
}
_deviceAttributes.fetch_or(attributes.bits(), std::memory_order_relaxed);

View File

@ -51,6 +51,10 @@ namespace Microsoft::Console::VirtualTerminal
enum class DeviceAttribute : uint64_t
{
// Special value to indicate that InputStateMachineEngine::_deviceAttributes has been set.
// 0 in this case means 1<<0 == 1, which in turn means that _deviceAttributes is non-zero.
__some__ = 0,
Columns132 = 1,
PrinterPort = 2,
Sixel = 4,