Skip to content

fix: pr-bug-scan validated finding from #2437#2445

Open
buf0-bot[bot] wants to merge 1 commit into
mainfrom
bot/pr-bug-scan-2437-1779303893
Open

fix: pr-bug-scan validated finding from #2437#2445
buf0-bot[bot] wants to merge 1 commit into
mainfrom
bot/pr-bug-scan-2437-1779303893

Conversation

@buf0-bot
Copy link
Copy Markdown
Contributor

@buf0-bot buf0-bot Bot commented May 20, 2026

Automated fix-PR from pr-bug-scan for parent #2437.

Fixer status: FIXED_WITH_REPRO
Summary: Fixed jsxElementReports: spread className now overrides earlier explicit className (later wins); expressionHasStyledScrollbarLiteral skips conditional/short-circuit branches so a conditional scrollbar class no longer waives inline-style checks.
Blocked proof link: config/scripts/styled-scrollbars/styled-scrollbar-jsx-check.mjs:248-260 (C1: ??= replaced with later-wins assignment) and :128-148 (C2: scrollbar literal walk now stops at conditional/&&/||/?? boundaries so it can't cover unconditional inline overflow)
Typecheck: skipped

Proof (from validator)

  • C1 — proof_type: code_analysis
    • trigger: JSX element with explicit className="scrollbar-sleek" followed by a spread attribute {...{ className: 'overflow-y-auto' }} — at runtime React's later spread overrides className, so the element renders with overflow-y-auto and no scrollbar class.
    • observable: reportUnstyledScrollbars returns [] for the trigger snippet, so the styled-scrollbar lint passes; however the rendered DOM has overflow-y-auto with no scrollbar-* class.
    • path:
      • config/scripts/styled-scrollbars/styled-scrollbar-jsx-check.mjs:248-260 jsxElementReports loops attributes; explicit className branch does classExpression = jsxAttributeExpression(attribute), while spread branch does classExpression ??= spreadPropExpressions(...).at(-1)
      • config/scripts/styled-scrollbars/styled-scrollbar-jsx-check.mjs:251 spread's ??= is a no-op once classExpression is already assigned by the earlier explicit className
      • config/scripts/styled-scrollbars/styled-scrollbar-jsx-check.mjs:268-271 collectClassLiteralReports then inspects only the explicit literal 'scrollbar-sleek' (no vertical overflow class) and produces no report; expressionHasStyledScrollbarLiteral returns true, so style checks are also skipped
  • C2 — proof_type: code_analysis
    • trigger: JSX element like <div className={enabled && 'scrollbar-sleek'} style={{ overflowY: 'auto' }} />. When enabled === false, className is falsy and only the inline overflowY: 'auto' is applied, so the native scrollbar shows.
    • observable: reportUnstyledScrollbars returns [] for the trigger; lint passes despite the falsy-branch DOM having overflow-y-auto with no scrollbar class.
    • path:
      • config/scripts/styled-scrollbars/styled-scrollbar-jsx-check.mjs:255-258 classExpression is set to the enabled && 'scrollbar-sleek' expression; styleExpressions collects the inline { overflowY: 'auto' }
      • config/scripts/styled-scrollbars/styled-scrollbar-jsx-check.mjs:265-271 collectClassLiteralReports walks the expression's string literals; only 'scrollbar-sleek' is present (no overflow class) so no class-literal report is produced
      • config/scripts/styled-scrollbars/styled-scrollbar-jsx-check.mjs:128-148 expressionHasStyledScrollbarLiteral does an unconditional some(token in STYLED_SCROLLBAR_CLASSES) walk and returns true regardless of the enabled && guard
      • config/scripts/styled-scrollbars/styled-scrollbar-jsx-check.mjs:275-277 jsxElementReports early-returns whenever expressionHasStyledScrollbarLiteral is true, so collectStyleReports is never invoked on the unconditional inline overflowY

Reproduction

node -e "import('/tmp/orca-bug-scan-wt/pr-2437-1779303893/config/scripts/styled-scrollbars/styled-scrollbar-jsx-check.mjs').then(m=>{console.log(m.reportUnstyledScrollbars('E.tsx',\"export function E(){return <div className=\\\"scrollbar-sleek\\\" {...{className:'overflow-y-auto'}}/>}\").length)})"

  • before fix: reportUnstyledScrollbars returns [] (length 0) for both C1 and C2 trigger snippets; lint passes despite unstyled overflow
  • after fix: reportUnstyledScrollbars returns a non-empty array (length >=1) for both C1 and C2 triggers; existing accepted cases still return []

Generated by pr-bug-scan (proof-machine architecture). Human approval required before merge.

Fixed jsxElementReports: spread className now overrides earlier explicit className (later wins); expressionHasStyledScrollbarLiteral skips conditional/short-circuit branches so a conditional scrollbar
@AmethystLiang AmethystLiang self-assigned this May 20, 2026
@AmethystLiang AmethystLiang self-requested a review May 20, 2026 21:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant