Skip to content

fix: prevent unicode corruption from thread-unsafe OCR mutation#1388

Open
Project-A-E-G-I-S wants to merge 1 commit into
p0deje:masterfrom
Project-A-E-G-I-S:fix/ocr-thread-safety
Open

fix: prevent unicode corruption from thread-unsafe OCR mutation#1388
Project-A-E-G-I-S wants to merge 1 commit into
p0deje:masterfrom
Project-A-E-G-I-S:fix/ocr-thread-safety

Conversation

@Project-A-E-G-I-S

Copy link
Copy Markdown

Summary

Fixes a thread safety violation where VNRecognizeTextRequest's completion handler mutated a SwiftData @Model property from a background thread, gradually corrupting the ModelContext's internal state and causing random unicode corruption across all clipboard items.

Root Cause

In HistoryItem.generateTitle() (Maccy/Models/HistoryItem.swift:88-94), when the copied item is an image, a Task fires performTextRecognition(). Since generateTitle() is not @MainActor, this Task runs on the default global concurrent executor.

VNImageRequestHandler.perform() is synchronous (Maccy/Models/HistoryItem.swift:226) — the recognizeTextHandler completion handler executes on the same background thread. It directly set self.title on a SwiftData @Model object (line 241), which is only safe on the @MainActor.

This thread safety violation corrupts the shared ModelContext's internal snapshot and change tracking state. Over days of use, the corruption spreads to all loaded objects — not just images — manifesting as random unicode characters in clipboard text.

Quitting the app clears the in-memory context, which is why it temporarily 'fixes' itself on relaunch.

Fix

Capture the recognized text on the background thread (safe), then dispatch the SwiftData model mutation to @MainActor:

let text = recognizedStrings.joined(separator: "\n")
Task { @MainActor in
    self.title = text
}

Testing

  • Existing HistoryItemTests continue to pass
  • The OCR path is exercised whenever an image item's title is generated

Closes #1374

HistoryItem.generateTitle() fires a Task on the default executor to
perform text recognition via Vision. VNImageRequestHandler.perform()
is synchronous, so the recognizeTextHandler completion handler also
runs on that background thread. It was directly mutating self.title on
a SwiftData @model object — a thread safety violation that gradually
corrupts the ModelContext'\''s internal state, affecting ALL loaded
objects (not just images).

This explains the random unicode corruption reported in p0deje#1374: over
days of use, the accumulated corruption spreads to all clipboard
items. Quitting the app clears the in-memory context, which is why
it appears to '\''fix'\'' temporarily.

Fix: Dispatch the self.title mutation to @mainactor.

Closes p0deje#1374
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.

Additional unicode characters getting added to pinned items

1 participant