terminal/src/host
James Holderness 55151a4a04
Refactor VT parameter handling (#7799)
This PR introduces a pair of classes for managing VT parameters that
automatically handle range checking and default fallback values, so the
individual operations don't have to do that validation themselves. In
addition to simplifying the code, this fixes a few cases where we were
mishandling missing or extraneous parameters, and adds support for
parameter sequences on commands that couldn't previously handle them.
This PR also sets a limit on the number of parameters allowed, to help
thwart DoS memory consumption attacks.

## References

* The new parameter class also introduces the concept of an
  omitted/default parameter which is not necessarily zero, which is a
  prerequisite for addressing issue #4417.

## Detailed Description of the Pull Request / Additional comments

There are two new classes provide by this PR: a `VTParameter` class,
similar in function to a `std::optional<size_t>`, which holds an
individual parameter (which may be an omitted/default value); and a
`VTParameters` class, similar in function to `gsl:span<VTParameter>`,
which holds a sequence of those parameters.

Where `VTParameter` differs from `std::optional` is with the inclusion
of two cast operators. There is a `size_t` cast that interprets omitted
and zero values as 1 (the expected behaviour for most numeric
parameters). And there is a generic cast, for use with the enum
parameter types, which interprets omitted values as 0 (the expected
behaviour for most selective parameters).

The advantage of `VTParameters` class is that it has an `at` method that
can never fail - out of range values simply return the a default
`VTParameter` instance (this is standard behaviour in VT terminals). It
also has a `size` method that will always return a minimum count of 1,
since an empty parameter list is typically the equivalent of a single
"default" parameter, so this guarantees you'll get at least one value
when iterating over the list with `size()`.

For cases where we just need to call the same dispatch method for every
parameter, there is a helper `for_each` method, which repeatedly calls a
given predicate function with each value in the sequence. It also
collates the returned success values to determine the overall result of
the sequence. As with the `size` method, this will always make at least
one call, so it correctly handles empty sequences.

With those two classes in place, we could get rid of all the parameter
validation and default handling code in the `OutputStateMachineEngine`.
We now just use the `VTParameters::at` method to grab a parameter and
typically pass it straight to the appropriate dispatch method, letting
the cast operators automatically handle the assignment of default
values. Occasionally we might need a `value_or` call to specify a
non-standard default value, but those cases are fairly rare.

In some case the `OutputStateMachineEngine` was also checking whether
parameters values were in range, but for the most part this shouldn't
have been necessary, since that is something the dispatch classes would
already have been doing themselves (in the few cases that they weren't,
I've now updated them to do so).

I've also updated the `InputStateMachineEngine` in a similar way to the
`OutputStateMachineEngine`, getting rid of a few of the parameter
extraction methods, and simplifying other parts of the implementation.
It's not as clean a replacement as the output engine, but there are
still benefits in using the new classes.

## Validation Steps Performed

For the most part I haven't had to alter existing tests other than
accounting for changes to the API. There were a couple of tests I needed
to drop because they were checking for failure cases which shouldn't
have been failing (unexpected parameters should never be an error), or
testing output engine validation that is no longer handled at that
level.

I've added a few new tests to cover operations that take sequences of
selective parameters (`ED`, `EL`, `TBC`, `SM`, and `RM`). And I've
extended the cursor movement tests to make sure those operations can
handle extraneous parameters that weren't expected. I've also added a
test to verify that the state machine will correctly ignore parameters
beyond the maximum 32 parameter count limit.

I've also manual confirmed that the various test cases given in issues
#2101 are now working as expected.

Closes #2101
2020-10-15 16:12:52 +00:00
..
dll Unify and clean up the common build properties (#3429) 2019-11-05 14:29:11 -08:00
exe Merged PR 4641914: [Git2Git] Git Train: Merge of building/rs_onecore_dep_uxp/200504-1008 into official/rs_onecore_dep_uxp Retrieved from https://microsoft.visualstudio.com os OS official/rs_onecore_dep_uxp bbdf04608ba96c3f8ee06cf100428cde01f3df79 2020-05-05 22:47:08 +00:00
ft_host Improve the legacy color conversions (#6358) 2020-06-08 19:05:06 +00:00
ft_integrity Fix a bunch of spelling errors across the project (#4295) 2020-02-10 20:40:01 +00:00
ft_uia Helix Testing (#6992) 2020-08-18 18:23:24 +00:00
lib Migrate Search module as a shared component for Terminal Search (#3279) 2019-11-14 14:36:41 -08:00
ut_host Refactor VT parameter handling (#7799) 2020-10-15 16:12:52 +00:00
ut_lib Unify and clean up the common build properties (#3429) 2019-11-05 14:29:11 -08:00
_output.cpp Replace basic_string_view<T> with span<const T> (#6921) 2020-07-15 16:40:42 +00:00
_output.h Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
_stream.cpp Reintroduce a color compatibility hack, but only for PowerShells (#6810) 2020-07-10 15:25:39 -07:00
_stream.h Reintroduce a color compatibility hack, but only for PowerShells (#6810) 2020-07-10 15:25:39 -07:00
alias.cpp Replace gsl::at with a new til::at(span) for pre-checked bounds (#6925) 2020-07-15 10:29:36 -07:00
alias.h add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
ApiRoutines.h Replace basic_string_view<T> with span<const T> (#6921) 2020-07-15 16:40:42 +00:00
cmdline.cpp Improve the legacy color conversions (#6358) 2020-06-08 19:05:06 +00:00
cmdline.h Improve the legacy color conversions (#6358) 2020-06-08 19:05:06 +00:00
CommandListPopup.cpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
CommandListPopup.hpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
CommandNumberPopup.cpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
CommandNumberPopup.hpp Add explicit identifier to some constructors (#5652) 2020-04-29 16:50:47 -07:00
conapi.h Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
conareainfo.cpp Replace basic_string_view<T> with span<const T> (#6921) 2020-07-15 16:40:42 +00:00
conareainfo.h Improve the legacy color conversions (#6358) 2020-06-08 19:05:06 +00:00
conattrs.cpp Improve the propagation of color attributes over ConPTY (#6506) 2020-07-01 11:10:36 -07:00
conddkrefs.h add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
conhost.rcv Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
conhostv2_traceviewpp.tvpp Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
conimeinfo.cpp Make sure we don't hide the cursor until the IME starts (#7673) 2020-09-18 19:25:39 +00:00
conimeinfo.h Replace basic_string_view<T> with span<const T> (#6921) 2020-07-15 16:40:42 +00:00
conserv.h add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
ConsoleArguments.cpp Add support for win32-input-mode to conhost, ConPTY, Terminal (#6309) 2020-06-08 22:31:28 +00:00
ConsoleArguments.hpp Add support for win32-input-mode to conhost, ConPTY, Terminal (#6309) 2020-06-08 22:31:28 +00:00
consoleInformation.cpp Add support for the "blink" graphic rendition attribute (#7490) 2020-09-21 23:21:33 +00:00
conv.h add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
convarea.cpp Make sure we don't hide the cursor until the IME starts (#7673) 2020-09-18 19:25:39 +00:00
conwinuserrefs.h add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
CopyFromCharPopup.cpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
CopyFromCharPopup.hpp Add explicit identifier to some constructors (#5652) 2020-04-29 16:50:47 -07:00
CopyToCharPopup.cpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
CopyToCharPopup.hpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
CursorBlinker.cpp Add support for the "blink" graphic rendition attribute (#7490) 2020-09-21 23:21:33 +00:00
CursorBlinker.hpp Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
dbcs.cpp Replace gsl::at with a new til::at(span) for pre-checked bounds (#6925) 2020-07-15 10:29:36 -07:00
dbcs.h add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
directio.cpp Switch all DSR responses to appending instead of prepending (#7583) 2020-09-09 23:55:22 +00:00
directio.h Switch all DSR responses to appending instead of prepending (#7583) 2020-09-09 23:55:22 +00:00
dirs Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
exemain.cpp Change NULL to nullptr since they are pointers (#4960) 2020-03-20 20:35:12 +00:00
getset.cpp OSC 8 support for conhost and terminal (#7251) 2020-09-03 13:52:39 -04:00
getset.h OSC 8 support for conhost and terminal (#7251) 2020-09-03 13:52:39 -04:00
globals.cpp Implement a pair of shims for cls, Clear-Host in conpty mode (#5627) 2020-04-30 21:53:31 +00:00
globals.h Implement a pair of shims for cls, Clear-Host in conpty mode (#5627) 2020-04-30 21:53:31 +00:00
handle.cpp Removed using namespace directive from header files (#955) 2019-05-30 11:14:21 -07:00
handle.h Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
history.cpp Replace gsl::at with a new til::at(span) for pre-checked bounds (#6925) 2020-07-15 10:29:36 -07:00
history.h Replace macros with constexpr part 2 (#3416) 2019-11-04 07:37:47 -06:00
host-common.vcxitems Migrate Search module as a shared component for Terminal Search (#3279) 2019-11-14 14:36:41 -08:00
IIoProvider.hpp Fix a bunch of spelling errors across the project (#4295) 2020-02-10 20:40:01 +00:00
init.cpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
init.hpp Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
input.cpp ci: run spell check in CI, fix remaining issues (#4799) 2020-03-25 11:02:53 -07:00
input.h Replace macros with constexpr part 2 (#3416) 2019-11-04 07:37:47 -06:00
inputBuffer.cpp ci: run spell check in CI, fix remaining issues (#4799) 2020-03-25 11:02:53 -07:00
inputBuffer.hpp Move MouseInput from TermAdapter to TermInput (#4848) 2020-03-12 22:25:43 +00:00
inputKeyInfo.cpp Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
inputReadHandleData.cpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
inputReadHandleData.h add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
misc.cpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
misc.h add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
ntprivapi.cpp Change NULL to nullptr since they are pointers (#4960) 2020-03-20 20:35:12 +00:00
ntprivapi.hpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
output.cpp Improve conpty rendering of default colors in legacy apps (#6698) 2020-07-01 11:08:30 -07:00
output.h add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
outputStream.cpp Switch all DSR responses to appending instead of prepending (#7583) 2020-09-09 23:55:22 +00:00
outputStream.hpp Switch all DSR responses to appending instead of prepending (#7583) 2020-09-09 23:55:22 +00:00
popup.cpp Improve the legacy color conversions (#6358) 2020-06-08 19:05:06 +00:00
popup.h Improve the legacy color conversions (#6358) 2020-06-08 19:05:06 +00:00
precomp.cpp Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
precomp.h Replace old C headers (xxx.h) with modern ones (cxxx) (#5080) 2020-07-01 11:00:24 -07:00
PtySignalInputThread.cpp Fix a bunch of spelling errors across the project (#4295) 2020-02-10 20:40:01 +00:00
PtySignalInputThread.hpp Revert locking changes (#3488) 2019-11-08 13:44:52 -08:00
readData.cpp Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
readData.hpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
readDataCooked.cpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
readDataCooked.hpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
readDataDirect.cpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
readDataDirect.hpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
readDataRaw.cpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
readDataRaw.hpp Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
registry.cpp Fix a bunch of spelling errors across the project (#4295) 2020-02-10 20:40:01 +00:00
registry.hpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
renderData.cpp OSC 8 support for conhost and terminal (#7251) 2020-09-03 13:52:39 -04:00
renderData.hpp OSC 8 support for conhost and terminal (#7251) 2020-09-03 13:52:39 -04:00
renderFontDefaults.cpp Allow FontInfo{,Base,Desired} to store a font name > 32 wch (#3107) 2019-10-14 21:23:45 -07:00
renderFontDefaults.hpp Allow FontInfo{,Base,Desired} to store a font name > 32 wch (#3107) 2019-10-14 21:23:45 -07:00
res.rc Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
resource.h add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
runft.bat Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
runtests.bat Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
runut.bat Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
ScreenBufferRenderTarget.cpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
ScreenBufferRenderTarget.hpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
screenInfo.cpp When win32 is resizing the viewport, make sure Right > Left (#7768) 2020-09-28 15:46:45 -07:00
screenInfo.hpp Reintroduce a color compatibility hack, but only for PowerShells (#6810) 2020-07-10 15:25:39 -07:00
scrolling.cpp Accessibility: Set-up UIA Tree (#1691) 2019-07-29 15:21:15 -07:00
scrolling.hpp Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
selection.cpp Move rect expansion to textbuffer; refactor selection code (#4560) 2020-02-27 16:42:26 -08:00
selection.hpp Tie up some A11y loose threads (#6417) 2020-06-10 15:15:26 +00:00
selectionInput.cpp Improve the legacy color conversions (#6358) 2020-06-08 19:05:06 +00:00
selectionState.cpp Fix a bunch of spelling errors across the project (#4295) 2020-02-10 20:40:01 +00:00
server.h Add support for the "blink" graphic rendition attribute (#7490) 2020-09-21 23:21:33 +00:00
settings.cpp Add support for more OSC color formats (#7578) 2020-10-14 17:29:10 -07:00
settings.hpp Add support for the "blink" graphic rendition attribute (#7490) 2020-09-21 23:21:33 +00:00
sources.inc Merged PR 4988918: Reflect OS changes for LKG10 2020-07-30 22:55:57 +00:00
sources.test.inc Initial release of the Windows Terminal source code 2019-05-02 15:29:04 -07:00
srvinit.cpp Change NULL to nullptr since they are pointers (#4960) 2020-03-20 20:35:12 +00:00
srvinit.h add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
stream.cpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
stream.h add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
telemetry.cpp Replace old C headers (xxx.h) with modern ones (cxxx) (#5080) 2020-07-01 11:00:24 -07:00
telemetry.hpp Fix a bunch of spelling errors across the project (#4295) 2020-02-10 20:40:01 +00:00
tracing.cpp Tie up some A11y loose threads (#6417) 2020-06-10 15:15:26 +00:00
tracing.hpp UIA: Fix GetVisibleRanges() and add Tracing (#4495) 2020-02-20 23:50:43 +00:00
utf8ToWideCharParser.cpp Fix a bunch of spelling errors across the project (#4295) 2020-02-10 20:40:01 +00:00
utf8ToWideCharParser.hpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
utils.cpp add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
utils.hpp Fix a bunch of spelling errors across the project (#4295) 2020-02-10 20:40:01 +00:00
VtInputThread.cpp Enable Passthrough for VT Input Mode in ConPty (#4856) 2020-03-10 22:07:14 +00:00
VtInputThread.hpp Unify UTF-8 handling using til::u8u16 & revise WriteConsoleAImpl (#4422) 2020-02-03 18:06:55 -08:00
VtIo.cpp Improve the propagation of color attributes over ConPTY (#6506) 2020-07-01 11:10:36 -07:00
VtIo.hpp Add support for win32-input-mode to conhost, ConPTY, Terminal (#6309) 2020-06-08 22:31:28 +00:00
writeData.cpp Reintroduce a color compatibility hack, but only for PowerShells (#6810) 2020-07-10 15:25:39 -07:00
writeData.hpp Reintroduce a color compatibility hack, but only for PowerShells (#6810) 2020-07-10 15:25:39 -07:00