-
Notifications
You must be signed in to change notification settings - Fork 944
Fix: initialize MData and AXUIElementRef to avoid segfault in get_active #755
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: initialize MData and AXUIElementRef to avoid segfault in get_active #755
Conversation
📝 WalkthroughWalkthroughThis pull request addresses a SIGSEGV crash in the Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
window/window.h
🔇 Additional comments (1)
window/window.h (1)
373-384: LGTM: Correct logic and memory management.The refactored logic correctly handles all cases:
- Success path: Both conditions succeed →
resultis populated with valid values,elementownership transfers to caller (no release here).- Partial failure: Outer condition succeeds but inner fails →
elementis properly released (line 382),resultremains zero-initialized.- Early failure: Outer condition fails →
elementremains NULL, no release needed,resultremains zero-initialized.Memory management is sound. The caller is responsible for releasing
result.AxID(handled viapub_mData.AxIDcleanup insetHandle()at lines 179-181).
| MData get_active(void) { | ||
| #if defined(IS_MACOSX) | ||
| MData result; | ||
| MData result = {0}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical fix: zero-initialize result to prevent undefined behavior.
This initialization is essential to ensure that all error paths return deterministic zero values instead of garbage memory. Without this, callers like is_valid() could dereference invalid pointers when checking result.AxID, causing the SIGSEGV described in issue #754.
🤖 Prompt for AI Agents
In window/window.h around line 353, the MData variable 'result' is not being
zero-initialized which can leave fields (like result.AxID) containing garbage
and cause undefined behavior or SIGSEGV on error paths; fix this by initializing
result to zero (e.g., set all bytes/fields to zero) at declaration so all
callers receive deterministic zeroed fields on failure and avoid dereferencing
invalid pointers.
| if (focused == NULL) { return result; } // Verify | ||
|
|
||
| AXUIElementRef element; | ||
| AXUIElementRef element = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical fix: initialize element to NULL.
Initializing element to NULL prevents garbage pointer propagation. Previously, if AXUIElementCopyAttributeValue() failed (common in CI environments without accessibility permissions), the uninitialized element could contain a garbage pointer that might pass the null check and be assigned to result.AxID, leading to crashes when dereferenced downstream.
🤖 Prompt for AI Agents
In window/window.h around line 370, the local variable 'element' must be
explicitly initialized to NULL to avoid propagation of a garbage pointer when
AXUIElementCopyAttributeValue() fails; update the declaration so 'element' is
initialized to NULL, ensuring subsequent null checks are reliable and preventing
invalid pointers from being assigned to result.AxID.
| return result; | ||
| #elif defined(USE_X11) | ||
| MData result; | ||
| MData result = {0}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Good: Consistent zero-initialization across all platforms.
Applying the same initialization pattern to X11 and Windows paths ensures consistent, deterministic behavior across all platforms and eliminates undefined behavior. This aligns with secure coding best practices (CERT C EXP33-C) and prevents similar issues from manifesting on other platforms.
Also applies to: 428-428
🤖 Prompt for AI Agents
In window/window.h around lines 389 and 428, the MData structures are not
explicitly zero-initialized on both X11 and Windows code paths; change the
declarations to use explicit zero-initialization (e.g., MData result = {0};) at
both locations so the structs are deterministically initialized across platforms
and avoid undefined behavior.
Summary
Fix segmentation fault (SIGSEGV) in
get_active()andGetTitle()functions caused by uninitialized variables, particularly in headless CI environments.Fixes: #754
Problem
The
get_active()function inwindow/window.hhas uninitialized local variables that cause undefined behavior:When
AXUIElementCopyAttributeValue()fails (common in CI environments without accessibility permissions), the uninitializedelementvariable contains a garbage pointer value. This garbage value is then used in subsequentAXUIElement*calls, causing SIGSEGV.CI Environment Specifics
GitHub Actions macOS runners cannot grant Accessibility Permissions because System Integrity Protection (SIP) is enabled. This causes
AXUIElementCopyAttributeValue()to fail, triggering the buggy code path.Root Cause Analysis
According to SEI CERT C Coding Standard (EXP33-C):
The C Standard specifies:
Effect
is_valid()= falseTesting
TestGetTitleReferences
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.