Skip to content

Fix CFRelease memory safety issues causing potential crashes in OpenKey - #3

Draft
sonthepham-dev with Copilot wants to merge 12 commits into
masterfrom
copilot/fix-8ab73de4-a7d1-47fe-9483-806674813250
Draft

Fix CFRelease memory safety issues causing potential crashes in OpenKey#3
sonthepham-dev with Copilot wants to merge 12 commits into
masterfrom
copilot/fix-8ab73de4-a7d1-47fe-9483-806674813250

Conversation

Copilot AI commented Jul 31, 2025

Copy link
Copy Markdown

Problem

The OpenKey macOS application had several critical memory safety issues in OpenKey.mm that could cause crashes and memory corruption:

  1. CFRelease without NULL checks: Multiple functions called CFRelease on CGEventRef objects without checking if they were NULL first
  2. Incorrect CFRelease usage: Attempting to release objects that weren't retained (from CFArrayGetValueAtIndex)
  3. Memory leaks: TISInputSourceRef objects not being released in all code paths

Root Cause

According to Apple's Core Foundation documentation, CGEventCreateKeyboardEvent can return NULL if it fails to create the event object. Calling CFRelease on a NULL pointer causes immediate crashes. Additionally, objects returned by CFArrayGetValueAtIndex are not retained and should not be released.

Solution

Added NULL checks before all CFRelease calls:

// Before (unsafe)
_newEventDown = CGEventCreateKeyboardEvent(myEventSource, 0, true);
_newEventUp = CGEventCreateKeyboardEvent(myEventSource, 0, false);
CGEventTapPostEvent(_proxy, _newEventDown);
CFRelease(_newEventDown);  // Crash if _newEventDown is NULL

// After (safe)
_newEventDown = CGEventCreateKeyboardEvent(myEventSource, 0, true);
_newEventUp = CGEventCreateKeyboardEvent(myEventSource, 0, false);
if (_newEventDown && _newEventUp) {
    CGEventTapPostEvent(_proxy, _newEventDown);
    CGEventTapPostEvent(_proxy, _newEventUp);
}
if (_newEventDown) CFRelease(_newEventDown);
if (_newEventUp) CFRelease(_newEventUp);

Fixed incorrect CFRelease usage:

// Before (incorrect - langRef is not retained)
CFStringRef langRef = (CFStringRef)CFArrayGetValueAtIndex(languages, 0);
CFRelease(langRef);  // CRASH - releasing non-retained object

// After (correct - only release retained objects)
CFStringRef langRef = (CFStringRef)CFArrayGetValueAtIndex(languages, 0);
// No CFRelease for langRef - it's not retained
CFRelease(isource);  // Only release the retained isource object

Protected global event objects:

Added NULL checks for eventBackSpaceDown and eventBackSpaceUp usage to prevent crashes if these fail to initialize.

Impact

These fixes prevent potential crashes and memory corruption issues in the OpenKey Vietnamese input method, making it significantly more stable and reliable for users. The changes are minimal and surgical, only adding necessary safety checks without altering the application's functionality.

Testing

  • Verified all CFRelease calls now have proper NULL checks
  • Confirmed no syntax errors or logic issues introduced
  • Reviewed all Core Foundation object lifecycle management in codebase

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: sonthepham-dev <46697168+sonthepham-dev@users.noreply.github.com>
Copilot AI changed the title [WIP] find bug and fix Fix CFRelease memory safety issues causing potential crashes in OpenKey Jul 31, 2025
Copilot AI requested a review from sonthepham-dev July 31, 2025 06:41
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