From 1d6818829e8b43e224cccd67c6331e2040419b28 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Thu, 25 Nov 2021 00:28:27 +0100 Subject: [PATCH] Enable /permissive- and remaining /Zc flags --- .../SettingsModel.LocalTests.vcxproj | 3 +- .../TestHostApp/TestHostApp.vcxproj | 6 +- src/cascadia/TerminalControl/pch.h | 3 +- ...crosoft.Terminal.Settings.ModelLib.vcxproj | 2 + .../UnitTests_TerminalCore/TestUtils.h | 2 +- .../ut_app/TerminalApp.UnitTests.vcxproj | 3 +- src/common.build.pre.props | 4 +- src/cppwinrt.build.pre.props | 6 +- src/host/_stream.cpp | 2 +- src/host/_stream.h | 2 +- src/host/alias.cpp | 2 +- src/host/alias.h | 2 +- src/host/ft_host/API_FileTests.cpp | 2 +- src/host/init.cpp | 37 ++--- src/host/tracing.cpp | 2 +- src/host/tracing.hpp | 2 +- src/host/ut_host/AliasTests.cpp | 12 +- src/host/ut_host/ReadWaitTests.cpp | 2 +- src/host/ut_host/ScreenBufferTests.cpp | 4 +- src/host/ut_host/TextBufferIteratorTests.cpp | 110 +++++++-------- src/host/ut_host/TextBufferTests.cpp | 40 +++--- src/host/writeData.cpp | 2 +- src/host/writeData.hpp | 2 +- src/inc/til/static_map.h | 2 +- src/inc/til/string.h | 2 +- .../UiaTextRangeTests.cpp | 18 +-- src/propsheet/PropSheetHandler.cpp | 21 +-- src/renderer/atlas/AtlasEngine.h | 4 +- src/server/ApiSorter.cpp | 21 ++- src/server/IoDispatchers.cpp | 60 ++++---- .../adapter/ut_adapter/MouseInputTest.cpp | 10 +- .../parser/ft_fuzzer/VTCommandFuzzer.cpp | 42 +++--- .../parser/ft_fuzzer/fuzzing_directed.h | 8 +- src/terminal/parser/ft_fuzzer/fuzzing_logic.h | 63 +++++---- src/types/inc/viewport.hpp | 22 ++- src/winconpty/ft_pty/ConPtyTests.cpp | 132 +++++------------- 36 files changed, 283 insertions(+), 374 deletions(-) diff --git a/src/cascadia/LocalTests_SettingsModel/SettingsModel.LocalTests.vcxproj b/src/cascadia/LocalTests_SettingsModel/SettingsModel.LocalTests.vcxproj index 576c89e7d..3d74dac87 100644 --- a/src/cascadia/LocalTests_SettingsModel/SettingsModel.LocalTests.vcxproj +++ b/src/cascadia/LocalTests_SettingsModel/SettingsModel.LocalTests.vcxproj @@ -69,7 +69,8 @@ ..;$(OpenConsoleDir)\dep;$(OpenConsoleDir)\dep\jsoncpp\json;$(OpenConsoleDir)src\inc;$(OpenConsoleDir)src\inc\test;$(WinRT_IncludePath)\..\cppwinrt\winrt;"$(OpenConsoleDir)\src\cascadia\TerminalSettingsModel\Generated Files";%(AdditionalIncludeDirectories) pch.h - + + %(AdditionalOptions) /Zc:twoPhase- 4702;%(DisableSpecificWarnings) diff --git a/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj b/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj index 722ce9f5d..67e076ee5 100644 --- a/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj +++ b/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj @@ -51,10 +51,10 @@ + + %(AdditionalOptions) /Zc:twoPhase- 4453;%(DisableSpecificWarnings) - %(AdditionalIncludeDirectories) - ;$(IntermediateOutputPath) - + %(AdditionalIncludeDirectories);$(IntermediateOutputPath) INLINE_TEST_METHOD_MARKUP;%(PreprocessorDefinitions) diff --git a/src/cascadia/TerminalControl/pch.h b/src/cascadia/TerminalControl/pch.h index bac6c29ca..f9139b7d0 100644 --- a/src/cascadia/TerminalControl/pch.h +++ b/src/cascadia/TerminalControl/pch.h @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT license. // // pch.h @@ -57,6 +57,7 @@ TRACELOGGING_DECLARE_PROVIDER(g_hTerminalControlProvider); #include +#include #include #include "til.h" diff --git a/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj b/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj index bdd0fd38b..623810e8e 100644 --- a/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj +++ b/src/cascadia/TerminalSettingsModel/Microsoft.Terminal.Settings.ModelLib.vcxproj @@ -250,6 +250,8 @@ pch.h ..;$(OpenConsoleDir)\dep\jsoncpp\json;%(AdditionalIncludeDirectories); + + %(AdditionalOptions) /Zc:twoPhase- 4702;%(DisableSpecificWarnings) diff --git a/src/cascadia/UnitTests_TerminalCore/TestUtils.h b/src/cascadia/UnitTests_TerminalCore/TestUtils.h index 60008a07c..3f4373039 100644 --- a/src/cascadia/UnitTests_TerminalCore/TestUtils.h +++ b/src/cascadia/UnitTests_TerminalCore/TestUtils.h @@ -171,7 +171,7 @@ public: auto mismatched = (actualChars != expectedChars || actualAttrs != expectedAttrs); if (mismatched) { - Log::Comment(NoThrowString().Format( + WEX::Logging::Log::Comment(WEX::Common::NoThrowString().Format( L"Character or attribute at index %d was mismatched", charsProcessed)); } diff --git a/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj b/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj index 50ad0c4d1..b14062dad 100644 --- a/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj +++ b/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj @@ -60,7 +60,8 @@ ..;$(OpenConsoleDir)\dep\jsoncpp\json;$(OpenConsoleDir)src\inc;$(OpenConsoleDir)src\inc\test;$(WinRT_IncludePath)\..\cppwinrt\winrt;"$(OpenConsoleDir)\src\cascadia\TerminalApp\Generated Files";"$(OpenConsoleDir)\src\cascadia\TerminalSettingsModel\Generated Files";%(AdditionalIncludeDirectories) precomp.h - + + %(AdditionalOptions) /Zc:twoPhase- 4702;%(DisableSpecificWarnings) diff --git a/src/common.build.pre.props b/src/common.build.pre.props index 8238e3a93..557b2ab6d 100644 --- a/src/common.build.pre.props +++ b/src/common.build.pre.props @@ -116,9 +116,11 @@ true false false + true + true stdcpp17 stdc17 - /utf-8 %(AdditionalOptions) + %(AdditionalOptions) /utf-8 /Zc:externConstexpr /Zc:lambda /Zc:throwingNew Guard Fast diff --git a/src/cppwinrt.build.pre.props b/src/cppwinrt.build.pre.props index 2022dbc7f..7a9938631 100644 --- a/src/cppwinrt.build.pre.props +++ b/src/cppwinrt.build.pre.props @@ -71,10 +71,8 @@ pch.h $(IntDir)pch.pch - - true - true - %(AdditionalOptions) /bigobj /Zc:twoPhase- + + %(AdditionalOptions) /bigobj 5104;28204;%(DisableSpecificWarnings) $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) diff --git a/src/host/_stream.cpp b/src/host/_stream.cpp index e00238e41..dfe8fd51e 100644 --- a/src/host/_stream.cpp +++ b/src/host/_stream.cpp @@ -1001,7 +1001,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine; // - STATUS_SUCCESS if OK. // - CONSOLE_STATUS_WAIT if we couldn't finish now and need to be called back later (see ppWaiter). // - Or a suitable NTSTATUS format error code for memory/string/math failures. -[[nodiscard]] NTSTATUS DoWriteConsole(_In_reads_bytes_(*pcbBuffer) PWCHAR pwchBuffer, +[[nodiscard]] NTSTATUS DoWriteConsole(_In_reads_bytes_(*pcbBuffer) PCWCHAR pwchBuffer, _Inout_ size_t* const pcbBuffer, SCREEN_INFORMATION& screenInfo, bool requiresVtQuirk, diff --git a/src/host/_stream.h b/src/host/_stream.h index 349cb206a..2f9656c7b 100644 --- a/src/host/_stream.h +++ b/src/host/_stream.h @@ -90,7 +90,7 @@ Note: // NOTE: console lock must be held when calling this routine // String has been translated to unicode at this point. -[[nodiscard]] NTSTATUS DoWriteConsole(_In_reads_bytes_(*pcbBuffer) PWCHAR pwchBuffer, +[[nodiscard]] NTSTATUS DoWriteConsole(_In_reads_bytes_(*pcbBuffer) PCWCHAR pwchBuffer, _Inout_ size_t* const pcbBuffer, SCREEN_INFORMATION& screenInfo, bool requiresVtQuirk, diff --git a/src/host/alias.cpp b/src/host/alias.cpp index 01c9bda99..98d34e2b2 100644 --- a/src/host/alias.cpp +++ b/src/host/alias.cpp @@ -1216,7 +1216,7 @@ std::wstring Alias::s_MatchAndCopyAlias(const std::wstring& sourceText, // - LineCount - aliases can contain multiple commands. $T is the command separator // Return Value: // - None. It will just maintain the source as the target if we can't match an alias. -void Alias::s_MatchAndCopyAliasLegacy(_In_reads_bytes_(cbSource) PWCHAR pwchSource, +void Alias::s_MatchAndCopyAliasLegacy(_In_reads_bytes_(cbSource) PCWCH pwchSource, _In_ size_t cbSource, _Out_writes_bytes_(cbTargetWritten) PWCHAR pwchTarget, _In_ const size_t cbTargetSize, diff --git a/src/host/alias.h b/src/host/alias.h index ab8624b9f..ba0d0b27f 100644 --- a/src/host/alias.h +++ b/src/host/alias.h @@ -16,7 +16,7 @@ class Alias public: static void s_ClearCmdExeAliases(); - static void s_MatchAndCopyAliasLegacy(_In_reads_bytes_(cbSource) PWCHAR pwchSource, + static void s_MatchAndCopyAliasLegacy(_In_reads_bytes_(cbSource) PCWCH pwchSource, _In_ size_t cbSource, _Out_writes_bytes_(cbTargetWritten) PWCHAR pwchTarget, _In_ const size_t cbTargetSize, diff --git a/src/host/ft_host/API_FileTests.cpp b/src/host/ft_host/API_FileTests.cpp index ed0ed5afc..76dc7c152 100644 --- a/src/host/ft_host/API_FileTests.cpp +++ b/src/host/ft_host/API_FileTests.cpp @@ -104,7 +104,7 @@ void FileTests::TestUtf8WriteFileInvalid() DWORD dwWritten; DWORD dwExpectedWritten; - char* str; + const char* str; DWORD cbStr; // \x80 is an invalid UTF-8 continuation diff --git a/src/host/init.cpp b/src/host/init.cpp index 4d3c32709..e079bb7d9 100644 --- a/src/host/init.cpp +++ b/src/host/init.cpp @@ -12,8 +12,6 @@ // - Ensures the SxS initialization for the process. void InitSideBySide(_Out_writes_(ScratchBufferSize) PWSTR ScratchBuffer, __range(MAX_PATH, MAX_PATH) DWORD ScratchBufferSize) { - ACTCTXW actctx = { 0 }; - // Account for the fact that sidebyside stuff happens in CreateProcess // but conhost is run with RtlCreateUserProcess. @@ -30,38 +28,35 @@ void InitSideBySide(_Out_writes_(ScratchBufferSize) PWSTR ScratchBuffer, __range // make references to DLLs in the system that are in the SxS cache (ex. a 3rd party IME is loaded and asks for // comctl32.dll. The load will fail if SxS wasn't initialized.) This was bug# WIN7:681280. - // We look at the first few chars without being careful about a terminal nul, so init them. - ScratchBuffer[0] = 0; - ScratchBuffer[1] = 0; - ScratchBuffer[2] = 0; - ScratchBuffer[3] = 0; - ScratchBuffer[4] = 0; - ScratchBuffer[5] = 0; - ScratchBuffer[6] = 0; - - // GetModuleFileNameW truncates its result to fit in the buffer, so to detect if we fit, we have to do this. - ScratchBuffer[ScratchBufferSize - 2] = 0; DWORD const dwModuleFileNameLength = GetModuleFileNameW(nullptr, ScratchBuffer, ScratchBufferSize); if (dwModuleFileNameLength == 0) { RIPMSG1(RIP_ERROR, "GetModuleFileNameW failed %d.\n", GetLastError()); - goto Exit; + return; } - if (ScratchBuffer[ScratchBufferSize - 2] != 0) + // GetModuleFileNameW truncates its result to fit in the buffer + // and returns the given buffer size in such cases. + if (dwModuleFileNameLength == ScratchBufferSize) { RIPMSG1(RIP_ERROR, "GetModuleFileNameW requires more than ScratchBufferSize(%d) - 1.\n", ScratchBufferSize); - goto Exit; + return; } // We get an NT path from the Win32 api. Fix it to be Win32. + // We can test for NT paths by checking whether the string starts with "\??\C:\", or any + // alternative letter other than C. We specifically don't test for the drive letter below. UINT NtToWin32PathOffset = 0; - if (ScratchBuffer[0] == '\\' && ScratchBuffer[1] == '?' && ScratchBuffer[2] == '?' && ScratchBuffer[3] == '\\' - //&& ScratchBuffer[4] == a drive letter - && ScratchBuffer[5] == ':' && ScratchBuffer[6] == '\\') + static constexpr wchar_t ntPathSpec1[]{ L'\\', L'?', L'?', L'\\' }; + static constexpr wchar_t ntPathSpec2[]{ L':', L'\\' }; + if ( + dwModuleFileNameLength >= 7 && + memcmp(&ScratchBuffer[0], &ntPathSpec1[0], sizeof(ntPathSpec1)) == 0 && + memcmp(&ScratchBuffer[5], &ntPathSpec2[0], sizeof(ntPathSpec2)) == 0) { NtToWin32PathOffset = 4; } + ACTCTXW actctx{}; actctx.cbSize = sizeof(actctx); actctx.dwFlags = (ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_SET_PROCESS_DEFAULT); actctx.lpResourceName = MAKEINTRESOURCE(IDR_SYSTEM_MANIFEST); @@ -83,11 +78,7 @@ void InitSideBySide(_Out_writes_(ScratchBufferSize) PWSTR ScratchBuffer, __range { RIPMSG1(RIP_WARNING, "InitSideBySide failed create an activation context. Error: %d\r\n", error); } - goto Exit; } - -Exit: - ScratchBuffer[0] = 0; } // Routine Description: diff --git a/src/host/tracing.cpp b/src/host/tracing.cpp index 111436ce1..44d9b9a96 100644 --- a/src/host/tracing.cpp +++ b/src/host/tracing.cpp @@ -58,7 +58,7 @@ Tracing::~Tracing() // Return Value: // - An object for the caller to hold until the API call is complete. // Then destroy it to signal that the call is over so the stop trace can be written. -Tracing Tracing::s_TraceApiCall(const NTSTATUS& result, PCSTR traceName) +Tracing Tracing::s_TraceApiCall(const NTSTATUS result, PCSTR traceName) { // clang-format off TraceLoggingWrite( diff --git a/src/host/tracing.hpp b/src/host/tracing.hpp index a32fc6c3f..f1d1e4126 100644 --- a/src/host/tracing.hpp +++ b/src/host/tracing.hpp @@ -40,7 +40,7 @@ class Tracing public: ~Tracing(); - static Tracing s_TraceApiCall(const NTSTATUS& result, PCSTR traceName); + static Tracing s_TraceApiCall(const NTSTATUS result, PCSTR traceName); static void s_TraceApi(const NTSTATUS status, const CONSOLE_GETLARGESTWINDOWSIZE_MSG* const a); static void s_TraceApi(const NTSTATUS status, const CONSOLE_SCREENBUFFERINFO_MSG* const a, const bool fSet); diff --git a/src/host/ut_host/AliasTests.cpp b/src/host/ut_host/AliasTests.cpp index 2249b2b4c..b401823bf 100644 --- a/src/host/ut_host/AliasTests.cpp +++ b/src/host/ut_host/AliasTests.cpp @@ -153,7 +153,7 @@ class AliasTests TEST_METHOD(TestMatchAndCopyTrailingCRLF) { - PWSTR pwszSource = L"SourceWithoutCRLF\r\n"; + const auto pwszSource = L"SourceWithoutCRLF\r\n"; const size_t cbSource = wcslen(pwszSource) * sizeof(wchar_t); const size_t cchTarget = 60; @@ -193,7 +193,7 @@ class AliasTests TEST_METHOD(TestMatchAndCopyInvalidExeName) { - PWSTR pwszSource = L"Source"; + const auto pwszSource = L"Source"; const size_t cbSource = wcslen(pwszSource) * sizeof(wchar_t); const size_t cchTarget = 12; @@ -225,7 +225,7 @@ class AliasTests TEST_METHOD(TestMatchAndCopyExeNotFound) { - PWSTR pwszSource = L"Source"; + const auto pwszSource = L"Source"; const size_t cbSource = wcslen(pwszSource) * sizeof(wchar_t); const size_t cchTarget = 12; @@ -257,7 +257,7 @@ class AliasTests TEST_METHOD(TestMatchAndCopyAliasNotFound) { - PWSTR pwszSource = L"Source"; + const auto pwszSource = L"Source"; const size_t cbSource = wcslen(pwszSource) * sizeof(wchar_t); const size_t cchTarget = 12; @@ -294,7 +294,7 @@ class AliasTests TEST_METHOD(TestMatchAndCopyTargetTooSmall) { - PWSTR pwszSource = L"Source"; + const auto pwszSource = L"Source"; const size_t cbSource = wcslen(pwszSource) * sizeof(wchar_t); const size_t cchTarget = 12; @@ -330,7 +330,7 @@ class AliasTests TEST_METHOD(TestMatchAndCopyLeadingSpaces) { - PWSTR pwszSource = L" Source"; + const auto pwszSource = L" Source"; const size_t cbSource = wcslen(pwszSource) * sizeof(wchar_t); const size_t cchTarget = 12; diff --git a/src/host/ut_host/ReadWaitTests.cpp b/src/host/ut_host/ReadWaitTests.cpp index d4b34328d..c4724ccbd 100644 --- a/src/host/ut_host/ReadWaitTests.cpp +++ b/src/host/ut_host/ReadWaitTests.cpp @@ -118,7 +118,7 @@ class InputRecordConversionTests dbcsChars, INPUT_RECORD_COUNT * 2, nullptr, - false); + FALSE); VERIFY_ARE_EQUAL(writtenBytes, static_cast(INPUT_RECORD_COUNT * 2)); for (size_t i = 0; i < INPUT_RECORD_COUNT * 2; ++i) { diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp index 4d9381309..04a9b14d9 100644 --- a/src/host/ut_host/ScreenBufferTests.cpp +++ b/src/host/ut_host/ScreenBufferTests.cpp @@ -2572,7 +2572,7 @@ void ScreenBufferTests::BackspaceDefaultAttrsWriteCharsLegacy() if (writeSingly) { - wchar_t* str = L"X"; + auto str = L"X"; size_t seqCb = 2; VERIFY_SUCCESS_NTSTATUS(WriteCharsLegacy(si, str, str, str, &seqCb, nullptr, cursor.GetPosition().X, writeCharsLegacyMode, nullptr)); VERIFY_SUCCESS_NTSTATUS(WriteCharsLegacy(si, str, str, str, &seqCb, nullptr, cursor.GetPosition().X, writeCharsLegacyMode, nullptr)); @@ -2581,7 +2581,7 @@ void ScreenBufferTests::BackspaceDefaultAttrsWriteCharsLegacy() } else { - wchar_t* str = L"XX\x08"; + const auto str = L"XX\x08"; size_t seqCb = 6; VERIFY_SUCCESS_NTSTATUS(WriteCharsLegacy(si, str, str, str, &seqCb, nullptr, cursor.GetPosition().X, writeCharsLegacyMode, nullptr)); } diff --git a/src/host/ut_host/TextBufferIteratorTests.cpp b/src/host/ut_host/TextBufferIteratorTests.cpp index 197deffa1..e5538c459 100644 --- a/src/host/ut_host/TextBufferIteratorTests.cpp +++ b/src/host/ut_host/TextBufferIteratorTests.cpp @@ -22,6 +22,61 @@ using namespace WEX::Logging; using namespace WEX::TestExecution; using Microsoft::Console::Interactivity::ServiceLocator; +template +T GetIterator() +{ +} + +template +T GetIteratorAt(COORD at) +{ +} + +template +T GetIteratorWithAdvance() +{ +} + +template<> +TextBufferCellIterator GetIteratorAt(COORD at) +{ + const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); + const auto& outputBuffer = gci.GetActiveOutputBuffer(); + return outputBuffer.GetCellDataAt(at); +} + +template<> +TextBufferCellIterator GetIterator() +{ + return GetIteratorAt({ 0 }); +} + +template<> +TextBufferCellIterator GetIteratorWithAdvance() +{ + return GetIteratorAt({ 5, 5 }); +} + +template<> +TextBufferTextIterator GetIteratorAt(COORD at) +{ + const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); + const auto& outputBuffer = gci.GetActiveOutputBuffer(); + return outputBuffer.GetTextDataAt(at); +} + +template<> +TextBufferTextIterator GetIterator() +{ + return GetIteratorAt({ 0 }); +} + +template<> +TextBufferTextIterator GetIteratorWithAdvance() +{ + return GetIteratorAt({ 5, 5 }); +} + class TextBufferIteratorTests { CommonState* m_state; @@ -268,61 +323,6 @@ class TextBufferIteratorTests TEST_METHOD(ConstructedLimits); }; -template -T GetIterator() -{ -} - -template -T GetIteratorAt(COORD at) -{ -} - -template -T GetIteratorWithAdvance() -{ -} - -template<> -TextBufferCellIterator GetIteratorAt(COORD at) -{ - const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - const auto& outputBuffer = gci.GetActiveOutputBuffer(); - return outputBuffer.GetCellDataAt(at); -} - -template<> -TextBufferCellIterator GetIterator() -{ - return GetIteratorAt({ 0 }); -} - -template<> -TextBufferCellIterator GetIteratorWithAdvance() -{ - return GetIteratorAt({ 5, 5 }); -} - -template<> -TextBufferTextIterator GetIteratorAt(COORD at) -{ - const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - const auto& outputBuffer = gci.GetActiveOutputBuffer(); - return outputBuffer.GetTextDataAt(at); -} - -template<> -TextBufferTextIterator GetIterator() -{ - return GetIteratorAt({ 0 }); -} - -template<> -TextBufferTextIterator GetIteratorWithAdvance() -{ - return GetIteratorAt({ 5, 5 }); -} - void TextBufferIteratorTests::BoolOperatorText() { BoolOperatorTestHelper(); diff --git a/src/host/ut_host/TextBufferTests.cpp b/src/host/ut_host/TextBufferTests.cpp index 2872c9421..59567512e 100644 --- a/src/host/ut_host/TextBufferTests.cpp +++ b/src/host/ut_host/TextBufferTests.cpp @@ -81,7 +81,7 @@ class TextBufferTests TEST_METHOD(TestDoubleBytePadFlag); - void DoBoundaryTest(PWCHAR const pwszInputString, + void DoBoundaryTest(PCWCHAR const pwszInputString, short const cLength, short const cMax, short const cLeft, @@ -300,7 +300,7 @@ void TextBufferTests::TestDoubleBytePadFlag() VERIFY_IS_FALSE(Row.WasDoubleBytePadded()); } -void TextBufferTests::DoBoundaryTest(PWCHAR const pwszInputString, +void TextBufferTests::DoBoundaryTest(PCWCHAR const pwszInputString, short const cLength, short const cMax, short const cLeft, @@ -336,7 +336,7 @@ void TextBufferTests::TestBoundaryMeasuresRegularString() SHORT csBufferWidth = GetBufferWidth(); // length 44, left 0, right 44 - const PWCHAR pwszLazyDog = L"The quick brown fox jumps over the lazy dog."; + const auto pwszLazyDog = L"The quick brown fox jumps over the lazy dog."; DoBoundaryTest(pwszLazyDog, 44, csBufferWidth, 0, 44); } @@ -345,7 +345,7 @@ void TextBufferTests::TestBoundaryMeasuresFloatingString() SHORT csBufferWidth = GetBufferWidth(); // length 5 spaces + 4 chars + 5 spaces = 14, left 5, right 9 - const PWCHAR pwszOffsets = L" C:\\> "; + const auto pwszOffsets = L" C:\\> "; DoBoundaryTest(pwszOffsets, 14, csBufferWidth, 5, 9); } @@ -648,7 +648,7 @@ void TextBufferTests::TestMixedRgbAndLegacyForeground() // FG = rgb(64;128;255), BG = rgb(default) Log::Comment(L"Case 1 \"\\E[m\\E[38;2;64;128;255mX\\E[49mX\\E[m\""); - wchar_t* sequence = L"\x1b[m\x1b[38;2;64;128;255mX\x1b[49mX\x1b[m"; + const auto sequence = L"\x1b[m\x1b[38;2;64;128;255mX\x1b[49mX\x1b[m"; stateMachine.ProcessString(sequence); const short x = cursor.GetPosition().X; @@ -675,7 +675,7 @@ void TextBufferTests::TestMixedRgbAndLegacyForeground() VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA), std::make_pair(fgColor, bgColor)); VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB), std::make_pair(fgColor, bgColor)); - wchar_t* reset = L"\x1b[0m"; + const auto reset = L"\x1b[0m"; stateMachine.ProcessString(reset); } @@ -693,7 +693,7 @@ void TextBufferTests::TestMixedRgbAndLegacyBackground() // FG = rgb(default), BG = rgb(64;128;255) Log::Comment(L"Case 2 \"\\E[m\\E[48;2;64;128;255mX\\E[39mX\\E[m\""); - wchar_t* sequence = L"\x1b[m\x1b[48;2;64;128;255mX\x1b[39mX\x1b[m"; + const auto sequence = L"\x1b[m\x1b[48;2;64;128;255mX\x1b[39mX\x1b[m"; stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; @@ -719,7 +719,7 @@ void TextBufferTests::TestMixedRgbAndLegacyBackground() VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA), std::make_pair(fgColor, bgColor)); VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB), std::make_pair(fgColor, bgColor)); - wchar_t* reset = L"\x1b[0m"; + const auto reset = L"\x1b[0m"; stateMachine.ProcessString(reset); } @@ -735,7 +735,7 @@ void TextBufferTests::TestMixedRgbAndLegacyUnderline() // '\E[m\E[48;2;64;128;255mX\E[4mX\E[m' // Make sure that the second X has RGB attributes AND underline Log::Comment(L"Case 3 \"\\E[m\\E[48;2;64;128;255mX\\E[4mX\\E[m\""); - wchar_t* sequence = L"\x1b[m\x1b[48;2;64;128;255mX\x1b[4mX\x1b[m"; + const auto sequence = L"\x1b[m\x1b[48;2;64;128;255mX\x1b[4mX\x1b[m"; stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; @@ -764,7 +764,7 @@ void TextBufferTests::TestMixedRgbAndLegacyUnderline() VERIFY_ARE_EQUAL(attrA.IsUnderlined(), false); VERIFY_ARE_EQUAL(attrB.IsUnderlined(), true); - wchar_t* reset = L"\x1b[0m"; + const auto reset = L"\x1b[0m"; stateMachine.ProcessString(reset); } @@ -783,7 +783,7 @@ void TextBufferTests::TestMixedRgbAndLegacyBrightness() const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN); VERIFY_ARE_NOT_EQUAL(dark_green, bright_green); - wchar_t* sequence = L"\x1b[m\x1b[32mX\x1b[1mX"; + const auto sequence = L"\x1b[m\x1b[32mX\x1b[1mX"; stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; @@ -806,7 +806,7 @@ void TextBufferTests::TestMixedRgbAndLegacyBrightness() VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA).first, dark_green); VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB).first, bright_green); - wchar_t* reset = L"\x1b[0m"; + const auto reset = L"\x1b[0m"; stateMachine.ProcessString(reset); } @@ -1384,7 +1384,7 @@ void TextBufferTests::TestRgbThenBold() VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA), std::make_pair(foreground, background)); VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB), std::make_pair(foreground, background)); - wchar_t* reset = L"\x1b[0m"; + const auto reset = L"\x1b[0m"; stateMachine.ProcessString(reset); } @@ -1408,7 +1408,7 @@ void TextBufferTests::TestResetClearsBoldness() const auto dark_green = gci.GetColorTableEntry(TextColor::DARK_GREEN); const auto bright_green = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN); - wchar_t* sequence = L"\x1b[32mA\x1b[1mB\x1b[0mC\x1b[32mD"; + const auto sequence = L"\x1b[32mA\x1b[1mB\x1b[0mC\x1b[32mD"; Log::Comment(NoThrowString().Format(sequence)); stateMachine.ProcessString(sequence); @@ -1443,7 +1443,7 @@ void TextBufferTests::TestResetClearsBoldness() VERIFY_IS_FALSE(attrC.IsBold()); VERIFY_IS_FALSE(attrD.IsBold()); - wchar_t* reset = L"\x1b[0m"; + const auto reset = L"\x1b[0m"; stateMachine.ProcessString(reset); } @@ -1552,7 +1552,7 @@ void TextBufferTests::TestBackspaceStringsAPI() Log::Comment(NoThrowString().Format( L"Using WriteCharsLegacy, write \\b \\b as a single string.")); { - wchar_t* str = L"\b \b"; + const auto str = L"\b \b"; VERIFY_SUCCESS_NTSTATUS(WriteCharsLegacy(si, str, str, str, &seqCb, nullptr, cursor.GetPosition().X, 0, nullptr)); VERIFY_ARE_EQUAL(cursor.GetPosition().X, x0); @@ -1583,19 +1583,19 @@ void TextBufferTests::TestBackspaceStringsAPI() Log::Comment(NoThrowString().Format( L"Using WriteCharsLegacy, write \\b \\b as separate strings.")); { - wchar_t* str = L"a"; + const auto str = L"a"; VERIFY_SUCCESS_NTSTATUS(WriteCharsLegacy(si, str, str, str, &seqCb, nullptr, cursor.GetPosition().X, 0, nullptr)); } { - wchar_t* str = L"\b"; + const auto str = L"\b"; VERIFY_SUCCESS_NTSTATUS(WriteCharsLegacy(si, str, str, str, &seqCb, nullptr, cursor.GetPosition().X, 0, nullptr)); } { - wchar_t* str = L" "; + const auto str = L" "; VERIFY_SUCCESS_NTSTATUS(WriteCharsLegacy(si, str, str, str, &seqCb, nullptr, cursor.GetPosition().X, 0, nullptr)); } { - wchar_t* str = L"\b"; + const auto str = L"\b"; VERIFY_SUCCESS_NTSTATUS(WriteCharsLegacy(si, str, str, str, &seqCb, nullptr, cursor.GetPosition().X, 0, nullptr)); } diff --git a/src/host/writeData.cpp b/src/host/writeData.cpp index 2de6940b2..73b52e427 100644 --- a/src/host/writeData.cpp +++ b/src/host/writeData.cpp @@ -22,7 +22,7 @@ // Return Value: // - THROW: Throws if space cannot be allocated to copy the given string WriteData::WriteData(SCREEN_INFORMATION& siContext, - _In_reads_bytes_(cbContext) wchar_t* const pwchContext, + _In_reads_bytes_(cbContext) PCWCHAR pwchContext, const size_t cbContext, const UINT uiOutputCodepage, const bool requiresVtQuirk) : diff --git a/src/host/writeData.hpp b/src/host/writeData.hpp index b23e12ad4..ada370208 100644 --- a/src/host/writeData.hpp +++ b/src/host/writeData.hpp @@ -25,7 +25,7 @@ class WriteData : public IWaitRoutine { public: WriteData(SCREEN_INFORMATION& siContext, - _In_reads_bytes_(cbContext) wchar_t* const pwchContext, + _In_reads_bytes_(cbContext) PCWCHAR pwchContext, const size_t cbContext, const UINT uiOutputCodepage, const bool requiresVtQuirk); diff --git a/src/inc/til/static_map.h b/src/inc/til/static_map.h index 8bcb7689c..f5d82f113 100644 --- a/src/inc/til/static_map.h +++ b/src/inc/til/static_map.h @@ -97,7 +97,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" public: template constexpr explicit presorted_static_map(const Args&... args) noexcept : - static_map{ args... } {}; + static_map{ args... } {}; }; // this is a deduction guide that ensures two things: diff --git a/src/inc/til/string.h b/src/inc/til/string.h index 0f7d38738..d09eb159b 100644 --- a/src/inc/til/string.h +++ b/src/inc/til/string.h @@ -169,7 +169,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" // and 5x or more for long strings (128 characters or more). // See: https://github.com/microsoft/STL/issues/2289 template - bool equals(const std::basic_string_view& str1, const std::basic_string_view& str2) noexcept + bool equals(const std::basic_string_view& lhs, const std::basic_string_view& rhs) noexcept { return lhs.size() == rhs.size() && __builtin_memcmp(lhs.data(), rhs.data(), lhs.size() * sizeof(T)) == 0; } diff --git a/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp b/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp index 518dc8747..f2c93ebe6 100644 --- a/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp +++ b/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp @@ -315,7 +315,7 @@ class UiaTextRangeTests short yPos; }; - static constexpr wchar_t* toString(TextUnit unit) noexcept + static constexpr const wchar_t* toString(TextUnit unit) noexcept { // if a format is not supported, it goes to the next largest text unit switch (unit) @@ -1368,17 +1368,17 @@ class UiaTextRangeTests Log::Comment(NoThrowString().Format(L"Forward by %s", toString(textUnit))); // Create an UTR at EndExclusive - const auto utrEnd{ atDocumentEnd ? documentEndExclusive : endExclusive }; + const auto utrEnd{ atDocumentEnd ? documentEndExclusive : static_cast(endExclusive) }; if (degenerate) { // UTR: (exclusive, exclusive) range - const auto utrStart{ atDocumentEnd ? documentEndExclusive : endExclusive }; + const auto utrStart{ atDocumentEnd ? documentEndExclusive : static_cast(endExclusive) }; THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize(&utr, _pUiaData, &_dummyProvider, utrStart, utrEnd)); } else { // UTR: (inclusive, exclusive) range - const auto utrStart{ atDocumentEnd ? documentEndInclusive : endInclusive }; + const auto utrStart{ atDocumentEnd ? documentEndInclusive : static_cast(endInclusive) }; THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize(&utr, _pUiaData, &_dummyProvider, utrStart, utrEnd)); } THROW_IF_FAILED(utr->Move(textUnit, 1, &moveAmt)); @@ -1414,13 +1414,13 @@ class UiaTextRangeTests if (degenerate) { // UTR: (exclusive, exclusive) range - const auto utrStart{ atDocumentEnd ? documentEndExclusive : endExclusive }; + const auto utrStart{ atDocumentEnd ? documentEndExclusive : static_cast(endExclusive) }; THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize(&utr, _pUiaData, &_dummyProvider, utrStart, utrEnd)); } else { // UTR: (inclusive, exclusive) range - const auto utrStart{ atDocumentEnd ? documentEndInclusive : endInclusive }; + const auto utrStart{ atDocumentEnd ? documentEndInclusive : static_cast(endInclusive) }; THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize(&utr, _pUiaData, &_dummyProvider, utrStart, utrEnd)); } @@ -1447,14 +1447,14 @@ class UiaTextRangeTests else if (textUnit <= TextUnit::TextUnit_Line) { VERIFY_ARE_EQUAL(-1, moveAmt); - VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? lastLineStart : secondToLastLinePos, til::point{ utr->_start }); - VERIFY_ARE_EQUAL(lastLineStart, til::point{ utr->_end }); + VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? lastLineStart : static_cast(secondToLastLinePos), utr->_start); + VERIFY_ARE_EQUAL(lastLineStart, utr->_end); } else // textUnit <= TextUnit::TextUnit_Document: { VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? -1 : 0, moveAmt); VERIFY_ARE_EQUAL(origin, til::point{ utr->_start }); - VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? origin : documentEndExclusive, til::point{ utr->_end }); + VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? static_cast(origin) : documentEndExclusive, utr->_end); } } diff --git a/src/propsheet/PropSheetHandler.cpp b/src/propsheet/PropSheetHandler.cpp index 079f775c4..acdac9c3c 100644 --- a/src/propsheet/PropSheetHandler.cpp +++ b/src/propsheet/PropSheetHandler.cpp @@ -18,14 +18,7 @@ static CONSOLE_STATE_INFO g_csi; using namespace Microsoft::WRL; // This class exposes console property sheets for use when launching the filesystem shortcut properties dialog. -// clang-format off -[uuid(D2942F8E-478E-41D3-870A-35A16238F4EE)] -class ConsolePropertySheetHandler WrlFinal : public RuntimeClass, - IShellExtInit, - IShellPropSheetExt, - IPersist, - FtmBase> -// clang-format on +class __declspec(uuid("D2942F8E-478E-41D3-870A-35A16238F4EE")) ConsolePropertySheetHandler final : public RuntimeClass, IShellExtInit, IShellPropSheetExt, IPersist, FtmBase> { public: HRESULT RuntimeClassInitialize() @@ -34,7 +27,7 @@ public: } // IPersist - STDMETHODIMP GetClassID(_Out_ CLSID * clsid) override + STDMETHODIMP GetClassID(_Out_ CLSID* clsid) override { *clsid = __uuidof(this); return S_OK; @@ -43,7 +36,7 @@ public: // IShellExtInit // Shell QI's for IShellExtInit and calls Initialize first. If we return a succeeding HRESULT, the shell will QI for // IShellPropSheetExt and call AddPages. A failing HRESULT causes the shell to skip us. - STDMETHODIMP Initialize(_In_ PCIDLIST_ABSOLUTE /*pidlFolder*/, _In_ IDataObject * pdtobj, _In_ HKEY /*hkeyProgID*/) + STDMETHODIMP Initialize(_In_ PCIDLIST_ABSOLUTE /*pidlFolder*/, _In_ IDataObject* pdtobj, _In_ HKEY /*hkeyProgID*/) { WCHAR szLinkFileName[MAX_PATH]; HRESULT hr = _ShouldAddPropertySheet(pdtobj, szLinkFileName, ARRAYSIZE(szLinkFileName)); @@ -139,7 +132,7 @@ private: /////////////////////////////////////////////////////////////////////////// // CODE FROM THE SHELL DEPOT'S `idllib.h` // get a link target item without resolving it. - HRESULT GetTargetIdList(_In_ IShellItem * psiLink, _COM_Outptr_ PIDLIST_ABSOLUTE * ppidl) + HRESULT GetTargetIdList(_In_ IShellItem* psiLink, _COM_Outptr_ PIDLIST_ABSOLUTE* ppidl) { *ppidl = nullptr; @@ -156,7 +149,7 @@ private: } return hr; } - HRESULT GetTargetItem(_In_ IShellItem * psiLink, _In_ REFIID riid, _COM_Outptr_ void** ppv) + HRESULT GetTargetItem(_In_ IShellItem* psiLink, _In_ REFIID riid, _COM_Outptr_ void** ppv) { *ppv = nullptr; @@ -171,7 +164,7 @@ private: } /////////////////////////////////////////////////////////////////////////// - HRESULT _GetShellItemLinkTargetExpanded(_In_ IShellItem * pShellItem, + HRESULT _GetShellItemLinkTargetExpanded(_In_ IShellItem* pShellItem, _Out_writes_(cchFilePathExtended) PWSTR pszFilePathExtended, const size_t cchFilePathExtended) { @@ -190,7 +183,7 @@ private: return hr; } - HRESULT _ShouldAddPropertySheet(_In_ IDataObject * pdtobj, + HRESULT _ShouldAddPropertySheet(_In_ IDataObject* pdtobj, _Out_writes_(cchLinkFileName) PWSTR pszLinkFileName, const size_t cchLinkFileName) { diff --git a/src/renderer/atlas/AtlasEngine.h b/src/renderer/atlas/AtlasEngine.h index 8b9b6d0ca..87b3e5681 100644 --- a/src/renderer/atlas/AtlasEngine.h +++ b/src/renderer/atlas/AtlasEngine.h @@ -359,7 +359,9 @@ namespace Microsoft::Console::Render bool is_inline() const noexcept { - return (__builtin_bit_cast(uintptr_t, allocated) & 1) != 0; + // VSO-1430353: __builtin_bitcast crashes the compiler under /permissive-. +#pragma warning(suppress : 26490) // Don't use reinterpret_cast (type.1). + return (reinterpret_cast(allocated) & 1) != 0; } const T* data() const noexcept diff --git a/src/server/ApiSorter.cpp b/src/server/ApiSorter.cpp index 84cc81f96..7b1bd3469 100644 --- a/src/server/ApiSorter.cpp +++ b/src/server/ApiSorter.cpp @@ -144,11 +144,10 @@ PCONSOLE_API_MSG ApiSorter::ConsoleDispatchRequest(_Inout_ PCONSOLE_API_MSG Mess ULONG const LayerNumber = (Message->msgHeader.ApiNumber >> 24) - 1; ULONG const ApiNumber = Message->msgHeader.ApiNumber & 0xffffff; - NTSTATUS Status; - if ((LayerNumber >= RTL_NUMBER_OF(ConsoleApiLayerTable)) || (ApiNumber >= ConsoleApiLayerTable[LayerNumber].Count)) + if ((LayerNumber >= std::size(ConsoleApiLayerTable)) || (ApiNumber >= ConsoleApiLayerTable[LayerNumber].Count)) { - Status = STATUS_ILLEGAL_FUNCTION; - goto Complete; + Message->SetReplyStatus(STATUS_ILLEGAL_FUNCTION); + return Message; } CONSOLE_API_DESCRIPTOR const* Descriptor = &ConsoleApiLayerTable[LayerNumber].Descriptor[ApiNumber]; @@ -159,8 +158,8 @@ PCONSOLE_API_MSG ApiSorter::ConsoleDispatchRequest(_Inout_ PCONSOLE_API_MSG Mess (Message->msgHeader.ApiDescriptorSize > Message->Descriptor.InputSize - sizeof(CONSOLE_MSG_HEADER)) || (Message->msgHeader.ApiDescriptorSize < Descriptor->RequiredSize)) { - Status = STATUS_ILLEGAL_FUNCTION; - goto Complete; + Message->SetReplyStatus(STATUS_ILLEGAL_FUNCTION); + return Message; } BOOL ReplyPending = FALSE; @@ -173,6 +172,7 @@ PCONSOLE_API_MSG ApiSorter::ConsoleDispatchRequest(_Inout_ PCONSOLE_API_MSG Mess // hard dependencies on NTSTATUS codes that aren't readily expressible as an HRESULT. There's currently only one // such known code -- STATUS_BUFFER_TOO_SMALL. There's a conlibk dependency on this being returned from the console // alias API. + NTSTATUS Status = S_OK; { const auto trace = Tracing::s_TraceApiCall(Status, Descriptor->TraceName); Status = (*Descriptor->Routine)(Message, &ReplyPending); @@ -184,14 +184,9 @@ PCONSOLE_API_MSG ApiSorter::ConsoleDispatchRequest(_Inout_ PCONSOLE_API_MSG Mess if (!ReplyPending) { - goto Complete; + Message->SetReplyStatus(Status); + return Message; } return nullptr; - -Complete: - - Message->SetReplyStatus(Status); - - return Message; } diff --git a/src/server/IoDispatchers.cpp b/src/server/IoDispatchers.cpp index 63f9dc231..c2f3265bc 100644 --- a/src/server/IoDispatchers.cpp +++ b/src/server/IoDispatchers.cpp @@ -92,7 +92,9 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleCreateObject(_In_ PCONSOLE_API_MSG pMessa if (!NT_SUCCESS(Status)) { - goto Error; + UnlockConsole(); + pMessage->SetReplyStatus(Status); + return pMessage; } auto deviceComm{ ServiceLocator::LocateGlobals().pDeviceComm }; @@ -110,16 +112,6 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleCreateObject(_In_ PCONSOLE_API_MSG pMessa UnlockConsole(); return nullptr; - -Error: - - FAIL_FAST_IF(NT_SUCCESS(Status)); - - UnlockConsole(); - - pMessage->SetReplyStatus(Status); - - return pMessage; } // Routine Description: @@ -256,17 +248,32 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleHandleConnectionRequest(_In_ PCONSOLE_API Telemetry::Instance().LogApiCall(Telemetry::ApiCall::AttachConsole); ConsoleProcessHandle* ProcessData = nullptr; + NTSTATUS Status; LockConsole(); + const auto cleanup = wil::scope_exit([&]() noexcept { + UnlockConsole(); + + if (!NT_SUCCESS(Status)) + { + pReceiveMsg->SetReplyStatus(Status); + if (ProcessData != nullptr) + { + CommandHistory::s_Free(ProcessData); + gci.ProcessHandleList.FreeProcessData(ProcessData); + } + } + }); + DWORD const dwProcessId = (DWORD)pReceiveMsg->Descriptor.Process; DWORD const dwThreadId = (DWORD)pReceiveMsg->Descriptor.Object; CONSOLE_API_CONNECTINFO Cac; - NTSTATUS Status = ConsoleInitializeConnectInfo(pReceiveMsg, &Cac); + Status = ConsoleInitializeConnectInfo(pReceiveMsg, &Cac); if (!NT_SUCCESS(Status)) { - goto Error; + return pReceiveMsg; } // If we pass the tests... @@ -354,7 +361,7 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleHandleConnectionRequest(_In_ PCONSOLE_API if (!NT_SUCCESS(Status)) { - goto Error; + return pReceiveMsg; } ProcessData->fRootProcess = WI_IsFlagClear(gci.Flags, CONSOLE_INITIALIZED); @@ -376,7 +383,7 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleHandleConnectionRequest(_In_ PCONSOLE_API Status = ConsoleAllocateConsole(&Cac); if (!NT_SUCCESS(Status)) { - goto Error; + return pReceiveMsg; } WI_SetFlag(gci.Flags, CONSOLE_INITIALIZED); @@ -389,7 +396,7 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleHandleConnectionRequest(_In_ PCONSOLE_API catch (...) { LOG_CAUGHT_EXCEPTION(); - goto Error; + return pReceiveMsg; } gci.ProcessHandleList.ModifyConsoleProcessFocus(WI_IsFlagSet(gci.Flags, CONSOLE_HAS_FOCUS)); @@ -403,7 +410,7 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleHandleConnectionRequest(_In_ PCONSOLE_API if (!NT_SUCCESS(Status)) { - goto Error; + return pReceiveMsg; } auto& screenInfo = gci.GetActiveOutputBuffer().GetMainBuffer(); @@ -414,7 +421,7 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleHandleConnectionRequest(_In_ PCONSOLE_API if (!NT_SUCCESS(Status)) { - goto Error; + return pReceiveMsg; } // Complete the request. @@ -434,24 +441,7 @@ PCONSOLE_API_MSG IoDispatchers::ConsoleHandleConnectionRequest(_In_ PCONSOLE_API Tracing::s_TraceConsoleAttachDetach(ProcessData, true); - UnlockConsole(); - return nullptr; - -Error: - FAIL_FAST_IF(NT_SUCCESS(Status)); - - if (ProcessData != nullptr) - { - CommandHistory::s_Free((HANDLE)ProcessData); - gci.ProcessHandleList.FreeProcessData(ProcessData); - } - - UnlockConsole(); - - pReceiveMsg->SetReplyStatus(Status); - - return pReceiveMsg; } // Routine Description: diff --git a/src/terminal/adapter/ut_adapter/MouseInputTest.cpp b/src/terminal/adapter/ut_adapter/MouseInputTest.cpp index 6841c2782..b302928b8 100644 --- a/src/terminal/adapter/ut_adapter/MouseInputTest.cpp +++ b/src/terminal/adapter/ut_adapter/MouseInputTest.cpp @@ -25,7 +25,7 @@ using namespace Microsoft::Console::VirtualTerminal; // For magic reasons, this has to live outside the class. Something wonderful about TAEF macros makes it // invisible to the linker when inside the class. -static wchar_t* s_pwszInputExpected; +static const wchar_t* s_pwszInputExpected; static wchar_t s_pwszExpectedBuffer[BYTE_MAX]; // big enough for anything @@ -46,7 +46,7 @@ static COORD s_rgTestCoords[] = { // Note: We're going to be changing the value of the third char (the space) of // these strings as we test things with this array, to alter the expected button value. // The default value is the button=WM_LBUTTONDOWN case, which is element[3]=' ' -static wchar_t* s_rgDefaultTestOutput[] = { +static const wchar_t* s_rgDefaultTestOutput[] = { L"\x1b[M !!", L"\x1b[M !\"", L"\x1b[M \"\"", @@ -64,7 +64,7 @@ static wchar_t* s_rgDefaultTestOutput[] = { // these strings as we test things with this array, to alter the expected button value. // The default value is the button=WM_LBUTTONDOWN case, which is element[3]='0' // We're also going to change the last element, for button-down (M) vs button-up (m) -static wchar_t* s_rgSgrTestOutput[] = { +static const wchar_t* s_rgSgrTestOutput[] = { L"\x1b[<%d;1;1M", L"\x1b[<%d;1;2M", L"\x1b[<%d;2;2M", @@ -113,7 +113,7 @@ public: // Routine Description: // Constructs a string from s_rgDefaultTestOutput with the third char // correctly filled in to match uiButton. - wchar_t* BuildDefaultTestOutput(wchar_t* pwchTestOutput, unsigned int uiButton, short sModifierKeystate, short sScrollDelta) + wchar_t* BuildDefaultTestOutput(const wchar_t* pwchTestOutput, unsigned int uiButton, short sModifierKeystate, short sScrollDelta) { Log::Comment(NoThrowString().Format(L"Input Test Output:\'%s\'", pwchTestOutput)); // Copy the expected output into the buffer @@ -136,7 +136,7 @@ public: // Routine Description: // Constructs a string from s_rgSgrTestOutput with the third and last chars // correctly filled in to match uiButton. - wchar_t* BuildSGRTestOutput(wchar_t* pwchTestOutput, unsigned int uiButton, short sModifierKeystate, short sScrollDelta) + wchar_t* BuildSGRTestOutput(const wchar_t* pwchTestOutput, unsigned int uiButton, short sModifierKeystate, short sScrollDelta) { ClearTestBuffer(); diff --git a/src/terminal/parser/ft_fuzzer/VTCommandFuzzer.cpp b/src/terminal/parser/ft_fuzzer/VTCommandFuzzer.cpp index 5a61e49f6..484b8fbda 100644 --- a/src/terminal/parser/ft_fuzzer/VTCommandFuzzer.cpp +++ b/src/terminal/parser/ft_fuzzer/VTCommandFuzzer.cpp @@ -112,7 +112,7 @@ std::string GenerateWhiteSpaceToken() std::string GenerateTextToken() { - const LPSTR tokens[] = { + const LPCSTR tokens[] = { "The cow jumped over the moon.", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?", @@ -134,14 +134,14 @@ std::string GenerateTextToken() std::string GenerateInvalidToken() { - const LPSTR tokens[]{ ":", "'", "\"", "\\" }; + const LPCSTR tokens[]{ ":", "'", "\"", "\\" }; return std::string(CFuzzChance::SelectOne(tokens, ARRAYSIZE(tokens))); } std::string GenerateFuzzedToken( __in_ecount(cmap) const _fuzz_type_entry* map, __in DWORD cmap, - __in_ecount(ctokens) const LPSTR* tokens, + __in_ecount(ctokens) const LPCSTR* tokens, __in DWORD ctokens) { std::string csis[] = { CSI, C1CSI }; @@ -165,7 +165,7 @@ std::string GenerateFuzzedToken( std::string GenerateFuzzedOscToken( __in_ecount(cmap) const _fuzz_type_entry* map, __in DWORD cmap, - __in_ecount(ctokens) const LPSTR* tokens, + __in_ecount(ctokens) const LPCSTR* tokens, __in DWORD ctokens) { std::string s(OSC); @@ -227,7 +227,7 @@ std::string GenerateSGRToken() 49, }; - const LPSTR tokens[] = { "m" }; + const LPCSTR tokens[] = { "m" }; const _fuzz_type_entry map[] = { { 40, [&](std::string) { std::string s; AppendFormat(s, "%02d", CFuzzChance::SelectOne(psValid, ARRAYSIZE(psValid))); return s; } }, { 10, [](std::string) { std::string s; AppendFormat(s, "%d", CFuzzChance::GetRandom()); return s; } }, @@ -242,7 +242,7 @@ std::string GenerateSGRToken() // For example, moving the cursor to the next line, previous line, up, down, etc. std::string GenerateCUXToken() { - const LPSTR tokens[] = { "A", "B", "C", "D", "E", "F", "G" }; + const LPCSTR tokens[] = { "A", "B", "C", "D", "E", "F", "G" }; const _fuzz_type_entry map[] = { { 25, [](std::string) { std::string s; AppendFormat(s, "%d", CFuzzChance::GetRandom()); return s; } }, { 25, [](std::string) { std::string s; AppendFormat(s, "%d", CFuzzChance::GetRandom()); return s; } } @@ -255,7 +255,7 @@ std::string GenerateCUXToken() // Differs from other cursor functions since these are ESC sequences and not CSI sequences. std::string GenerateCUXToken2() { - const LPSTR tokens[] = { "7", "8" }; + const LPCSTR tokens[] = { "7", "8" }; std::string cux(ESC); cux += GenerateTokenLowProbability(); cux += CFuzzChance::SelectOne(tokens, ARRAYSIZE(tokens)); @@ -266,7 +266,7 @@ std::string GenerateCUXToken2() // Cursor positioning with two arguments std::string GenerateCUXToken3() { - const LPSTR tokens[]{ "H" }; + const LPCSTR tokens[]{ "H" }; const _fuzz_type_entry map[] = { { 60, [](std::string) { std::string s; AppendFormat(s, "%d;%d", CFuzzChance::GetRandom(), CFuzzChance::GetRandom()); return s; } }, // 60% give us two numbers in the valid range { 10, [](std::string) { return std::string(";"); } }, // 10% give us just a ; @@ -281,7 +281,7 @@ std::string GenerateCUXToken3() // Hard Reset (has no args) std::string GenerateHardResetToken() { - const LPSTR tokens[] = { "c" }; + const LPCSTR tokens[] = { "c" }; std::string cux(ESC); cux += GenerateTokenLowProbability(); cux += CFuzzChance::SelectOne(tokens, ARRAYSIZE(tokens)); @@ -292,7 +292,7 @@ std::string GenerateHardResetToken() // Soft Reset (has no args) std::string GenerateSoftResetToken() { - const LPSTR tokens[] = { "p" }; + const LPCSTR tokens[] = { "p" }; std::string cux(CSI); cux += GenerateTokenLowProbability(); cux += CFuzzChance::SelectOne(tokens, ARRAYSIZE(tokens)); @@ -304,7 +304,7 @@ std::string GenerateSoftResetToken() // enabling mouse mode, changing to the alt buffer, blinking the cursor, etc. std::string GeneratePrivateModeParamToken() { - const LPSTR tokens[] = { "h", "l" }; + const LPCSTR tokens[] = { "h", "l" }; const _fuzz_type_entry map[] = { { 12, [](std::string) { std::string s; AppendFormat(s, "?%02d", CFuzzChance::GetRandom()); return s; } }, { 8, [](std::string) { return std::string("?1"); } }, @@ -327,7 +327,7 @@ std::string GeneratePrivateModeParamToken() // Erase sequences, valid numerical values are 0-2. If no numeric value is specified, 0 is assumed. std::string GenerateEraseToken() { - const LPSTR tokens[] = { "J", "K" }; + const LPCSTR tokens[] = { "J", "K" }; const _fuzz_type_entry map[] = { { 9, [](std::string) { return std::string(""); } }, { 25, [](std::string) { return std::string("0"); } }, @@ -343,7 +343,7 @@ std::string GenerateEraseToken() // Device Attributes std::string GenerateDeviceAttributesToken() { - const LPSTR tokens[] = { "c" }; + const LPCSTR tokens[] = { "c" }; const _fuzz_type_entry map[] = { { 70, [](std::string) { return std::string(""); } }, // 70% leave it blank (valid) { 29, [](std::string) { return std::string("0"); } }, // 29% put in a 0 (valid) @@ -356,7 +356,7 @@ std::string GenerateDeviceAttributesToken() // Device Attributes std::string GenerateDeviceStatusReportToken() { - const LPSTR tokens[] = { "n" }; + const LPCSTR tokens[] = { "n" }; const _fuzz_type_entry map[] = { { 50, [](std::string) { return std::string("6"); } }, // 50% of the time, give us the one we were looking for (6, cursor report) { 49, [](std::string) { std::string s; AppendFormat(s, "%02d", CFuzzChance::GetRandom()); return s; } } // 49% of the time, put in a random value @@ -369,7 +369,7 @@ std::string GenerateDeviceStatusReportToken() // Scroll sequences, valid numeric values include 0-16384. std::string GenerateScrollToken() { - const LPSTR tokens[] = { "S", "T" }; + const LPCSTR tokens[] = { "S", "T" }; const _fuzz_type_entry map[] = { { 5, [](std::string) { std::string s; AppendFormat(s, "%08d", CFuzzChance::GetRandom()); return s; } }, { 5, [](std::string) { std::string s; AppendFormat(s, "%08d", CFuzzChance::GetRandom()); return s; } }, @@ -383,7 +383,7 @@ std::string GenerateScrollToken() // Resize sequences, valid numeric values include 0-16384. std::string GenerateResizeToken() { - const LPSTR tokens[] = { "t" }; + const LPCSTR tokens[] = { "t" }; // 5% - generate a random window manipulation with 1 params // 5% - generate a random window manipulation with 2 params // 5% - generate a random window manipulation with no params @@ -406,7 +406,7 @@ std::string GenerateResizeToken() // and BEL terminated. std::string GenerateOscTitleToken() { - const LPSTR tokens[] = { "\x7" }; + const LPCSTR tokens[] = { "\x7" }; const _fuzz_type_entry map[] = { { 100, [](std::string) { @@ -435,7 +435,7 @@ std::string GenerateOscTitleToken() // and BEL terminated. std::string GenerateOscColorTableToken() { - const LPSTR tokens[] = { "\x7", "\x1b\\" }; + const LPCSTR tokens[] = { "\x7", "\x1b\\" }; const _fuzz_type_entry map[] = { { 100, [](std::string) { @@ -515,7 +515,7 @@ std::string GenerateOscColorTableToken() // VT52 sequences without parameters. std::string GenerateVt52Token() { - const LPSTR tokens[] = { "A", "B", "C", "D", "F", "G", "H", "I", "J", "K", "Z", "<" }; + const LPCSTR tokens[] = { "A", "B", "C", "D", "F", "G", "H", "I", "J", "K", "Z", "<" }; std::string cux(ESC); cux += GenerateTokenLowProbability(); cux += CFuzzChance::SelectOne(tokens, ARRAYSIZE(tokens)); @@ -525,7 +525,7 @@ std::string GenerateVt52Token() // VT52 direct cursor address sequence with parameters. std::string GenerateVt52CursorAddressToken() { - const LPSTR tokens[] = { "Y" }; + const LPCSTR tokens[] = { "Y" }; std::string cux(ESC); cux += GenerateTokenLowProbability(); cux += CFuzzChance::SelectOne(tokens, ARRAYSIZE(tokens)); @@ -540,7 +540,7 @@ std::string GenerateVt52CursorAddressToken() // followed by a ";", followed by a string, and BEL terminated. std::string GenerateOscHyperlinkToken() { - const LPSTR tokens[] = { "\x7" }; + const LPCSTR tokens[] = { "\x7" }; const _fuzz_type_entry map[] = { { 100, [](std::string) { diff --git a/src/terminal/parser/ft_fuzzer/fuzzing_directed.h b/src/terminal/parser/ft_fuzzer/fuzzing_directed.h index 1095d7f06..aef4f3fb2 100644 --- a/src/terminal/parser/ft_fuzzer/fuzzing_directed.h +++ b/src/terminal/parser/ft_fuzzer/fuzzing_directed.h @@ -898,7 +898,7 @@ namespace fuzz _Type operator->() const throw() { - return (this->m_fFuzzed) ? this->m_t : m_tInit; + return (this->m_fFuzzed) ? this->m_t : CFuzzType<_Type, _Args...>::m_tInit; } // This operator makes it possible to invoke the fuzzing map @@ -909,7 +909,7 @@ namespace fuzz // the logic of the fuzz map). __inline void operator()() throw() { - GetValueFromMap(); + CFuzzType<_Type, _Args...>::GetValueFromMap(); } }; @@ -960,7 +960,7 @@ namespace fuzz __inline virtual _Type** operator&() throw() { m_ftEffectiveTraits |= TRAIT_TRANSFER_ALLOCATION; - return (this->m_fFuzzed) ? &(this->m_t) : &m_tInit; + return (this->m_fFuzzed) ? &(this->m_t) : &CFuzzType<_Type, _Args...>::m_tInit; } private: @@ -1087,7 +1087,7 @@ namespace fuzz int iLow = iHigh - (r.range.iHigh - r.range.iLow); if (iLow <= wRandom && wRandom < iHigh) { - this->m_t |= CallFuzzMapFunction(r.fte.pfnFuzz, this->m_tInit, m_tArgs); + this->m_t |= CallFuzzMapFunction(r.fte.pfnFuzz, this->m_tInit, CFuzzType<_Type, _Args...>::m_tArgs); } } } diff --git a/src/terminal/parser/ft_fuzzer/fuzzing_logic.h b/src/terminal/parser/ft_fuzzer/fuzzing_logic.h index 888a8b2bb..746d7d2f2 100644 --- a/src/terminal/parser/ft_fuzzer/fuzzing_logic.h +++ b/src/terminal/parser/ft_fuzzer/fuzzing_logic.h @@ -38,12 +38,12 @@ namespace fuzz { if (rcch > 1) { - const LPWSTR rgFormatStringChars[] = { L"%n", L"%s", L"%d" }; + const PCWSTR rgFormatStringChars[] = { L"%n", L"%s", L"%d" }; size_t cbDestSize = 2 * sizeof(WCHAR); memcpy_s( &(pwsz[CFuzzChance::GetRandom(rcch - 1)]), // -1 because we are writing 2 chars cbDestSize, - CFuzzChance::SelectOne(rgFormatStringChars, ARRAYSIZE(rgFormatStringChars)), + CFuzzChance::SelectOne(rgFormatStringChars, ARRAYSIZE(rgFormatStringChars)), cbDestSize); } @@ -56,12 +56,12 @@ namespace fuzz { if (rcch > 1) { - const LPSTR rgFormatStringChars[] = { "%n", "%s", "%d" }; + const LPCSTR rgFormatStringChars[] = { "%n", "%s", "%d" }; size_t cbDestSize = 2 * sizeof(CHAR); memcpy_s( &(psz[CFuzzChance::GetRandom(rcch - 1)]), cbDestSize, - CFuzzChance::SelectOne(rgFormatStringChars, ARRAYSIZE(rgFormatStringChars)), + CFuzzChance::SelectOne(rgFormatStringChars, ARRAYSIZE(rgFormatStringChars)), cbDestSize); } @@ -238,12 +238,40 @@ namespace fuzz return _strrev(psz); } + template + class CFuzzLogic; + + // Flips a random byte value within the buffer. + template + static _Type* _fz_flipByte(__inout_ecount(rcelms) _Type* p, __inout size_t& rcelms) + { + if (rcelms > 0) + { + return reinterpret_cast<_Type*>(CFuzzLogic<>::FuzzArrayElement( + reinterpret_cast(p), (rcelms) * sizeof(_Type))); + } + + return p; + } + + // Flips a random entry value within the buffer + template + static _Type* _fz_flipEntry(__inout_ecount(rcelms) _Type* p, __inout size_t& rcelms) + { + if (rcelms > 0) + { + return CFuzzLogic<>::FuzzArrayElement(p, rcelms); + } + + return p; + } + // Contains fuzzing logic based upon a variety of default scenarios. The // idea is to capture and make available a comprehensive fuzzing library // that does not require external modules or complex setup. This should // make fuzzing easier to implement and test, as well as more explicit // with regard to what fuzzing manipulations are possible. - template + template class CFuzzLogic { public: @@ -429,31 +457,6 @@ namespace fuzz } }; - // Flips a random byte value within the buffer. - template - static _Type* _fz_flipByte(__inout_ecount(rcelms) _Type* p, __inout size_t& rcelms) - { - if (rcelms > 0) - { - return reinterpret_cast<_Type*>(CFuzzLogic<>::FuzzArrayElement( - reinterpret_cast(p), (rcelms) * sizeof(_Type))); - } - - return p; - } - - // Flips a random entry value within the buffer - template - static _Type* _fz_flipEntry(__inout_ecount(rcelms) _Type* p, __inout size_t& rcelms) - { - if (rcelms > 0) - { - return CFuzzLogic<>::FuzzArrayElement(p, rcelms); - } - - return p; - } - static char* _fz_sz_tokenizeSpaces(__in char* psz) { const _fuzz_type_entry repeatMap[] = { diff --git a/src/types/inc/viewport.hpp b/src/types/inc/viewport.hpp index 23f3d3e55..6c23d4918 100644 --- a/src/types/inc/viewport.hpp +++ b/src/types/inc/viewport.hpp @@ -121,6 +121,16 @@ namespace Microsoft::Console::Types [[nodiscard]] static SomeViewports Subtract(const Viewport& original, const Viewport& removeMe) noexcept; + constexpr bool operator==(const Viewport& other) const noexcept + { + return _sr == other._sr; + } + + constexpr bool operator!=(const Viewport& other) const noexcept + { + return _sr != other._sr; + } + private: Viewport(const SMALL_RECT sr) noexcept; @@ -142,15 +152,3 @@ inline COORD operator-(const COORD& c) noexcept { return { -c.X, -c.Y }; } - -inline bool operator==(const Microsoft::Console::Types::Viewport& a, - const Microsoft::Console::Types::Viewport& b) noexcept -{ - return a.ToInclusive() == b.ToInclusive(); -} - -inline bool operator!=(const Microsoft::Console::Types::Viewport& a, - const Microsoft::Console::Types::Viewport& b) noexcept -{ - return !(a == b); -} diff --git a/src/winconpty/ft_pty/ConPtyTests.cpp b/src/winconpty/ft_pty/ConPtyTests.cpp index e4f8a0925..033ef7388 100644 --- a/src/winconpty/ft_pty/ConPtyTests.cpp +++ b/src/winconpty/ft_pty/ConPtyTests.cpp @@ -22,44 +22,48 @@ class ConPtyTests TEST_METHOD(DiesOnClose); }; -HRESULT _CreatePseudoConsole(const COORD size, - const HANDLE hInput, - const HANDLE hOutput, - const DWORD dwFlags, - _Inout_ PseudoConsole* pPty) +static HRESULT _CreatePseudoConsole(const COORD size, + const HANDLE hInput, + const HANDLE hOutput, + const DWORD dwFlags, + _Inout_ PseudoConsole* pPty) { return _CreatePseudoConsole(INVALID_HANDLE_VALUE, size, hInput, hOutput, dwFlags, pPty); } -HRESULT AttachPseudoConsole(HPCON hPC, LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList) +static HRESULT AttachPseudoConsole(HPCON hPC, std::wstring& command, PROCESS_INFORMATION* ppi) { - BOOL fSuccess = UpdateProcThreadAttribute(lpAttributeList, - 0, - PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, - hPC, - sizeof(HANDLE), - nullptr, - nullptr); - return fSuccess ? S_OK : HRESULT_FROM_WIN32(GetLastError()); -} + SIZE_T size = 0; + InitializeProcThreadAttributeList(nullptr, 1, 0, &size); + RETURN_LAST_ERROR_IF(size == 0); -void _CreateChildProcess(std::wstring& command, STARTUPINFOEXW* psiEx, PROCESS_INFORMATION* ppi) -{ - std::unique_ptr mutableCommandline = std::make_unique(command.length() + 1); - VERIFY_IS_NOT_NULL(mutableCommandline); - VERIFY_SUCCEEDED(StringCchCopyW(mutableCommandline.get(), command.length() + 1, command.c_str())); - VERIFY_IS_TRUE(CreateProcessW( + const auto buffer = std::make_unique(gsl::narrow_cast(size)); + + STARTUPINFOEXW siEx{}; + siEx.StartupInfo.cb = sizeof(STARTUPINFOEXW); + siEx.lpAttributeList = reinterpret_cast(buffer.get()); + + RETURN_IF_WIN32_BOOL_FALSE(InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, &size)); + auto deleteAttrList = wil::scope_exit([&] { + DeleteProcThreadAttributeList(siEx.lpAttributeList); + }); + + RETURN_IF_WIN32_BOOL_FALSE(UpdateProcThreadAttribute(siEx.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, hPC, sizeof(HANDLE), nullptr, nullptr)); + + RETURN_IF_WIN32_BOOL_FALSE(CreateProcessW( nullptr, - mutableCommandline.get(), + command.data(), nullptr, // lpProcessAttributes nullptr, // lpThreadAttributes true, // bInheritHandles EXTENDED_STARTUPINFO_PRESENT, // dwCreationFlags nullptr, // lpEnvironment nullptr, // lpCurrentDirectory - &psiEx->StartupInfo, // lpStartupInfo + &siEx.StartupInfo, // lpStartupInfo ppi // lpProcessInformation )); + + return S_OK; } void ConPtyTests::CreateConPtyNoPipes() @@ -200,27 +204,9 @@ void ConPtyTests::SurvivesOnBreakInput() VERIFY_IS_TRUE(GetExitCodeProcess(pty.hConPtyProcess, &dwExit)); VERIFY_ARE_EQUAL(dwExit, (DWORD)STILL_ACTIVE); - STARTUPINFOEXW siEx; - siEx = { 0 }; - siEx.StartupInfo.cb = sizeof(STARTUPINFOEXW); - size_t size; - VERIFY_IS_FALSE(InitializeProcThreadAttributeList(NULL, 1, 0, (PSIZE_T)&size)); - BYTE* attrList = new BYTE[size]; - auto freeAttrList = wil::scope_exit([&] { - delete[] attrList; - }); - - siEx.lpAttributeList = reinterpret_cast(attrList); - VERIFY_IS_TRUE(InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, (PSIZE_T)&size)); - auto deleteAttrList = wil::scope_exit([&] { - DeleteProcThreadAttributeList(siEx.lpAttributeList); - }); - VERIFY_SUCCEEDED( - AttachPseudoConsole(reinterpret_cast(&pty), siEx.lpAttributeList)); - wil::unique_process_information piClient; std::wstring realCommand = L"cmd.exe"; - _CreateChildProcess(realCommand, &siEx, piClient.addressof()); + VERIFY_SUCCEEDED(AttachPseudoConsole(&pty, realCommand, piClient.addressof())); VERIFY_IS_TRUE(GetExitCodeProcess(piClient.hProcess, &dwExit)); VERIFY_ARE_EQUAL(dwExit, (DWORD)STILL_ACTIVE); @@ -263,27 +249,9 @@ void ConPtyTests::SurvivesOnBreakOutput() VERIFY_IS_TRUE(GetExitCodeProcess(pty.hConPtyProcess, &dwExit)); VERIFY_ARE_EQUAL(dwExit, (DWORD)STILL_ACTIVE); - STARTUPINFOEXW siEx; - siEx = { 0 }; - siEx.StartupInfo.cb = sizeof(STARTUPINFOEXW); - size_t size; - VERIFY_IS_FALSE(InitializeProcThreadAttributeList(NULL, 1, 0, (PSIZE_T)&size)); - BYTE* attrList = new BYTE[size]; - auto freeAttrList = wil::scope_exit([&] { - delete[] attrList; - }); - - siEx.lpAttributeList = reinterpret_cast(attrList); - VERIFY_IS_TRUE(InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, (PSIZE_T)&size)); - auto deleteAttrList = wil::scope_exit([&] { - DeleteProcThreadAttributeList(siEx.lpAttributeList); - }); - VERIFY_SUCCEEDED( - AttachPseudoConsole(reinterpret_cast(&pty), siEx.lpAttributeList)); - wil::unique_process_information piClient; std::wstring realCommand = L"cmd.exe"; - _CreateChildProcess(realCommand, &siEx, piClient.addressof()); + VERIFY_SUCCEEDED(AttachPseudoConsole(&pty, realCommand, piClient.addressof())); VERIFY_IS_TRUE(GetExitCodeProcess(piClient.hProcess, &dwExit)); VERIFY_ARE_EQUAL(dwExit, (DWORD)STILL_ACTIVE); @@ -326,27 +294,9 @@ void ConPtyTests::DiesOnBreakBoth() VERIFY_IS_TRUE(GetExitCodeProcess(pty.hConPtyProcess, &dwExit)); VERIFY_ARE_EQUAL(dwExit, (DWORD)STILL_ACTIVE); - STARTUPINFOEXW siEx; - siEx = { 0 }; - siEx.StartupInfo.cb = sizeof(STARTUPINFOEXW); - size_t size; - VERIFY_IS_FALSE(InitializeProcThreadAttributeList(NULL, 1, 0, (PSIZE_T)&size)); - BYTE* attrList = new BYTE[size]; - auto freeAttrList = wil::scope_exit([&] { - delete[] attrList; - }); - - siEx.lpAttributeList = reinterpret_cast(attrList); - VERIFY_IS_TRUE(InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, (PSIZE_T)&size)); - auto deleteAttrList = wil::scope_exit([&] { - DeleteProcThreadAttributeList(siEx.lpAttributeList); - }); - VERIFY_SUCCEEDED( - AttachPseudoConsole(reinterpret_cast(&pty), siEx.lpAttributeList)); - wil::unique_process_information piClient; std::wstring realCommand = L"cmd.exe"; - _CreateChildProcess(realCommand, &siEx, piClient.addressof()); + VERIFY_SUCCEEDED(AttachPseudoConsole(&pty, realCommand, piClient.addressof())); VERIFY_IS_TRUE(GetExitCodeProcess(piClient.hProcess, &dwExit)); VERIFY_ARE_EQUAL(dwExit, (DWORD)STILL_ACTIVE); @@ -415,27 +365,9 @@ void ConPtyTests::DiesOnClose() VERIFY_IS_TRUE(GetExitCodeProcess(pty.hConPtyProcess, &dwExit)); VERIFY_ARE_EQUAL(dwExit, (DWORD)STILL_ACTIVE); - STARTUPINFOEXW siEx; - siEx = { 0 }; - siEx.StartupInfo.cb = sizeof(STARTUPINFOEXW); - size_t size; - VERIFY_IS_FALSE(InitializeProcThreadAttributeList(NULL, 1, 0, (PSIZE_T)&size)); - BYTE* attrList = new BYTE[size]; - auto freeAttrList = wil::scope_exit([&] { - delete[] attrList; - }); - - siEx.lpAttributeList = reinterpret_cast(attrList); - VERIFY_IS_TRUE(InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, (PSIZE_T)&size)); - auto deleteAttrList = wil::scope_exit([&] { - DeleteProcThreadAttributeList(siEx.lpAttributeList); - }); - VERIFY_SUCCEEDED( - AttachPseudoConsole(reinterpret_cast(&pty), siEx.lpAttributeList)); - wil::unique_process_information piClient; - std::wstring realCommand = testCommandline; - _CreateChildProcess(realCommand, &siEx, piClient.addressof()); + std::wstring realCommand(reinterpret_cast(testCommandline.GetBuffer()), testCommandline.GetLength()); + VERIFY_SUCCEEDED(AttachPseudoConsole(&pty, realCommand, piClient.addressof())); VERIFY_IS_TRUE(GetExitCodeProcess(piClient.hProcess, &dwExit)); VERIFY_ARE_EQUAL(dwExit, (DWORD)STILL_ACTIVE);