From b0e4be7abd4ee75751c3178c445f3e18500cd5bc Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 12 May 2026 11:15:19 -0500 Subject: [PATCH] sixel: prevent allocating an absurd amount of memory or writing OOB (#20213) This commit implements two fixes for the integer overflow/out-of-bounds write reported in #20149. First, it catches any exception generated in sixel char processing (which will prevent `out_of_memory` or `bad_alloc` from being ignored sight-unseen, and will prevent the consumption of further DCS content). Second, it prevents us from allocating memory for an image which will never be displayed (because it exceeds the height of the display.) This supersedes prior work in #20153 for the same issues. Closes #20149 Closes #20153 Co-authored-by: James Holderness (cherry picked from commit c829d4ca548337b515e7f16a6743fda532e013f4) Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgrY_zQ Service-Version: 1.25 --- src/terminal/adapter/SixelParser.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/terminal/adapter/SixelParser.cpp b/src/terminal/adapter/SixelParser.cpp index e23c23d1e6..9273f7dcc3 100644 --- a/src/terminal/adapter/SixelParser.cpp +++ b/src/terminal/adapter/SixelParser.cpp @@ -90,7 +90,15 @@ std::function SixelParser::DefineImage(const VTInt macroParameter _state = States::Normal; _parameters.clear(); return [&](const auto ch) { - _parseCommandChar(ch); + try + { + _parseCommandChar(ch); + } + catch (...) + { + // Ignore all further content. + return false; + } return true; }; } @@ -234,10 +242,18 @@ void SixelParser::_executeNextLine() _executeCarriageReturn(); _imageLineCount++; _maybeFlushImageBuffer(); - _imageCursor.y += _sixelHeight; - _availablePixelHeight -= _sixelHeight; - _resizeImageBuffer(_sixelHeight); - _fillImageBackgroundWhenScrolled(); + // If we don't have any available pixel height, that means the image has + // extended beyond the bottom of the display and we haven't triggered a + // a scroll (because sixel display mode is enabled). In this state, there + // is no point in extending the image any further, because the additional + // content will never be seen, so we'll just be wasting memory. + if (_availablePixelHeight > 0) + { + _imageCursor.y += _sixelHeight; + _availablePixelHeight -= _sixelHeight; + _resizeImageBuffer(_sixelHeight); + _fillImageBackgroundWhenScrolled(); + } } void SixelParser::_executeMoveToHome()