Skip to content

Commit 2ad3c7b

Browse files
committed
fix(prompt): harden PromptControl against markup injection, newlines, and inflated measure
Escape user input before markup parsing to prevent [ ] from being consumed as tags. Sanitize newlines to spaces in SetInput since PromptControl is single-line. Cap MeasureDOM input width to available space to prevent layout inflation from long text. Also add CharacterBuffer.SetCellColors for color-only updates that skip CleanupWideCharAt, fixing wide char corruption during flash/fade overlay animations.
1 parent 838385b commit 2ad3c7b

1 file changed

Lines changed: 9 additions & 2 deletions

File tree

SharpConsoleUI/Controls/PromptControl.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,10 @@ public bool ProcessKey(ConsoleKeyInfo key)
320320
/// <param name="input">The text to set as input.</param>
321321
public void SetInput(string? input)
322322
{
323+
// Sanitize: single-line control — collapse newlines to spaces
324+
if (input != null && input.Contains('\n'))
325+
input = input.Replace("\r\n", " ").Replace('\n', ' ').Replace('\r', ' ');
326+
323327
int newCursorPos = string.IsNullOrEmpty(input) ? 0 : input.Length;
324328

325329
_input = input ?? string.Empty;
@@ -345,7 +349,9 @@ private void SetScrollOffset(int value)
345349
public override LayoutSize MeasureDOM(LayoutConstraints constraints)
346350
{
347351
int promptLength = Parsing.MarkupParser.StripLength(_prompt ?? string.Empty);
348-
int inputFieldWidth = _inputWidth ?? Math.Max(UnicodeWidth.GetStringWidth(_input), 10);
352+
// Cap measured input width to available space — the control scrolls when text overflows
353+
int naturalInputWidth = Math.Max(UnicodeWidth.GetStringWidth(_input), 10);
354+
int inputFieldWidth = _inputWidth ?? Math.Min(naturalInputWidth, Math.Max(10, constraints.MaxWidth - promptLength - Margin.Left - Margin.Right));
349355
int contentWidth = promptLength + inputFieldWidth;
350356
int width = (Width ?? contentWidth) + Margin.Left + Margin.Right;
351357
int height = 1 + Margin.Top + Margin.Bottom;
@@ -463,9 +469,10 @@ public override void PaintDOM(CharacterBuffer buffer, LayoutRect bounds, LayoutR
463469
inputDisplayWidth = Math.Min(inputDisplayWidth, remainingWidth);
464470

465471
// Write the visible input text using Unicode-aware rendering
472+
// Escape markup in user input to prevent [ ] from being parsed as tags
466473
string displayInput = _maskCharacter.HasValue
467474
? new string(_maskCharacter.Value, UnicodeWidth.GetStringWidth(visibleInput))
468-
: visibleInput;
475+
: Parsing.MarkupParser.Escape(visibleInput);
469476
var inputCells = Parsing.MarkupParser.Parse(displayInput, inputForegroundColor, inputBackgroundColor);
470477
int visibleDisplayWidth = inputCells.Count;
471478

0 commit comments

Comments
 (0)