Skip to content

Conversation

FrozenPandaz
Copy link
Collaborator

@FrozenPandaz FrozenPandaz commented Aug 11, 2025

Current Behavior

The TUI dependency view experiences buffer overflow panics when rendering scrollbars on small or constrained terminal sizes. Users encounter crashes with messages like "index outside of buffer" at various coordinates such as (134, 37), (86, 0), (107, 0), etc.

Expected Behavior

The TUI should handle all terminal sizes gracefully without crashing, maintaining proper visual rendering of scrollbars and padding elements while staying within buffer boundaries.

Key Code Changes

The fix adds clean, reusable helper functions for bounds checking to prevent buffer overflows:

1. New Helper Functions (lines 216-239):

/// Check if a rectangle fits within buffer boundaries
fn fits_in_buffer(area: &Rect, buf: &Buffer) -> bool {
    area.x + area.width <= buf.area().width && area.y < buf.area().height
}

/// Create a safe rectangle clamped to buffer boundaries
fn clamp_to_buffer(area: Rect, buf: &Buffer) -> Option<Rect> {
    if area.width == 0 || area.height == 0 {
        return None;
    }
    let safe_area = Rect {
        x: area.x,
        y: area.y,
        width: area.width.min(buf.area().width.saturating_sub(area.x)),
        height: area.height.min(buf.area().height.saturating_sub(area.y)),
    };
    if safe_area.width > 0 && safe_area.height > 0 { Some(safe_area) } else { None }
}

2. Simplified Scrollbar Bounds Check (lines 478-481):

// Render scrollbar with bounds checking
if let Some(safe_scrollbar_area) = Self::clamp_to_buffer(outer_area, buf) {
    scrollbar.render(safe_scrollbar_area, buf, &mut state.scrollbar_state);
}

3. Cleaner Padding Validation (lines 241-286):

fn render_scrollbar_padding(outer_area: Rect, buf: &mut Buffer, style: Style) {
    const PADDING_WIDTH: u16 = 2;
    const RIGHT_MARGIN: u16 = 3;
    const WIDTH_PADDING: u16 = 2;
    const TOTAL_WIDTH: u16 = PADDING_WIDTH + RIGHT_MARGIN + WIDTH_PADDING;

    // Early exit if area is too small or has no height
    if outer_area.width < TOTAL_WIDTH || outer_area.height == 0 {
        return;
    }
    
    // Use helper function for bounds checking
    if Self::fits_in_buffer(&top_area, buf) {
        // render top padding
    }
    if Self::fits_in_buffer(&bottom_area, buf) {
        // render bottom padding  
    }
}

Key improvements:

  • Reduced complexity: Scrollbar bounds checking went from 11 lines to 3 lines
  • Reusable helpers: fits_in_buffer() and clamp_to_buffer() can be used throughout the codebase
  • Named constants: Replaced magic numbers with descriptive constants
  • Clear intent: Function names clearly express what the code does

Related Issue(s)

This fixes buffer overflow panics that occur when the terminal user interface attempts to render scrollbar widgets and padding outside the available buffer boundaries, particularly on smaller terminal sizes or when the terminal is resized.

The fix adds minimal bounds checking to:

  1. Scrollbar rendering: Validates the scrollbar area fits within buffer boundaries before rendering
  2. Padding rendering: Ensures top/bottom padding areas don't extend beyond buffer limits

Comprehensive test coverage added: 10 unit tests covering all edge cases including the specific problematic buffer dimensions that previously caused panics (45×30, 76×30, 104×30, 135×37, etc.).

Tested across multiple terminal buffer sizes and confirmed no more buffer overflow panics while maintaining correct scrollbar functionality.

@FrozenPandaz FrozenPandaz requested review from a team as code owners August 11, 2025 16:18
@FrozenPandaz FrozenPandaz requested a review from Cammisuli August 11, 2025 16:18
Copy link

vercel bot commented Aug 11, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
nx-dev ✅ Ready (Inspect) Visit Preview Aug 11, 2025 5:11pm
Copy link
Contributor

nx-cloud bot commented Aug 11, 2025

View your CI Pipeline Execution ↗ for commit 49465f0

Command Status Duration Result
nx affected --targets=lint,test,build,e2e,e2e-c... ✅ Succeeded 7m 4s View ↗
nx run-many -t check-imports check-commit check... ✅ Succeeded 2m 25s View ↗
nx-cloud record -- nx-cloud conformance:check ✅ Succeeded 2s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded 4s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 4s View ↗
nx documentation ✅ Succeeded 50s View ↗

☁️ Nx Cloud last updated this comment at 2025-08-11 18:01:47 UTC

@FrozenPandaz FrozenPandaz force-pushed the fix-panic branch 2 times, most recently from 9a6f1e0 to 6057108 Compare August 11, 2025 16:27
Copy link
Contributor

🐳 We have a release for that!

This PR has a release associated with it. You can try it out using this command:

npx create-nx-workspace@0.0.0-pr-32292-49465f0 my-workspace

Or just copy this version and use it in your own command:

0.0.0-pr-32292-49465f0
Release details 📑
Published version 0.0.0-pr-32292-49465f0
Triggered by @FrozenPandaz
Branch fix-panic
Commit 49465f0
Workflow run 16889483646

To request a new release for this pull request, mention someone from the Nx team or the @nrwl/nx-pipelines-reviewers.

@FrozenPandaz FrozenPandaz merged commit aeb1803 into master Aug 11, 2025
7 of 8 checks passed
@FrozenPandaz FrozenPandaz deleted the fix-panic branch August 11, 2025 20:08
Copy link
Contributor

This pull request has already been merged/closed. If you experience issues related to these changes, please open a new issue referencing this pull request.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 17, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

2 participants