From 06824c0ae4b3ac63845d51db91dfaaa5905fa4f7 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Mon, 11 May 2026 17:44:08 -0500 Subject: [PATCH] sixel: prevent allocating an absurd amount of memory or writing OOB 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 959c6f2f307..1ffb48e3908 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()