Skip to content

Fix clipboard heap corruption on Windows#215

Merged
ryanoneill merged 2 commits intomainfrom
fix/clipboard-heap-corruption
Mar 9, 2026
Merged

Fix clipboard heap corruption on Windows#215
ryanoneill merged 2 commits intomainfrom
fix/clipboard-heap-corruption

Conversation

@ryanoneill
Copy link
Owner

Summary

  • Root cause: arboard::Clipboard::new() initializes COM on Windows. When input_field and text_area tests run in parallel threads, concurrent COM init/teardown corrupts the heap, causing STATUS_HEAP_CORRUPTION (0xc0000374).
  • Fix: Extract clipboard access into a shared src/clipboard.rs module with a thread_local! cached arboard::Clipboard context. One COM initialization per thread, reused for the thread's lifetime.
  • Bonus: Eliminates duplicated clipboard functions that existed identically in both input_field/mod.rs and text_area/mod.rs.

What changed

File Change
src/clipboard.rs New shared module with system_clipboard_set/system_clipboard_get using thread-local caching
src/lib.rs Register clipboard module (gated on clipboard feature)
src/component/input_field/mod.rs Replace inline clipboard functions with import from shared module
src/component/text_area/mod.rs Replace inline clipboard functions with import from shared module
src/component/text_area/update.rs Update import path

Test plan

  • cargo test --all-features --lib passes (4086 tests)
  • cargo test --all-features --doc passes (787 tests)
  • cargo test --no-default-features --lib passes (793 tests)
  • cargo clippy --all-features -- -D warnings clean
  • CI passes on Windows (the platform where this manifests)

🤖 Generated with Claude Code

@codecov-commenter
Copy link

codecov-commenter commented Mar 8, 2026

Codecov Report

❌ Patch coverage is 90.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 92.12%. Comparing base (18a5375) to head (655fa1b).

Files with missing lines Patch % Lines
src/clipboard.rs 90.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #215      +/-   ##
==========================================
+ Coverage   92.08%   92.12%   +0.03%     
==========================================
  Files         145      146       +1     
  Lines       12778    12774       -4     
==========================================
+ Hits        11767    11768       +1     
+ Misses       1011     1006       -5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ryanoneill ryanoneill force-pushed the fix/clipboard-heap-corruption branch 2 times, most recently from 98417af to 88f1795 Compare March 9, 2026 01:10
ryanoneill and others added 2 commits March 8, 2026 18:22
On Windows, arboard::Clipboard::new() initializes COM per call. When
the test runner executes clipboard-touching tests from input_field and
text_area in parallel threads, concurrent COM initialization/teardown
corrupts the heap, causing STATUS_HEAP_CORRUPTION (0xc0000374).

Fix: Extract clipboard access into a shared src/clipboard.rs module
that caches the arboard::Clipboard context in a thread_local!. This
eliminates repeated COM init/teardown and also removes the duplicated
clipboard functions from input_field and text_area.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Thread-local caching was insufficient — concurrent Clipboard::new()
from different threads still caused heap corruption. Switch to a
process-global OnceLock<Mutex<Option<Clipboard>>> that creates exactly
one clipboard context and serializes all access.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ryanoneill ryanoneill force-pushed the fix/clipboard-heap-corruption branch from 88f1795 to 655fa1b Compare March 9, 2026 01:22
@ryanoneill ryanoneill merged commit bb5f5bb into main Mar 9, 2026
17 checks passed
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.

2 participants