Skip to content

History persistence is not thread-safe and can lose or corrupt entries #22

Description

@offbyonebit

Severity: high
Type: bug
Location: clipsync/history.pyClipboardHistory.add_entry() (~line 185), set_max_items() (~line 220), clear() (~line 210), _persist() (~line 150)

Problem: add_entry() and the other mutators release self._lock before calling _persist(), and _persist() reads self._entries without any lock. Two threads (or the UI child process writing the same file) can interleave their read/write cycles, causing one thread’s newly appended entry to be overwritten by another thread’s stale snapshot.

Suggested fix: Have _persist() acquire self._lock for the entire read+write, and keep the lock held in all mutators until persistence finishes. For cross-process safety, use a process-unique temporary file name instead of a fixed .json.tmp.


Filed from a full-source audit of the repo (2026-07-29). Independently confirmed against the source before filing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    auditFound in the 2026-07 code auditbugSomething isn't workingseverity:highWrong behaviour users will hit

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions