Skip to content
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

Crash with long IME compositions on Windows #5729

Closed
Guldoman opened this issue May 28, 2022 · 1 comment · Fixed by #5730
Closed

Crash with long IME compositions on Windows #5729

Guldoman opened this issue May 28, 2022 · 1 comment · Fixed by #5730

Comments

@Guldoman
Copy link
Contributor

Guldoman commented May 28, 2022

While comparing the IME behavior on Windows (#5398) against my PR #5617, I noticed that when doing long compositions (>64 bytes) a crash happened in SDL (2.0.22):

warning: Heap block at 000001F13D92F9E0 modified at 000001F13D92FA30 past requested size of 40

Thread 1 received signal SIGTRAP, Trace/breakpoint trap.
0x00007ffda1f4a313 in ntdll!RtlRegisterSecureMemoryCacheCallback () from /c/Windows/SYSTEM32/ntdll.dll
(gdb) bt
#0  0x00007ffda1f4a313 in ntdll!RtlRegisterSecureMemoryCacheCallback () from /c/Windows/SYSTEM32/ntdll.dll
#1  0x00007ffda1f4699f in ntdll!RtlZeroHeap () from /c/Windows/SYSTEM32/ntdll.dll
#2  0x00007ffda1f0ccc2 in ntdll!memset () from /c/Windows/SYSTEM32/ntdll.dll                                                                    #3  0x00007ffda1f491c1 in ntdll!RtlRegisterSecureMemoryCacheCallback () from /c/Windows/SYSTEM32/ntdll.dll
#4  0x00007ffda1e75cc1 in ntdll!RtlGetCurrentServiceSessionId () from /c/Windows/SYSTEM32/ntdll.dll                                             #5  0x00007ffda1e75b74 in ntdll!RtlGetCurrentServiceSessionId () from /c/Windows/SYSTEM32/ntdll.dll
#6  0x00007ffda1e747b1 in ntdll!RtlFreeHeap () from /c/Windows/SYSTEM32/ntdll.dll                                                               #7  0x00007ffda1199c9c in msvcrt!free () from /c/Windows/System32/msvcrt.dll
#8  0x00007ffd64b51d30 in SDL_free_REAL (ptr=0x1f13d92f9f0)
    at .../SDL2-2.0.22/src/stdlib/SDL_malloc.c:5432
#9  0x00007ffd64cd5d15 in IME_SendEditingEvent (videodata=0x1f1371e5820)
    at .../SDL2-2.0.22/src/video/windows/SDL_windowskeyboard.c:882
#10 0x00007ffd64cd63cd in IME_HandleMessage (hwnd=0x804a4, msg=271, wParam=12354, lParam=0x1001fe1b8, videodata=0x1f1371e5820)
    at .../SDL2-2.0.22/src/video/windows/SDL_windowskeyboard.c:1036
#11 0x00007ffd64cd0aea in WIN_WindowProc (hwnd=0x804a4, msg=271, wParam=12354, lParam=441)
    at .../SDL2-2.0.22/src/video/windows/SDL_windowsevents.c:666
#12 0x00007ffda1a8e858 in USER32!CallWindowProcW () from /c/Windows/System32/USER32.dll
#13 0x00007ffda1a8e299 in USER32!DispatchMessageW () from /c/Windows/System32/USER32.dll
#14 0x00007ffd64cd30f8 in WIN_PumpEvents (_this=0x1f1371e5200)
    at .../SDL2-2.0.22/src/video/windows/SDL_windowsevents.c:1535
#15 0x00007ffd64acd85a in SDL_PumpEventsInternal (push_sentinel=SDL_TRUE)
    at .../SDL2-2.0.22/src/events/SDL_events.c:847
#16 0x00007ffd64acdc69 in SDL_WaitEventTimeout_REAL (event=0x1001fe630, timeout=0)
    at .../SDL2-2.0.22/src/events/SDL_events.c:1024
#17 0x00007ffd64acd8fd in SDL_PollEvent_REAL (event=0x1001fe630)
    at .../SDL2-2.0.22/src/events/SDL_events.c:886
#18 0x00007ffd64abfb78 in SDL_PollEvent (a=0x1001fe630)
...

As this looked like a null terminator issue I added a bit of space for it, but a different crash happened:

warning: Heap block at 00000295F8725D20 modified at 00000295F8725D70 past requested size of 40

Thread 1 received signal SIGTRAP, Trace/breakpoint trap.
0x00007ffda1f4a313 in ntdll!RtlRegisterSecureMemoryCacheCallback () from /c/Windows/SYSTEM32/ntdll.dll
(gdb) bt
#0  0x00007ffda1f4a313 in ntdll!RtlRegisterSecureMemoryCacheCallback () from /c/Windows/SYSTEM32/ntdll.dll
#1  0x00007ffda1f4699f in ntdll!RtlZeroHeap () from /c/Windows/SYSTEM32/ntdll.dll
#2  0x00007ffda1f0ccc2 in ntdll!memset () from /c/Windows/SYSTEM32/ntdll.dll
#3  0x00007ffda1f491c1 in ntdll!RtlRegisterSecureMemoryCacheCallback () from /c/Windows/SYSTEM32/ntdll.dll                                      #4  0x00007ffda1e75cc1 in ntdll!RtlGetCurrentServiceSessionId () from /c/Windows/SYSTEM32/ntdll.dll
#5  0x00007ffda1e75b74 in ntdll!RtlGetCurrentServiceSessionId () from /c/Windows/SYSTEM32/ntdll.dll
#6  0x00007ffda1e747b1 in ntdll!RtlFreeHeap () from /c/Windows/SYSTEM32/ntdll.dll
#7  0x00007ffda1199c9c in msvcrt!free () from /c/Windows/System32/msvcrt.dll
#8  0x00007ffd64b51d30 in SDL_free_REAL (ptr=0x295f8725d30)
    at .../SDL2-2.0.22/src/stdlib/SDL_malloc.c:5432
#9  0x00007ffd64cd5816 in IME_GetCompositionString (videodata=0x295f8725820, himc=0x38b02b1, string=8)
    at .../SDL2-2.0.22/src/video/windows/SDL_windowskeyboard.c:776
#10 0x00007ffd64cd63c9 in IME_HandleMessage (hwnd=0x310768, msg=271, wParam=12354, lParam=0x9a165fe8a8, videodata=0x295f8725820)
    at .../SDL2-2.0.22/src/video/windows/SDL_windowskeyboard.c:1035
#11 0x00007ffd64cd0aea in WIN_WindowProc (hwnd=0x310768, msg=271, wParam=12354, lParam=441)
    at .../SDL2-2.0.22/src/video/windows/SDL_windowsevents.c:666
#12 0x00007ffda1a8e858 in USER32!CallWindowProcW () from /c/Windows/System32/USER32.dll
#13 0x00007ffda1a8e299 in USER32!DispatchMessageW () from /c/Windows/System32/USER32.dll
#14 0x00007ffd64cd30f8 in WIN_PumpEvents (_this=0x295f8725200)
    at .../SDL2-2.0.22/src/video/windows/SDL_windowsevents.c:1535
#15 0x00007ffd64acd85a in SDL_PumpEventsInternal (push_sentinel=SDL_TRUE)
    at .../SDL2-2.0.22/src/events/SDL_events.c:847
#16 0x00007ffd64acdc69 in SDL_WaitEventTimeout_REAL (event=0x0, timeout=379)
    at .../SDL2-2.0.22/src/events/SDL_events.c:1024
#17 0x00007ffd64abfbc3 in SDL_WaitEventTimeout (a=0x0, b=379)
    at .../SDL2-2.0.22/src/dynapi/SDL_dynapi_procs.h:155
...

As this one also looked like a null terminator problem (ImmGetCompositionStringW returns the length without it), I added space for that too.

So this seems to fix the crashes:

diff --git a/src/video/windows/SDL_windowskeyboard.c b/src/video/windows/SDL_windowskeyboard.c
index b9874a543..c71798fa2 100644
--- a/src/video/windows/SDL_windowskeyboard.c
+++ b/src/video/windows/SDL_windowskeyboard.c
@@ -65,7 +65,7 @@ WIN_InitKeyboard(_THIS)
     data->ime_hwnd_current = 0;
     data->ime_himc = 0;
     data->ime_composition_length = 32 * sizeof(WCHAR);
-    data->ime_composition = (WCHAR*)SDL_malloc(data->ime_composition_length);
+    data->ime_composition = (WCHAR*)SDL_malloc(data->ime_composition_length + sizeof(WCHAR));
     data->ime_composition[0] = 0;
     data->ime_readingstring[0] = 0;
     data->ime_cursor = 0;
@@ -813,7 +813,7 @@ IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string)
 
         length = ImmGetCompositionStringW(himc, GCS_COMPATTR, NULL, 0);
         if (length > 0) {
-            Uint8* attributes = (Uint8*)SDL_malloc(length);
+            Uint8* attributes = (Uint8*)SDL_malloc(length + sizeof(WCHAR));
             ImmGetCompositionString(himc, GCS_COMPATTR, attributes, length);
 
             for (start = 0; start < length; ++start) {
@@ -863,7 +863,7 @@ IME_SendEditingEvent(SDL_VideoData *videodata)
         size_t len = SDL_min(SDL_wcslen(videodata->ime_composition), (size_t)videodata->ime_cursor);
 
         size += sizeof(videodata->ime_readingstring);
-        buffer = (WCHAR*)SDL_malloc(size);
+        buffer = (WCHAR*)SDL_malloc(size + sizeof(WCHAR));
         buffer[0] = 0;
 
         SDL_wcslcpy(buffer, videodata->ime_composition, len + 1);
@@ -871,7 +871,7 @@ IME_SendEditingEvent(SDL_VideoData *videodata)
         SDL_wcslcat(buffer, &videodata->ime_composition[len], size);
     }
     else {
-        buffer = (WCHAR*)SDL_malloc(size);
+        buffer = (WCHAR*)SDL_malloc(size + sizeof(WCHAR));
         buffer[0] = 0;
         SDL_wcslcpy(buffer, videodata->ime_composition, size);
     }

Let me know if that looks reasonable and I'll PR it.

@slouken
Copy link
Collaborator

slouken commented May 28, 2022

Yup, that looks great.

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 a pull request may close this issue.

2 participants