Skip to content

Fixed memory width mismatch and null pointer issues in keyCodeForChar#2

Open
PekingSpades wants to merge 1 commit intogbevin:masterfrom
PekingSpades:master
Open

Fixed memory width mismatch and null pointer issues in keyCodeForChar#2
PekingSpades wants to merge 1 commit intogbevin:masterfrom
PekingSpades:master

Conversation

@PekingSpades
Copy link
Copy Markdown

Summary

This PR fixes two memory safety issues in keyCodeForChar() function in NativeSystemEventsMac.mm:

  1. Memory width mismatch: CFDictionaryGetValueIfPresent writes a pointer-sized value (8 bytes on 64-bit), but the original code passed &code where code is CGKeyCode (uint16_t, only 2 bytes). This causes stack corruption on 64-bit systems.

  2. Null pointer dereference: charStr could be NULL if CFStringCreateWithCharacters fails, but CFRelease(charStr) was called unconditionally.

Technical Details

The 64-bit Memory Corruption Bug

According to Apple's CF source code, the function signature is:

Boolean CFDictionaryGetValueIfPresent(CFDictionaryRef theDict, const void *key, const void **value);

The value parameter is "a pointer to memory which should be filled with the pointer-sized value".

The original code:

CGKeyCode code;  // uint16_t, only 2 bytes
CFDictionaryGetValueIfPresent(charToCodeDict, charStr, (const void **)&code);

On 64-bit systems, this writes 8 bytes into a 2-byte variable, corrupting adjacent stack memory.

As documented in A Collection of Examples of 64-bit Errors in Real Programs:

"Sometimes pointers are stored in integer types. Usually the int type is used for this purpose. This is perhaps one of the most frequent 64-bit errors."

"Due to shear luck, the pointer might always refer to objects located within the first 4 Gbytes of the address space during the testing."

This explains why such bugs can remain undetected for long periods.

The Fix

const void *value = NULL;  // Pointer-sized variable (8 bytes on 64-bit)
CGKeyCode code;

if (CFDictionaryGetValueIfPresent(charToCodeDict, charStr, &value))
{
    code = (CGKeyCode)(uintptr_t)value;
}

References

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.

1 participant