Severity: high
Type: bug
Location: clipsync/history.py — ClipboardHistory.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.
Severity: high
Type: bug
Location:
clipsync/history.py—ClipboardHistory.add_entry()(~line 185),set_max_items()(~line 220),clear()(~line 210),_persist()(~line 150)Problem:
add_entry()and the other mutators releaseself._lockbefore calling_persist(), and_persist()readsself._entrieswithout 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()acquireself._lockfor 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.