From c829d4ca548337b515e7f16a6743fda532e013f4 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 --- 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 959c6f2f30..1ffb48e390 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()