Skip to content

Commit 38783fa

Browse files
lheckerDHowett
authored andcommitted
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 ✅ (cherry picked from commit 32ae00f) Service-Card-Id: PVTI_lADOAF3p4s4AxadtzgYO0a4 Service-Version: 1.23
1 parent a0140ef commit 38783fa

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

src/terminal/parser/InputStateMachineEngine.cpp

+13-6
Original file line numberDiff line numberDiff line change
@@ -471,15 +471,22 @@ bool InputStateMachineEngine::ActionCsiDispatch(const VTID id, const VTParameter
471471
// We catch it here and store the information for later retrieval.
472472
if (_deviceAttributes.load(std::memory_order_relaxed) == 0)
473473
{
474-
til::enumset<DeviceAttribute, uint64_t> attributes;
474+
til::enumset<DeviceAttribute, uint64_t> attributes{ DeviceAttribute::__some__ };
475475

476476
// The first parameter denotes the conformance level.
477-
if (parameters.at(0).value() >= 61)
477+
const auto len = parameters.size();
478+
if (len >= 2 && parameters.at(0).value() >= 61)
478479
{
479-
parameters.subspan(1).for_each([&](auto p) {
480-
attributes.set(static_cast<DeviceAttribute>(p));
481-
return true;
482-
});
480+
// NOTE: VTParameters::for_each will replace empty spans with a single default value.
481+
// This means we could not distinguish between no parameters and a single default parameter.
482+
for (size_t i = 1; i < len; i++)
483+
{
484+
const auto value = parameters.at(i).value();
485+
if (value > 0 && value < 64)
486+
{
487+
attributes.set(static_cast<DeviceAttribute>(value));
488+
}
489+
}
483490
}
484491

485492
_deviceAttributes.fetch_or(attributes.bits(), std::memory_order_relaxed);

src/terminal/parser/InputStateMachineEngine.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ namespace Microsoft::Console::VirtualTerminal
5151

5252
enum class DeviceAttribute : uint64_t
5353
{
54+
// Special value to indicate that InputStateMachineEngine::_deviceAttributes has been set.
55+
// 0 in this case means 1<<0 == 1, which in turn means that _deviceAttributes is non-zero.
56+
__some__ = 0,
57+
5458
Columns132 = 1,
5559
PrinterPort = 2,
5660
Sixel = 4,

0 commit comments

Comments
 (0)