adjustments to ime_candidates - allocate ime_candidates on demand - allow write to the whole allocated memory of ime_candidates - ensure ime_candcount is set to zero in case the candidates can not be queried for any reason
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
diff --git a/src/video/windows/SDL_windowskeyboard.c b/src/video/windows/SDL_windowskeyboard.c
index bdf431f..6ab440d 100644
--- a/src/video/windows/SDL_windowskeyboard.c
+++ b/src/video/windows/SDL_windowskeyboard.c
@@ -67,7 +67,7 @@ WIN_InitKeyboard(_THIS)
data->ime_cursor = 0;
data->ime_candlist = SDL_FALSE;
- SDL_memset(data->ime_candidates, 0, sizeof(data->ime_candidates));
+ data->ime_candidates = NULL;
data->ime_candcount = 0;
data->ime_candref = 0;
data->ime_candsel = 0;
@@ -349,7 +349,7 @@ DEFINE_GUID(IID_ITfThreadMgrEx, 0x3E90ADE3,0x7594
#define SUBLANG() SUBLANGID(LANG())
static void IME_UpdateInputLocale(SDL_VideoData *videodata);
-static void IME_ShowCandidateList(SDL_VideoData *videodata);
+static int IME_ShowCandidateList(SDL_VideoData *videodata);
static void IME_ClearComposition(SDL_VideoData *videodata);
static void IME_SetWindow(SDL_VideoData* videodata, HWND hwnd);
static void IME_SetupAPI(SDL_VideoData *videodata);
@@ -801,12 +801,14 @@ IME_SendEditingEvent(SDL_VideoData *videodata)
static void
IME_AddCandidate(SDL_VideoData *videodata, UINT i, LPCWSTR candidate)
{
- LPWSTR dst = videodata->ime_candidates[i];
+ LPWSTR dst = &videodata->ime_candidates[i * MAX_CANDLENGTH];
+ LPWSTR end = &dst[MAX_CANDLENGTH - 1];
+ SDL_COMPILE_TIME_ASSERT(IME_CANDIDATE_INDEXING_REQUIRES, MAX_CANDLIST == 10);
*dst++ = (WCHAR)(TEXT('0') + ((i + videodata->ime_candlistindexbase) % 10));
if (videodata->ime_candvertical)
*dst++ = TEXT(' ');
- while (*candidate && (SDL_arraysize(videodata->ime_candidates[i]) > (dst - videodata->ime_candidates[i])))
+ while (*candidate && dst < end)
*dst++ = *candidate++;
*dst = (WCHAR)'\0';
@@ -819,8 +821,8 @@ IME_GetCandidateList(HWND hwnd, SDL_VideoData *videodata)
DWORD size;
LPCANDIDATELIST cand_list;
- IME_ShowCandidateList(videodata);
-
+ if (IME_ShowCandidateList(videodata) < 0)
+ return;
himc = ImmGetContext(hwnd);
if (!himc)
return;
@@ -857,7 +859,6 @@ IME_GetCandidateList(HWND hwnd, SDL_VideoData *videodata)
videodata->ime_candpgsize = SDL_min(cand_list->dwPageSize == 0 ? MAX_CANDLIST : cand_list->dwPageSize, MAX_CANDLIST);
page_start = (cand_list->dwSelection / videodata->ime_candpgsize) * videodata->ime_candpgsize;
}
- SDL_memset(&videodata->ime_candidates, 0, sizeof(videodata->ime_candidates));
for (i = page_start, j = 0; (DWORD)i < cand_list->dwCount && j < videodata->ime_candpgsize; i++, j++) {
LPCWSTR candidate = (LPCWSTR)((DWORD_PTR)cand_list + cand_list->dwOffset[i]);
IME_AddCandidate(videodata, j, candidate);
@@ -873,13 +874,26 @@ IME_GetCandidateList(HWND hwnd, SDL_VideoData *videodata)
ImmReleaseContext(hwnd, himc);
}
-static void
+static int
IME_ShowCandidateList(SDL_VideoData *videodata)
{
+ void *candidates;
+
+ videodata->ime_candcount = 0;
+ candidates = SDL_realloc(videodata->ime_candidates, MAX_CANDSIZE);
+ if (candidates != NULL)
+ videodata->ime_candidates = (WCHAR *)candidates;
+
+ if (videodata->ime_candidates == NULL)
+ return -1;
+
+ SDL_memset(videodata->ime_candidates, 0, MAX_CANDSIZE);
+
videodata->ime_dirty = SDL_TRUE;
videodata->ime_candlist = SDL_TRUE;
IME_DestroyTextures(videodata);
IME_SendEditingEvent(videodata);
+ return 0;
}
static void
@@ -995,7 +1009,8 @@ IME_CloseCandidateList(SDL_VideoData *videodata)
{
IME_HideCandidateList(videodata);
videodata->ime_candcount = 0;
- SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates));
+ SDL_free(videodata->ime_candidates);
+ videodata->ime_candidates = NULL;
}
static void
@@ -1008,13 +1023,15 @@ UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pca
DWORD pgstart = 0;
DWORD pgsize = 0;
UINT i, j;
+ if (IME_ShowCandidateList(videodata) < 0)
+ return;
+
pcandlist->lpVtbl->GetSelection(pcandlist, &selection);
pcandlist->lpVtbl->GetCount(pcandlist, &count);
pcandlist->lpVtbl->GetCurrentPage(pcandlist, &page);
videodata->ime_candsel = selection;
videodata->ime_candcount = count;
- IME_ShowCandidateList(videodata);
pcandlist->lpVtbl->GetPageIndex(pcandlist, 0, 0, &pgcount);
if (pgcount > 0) {
@@ -1032,8 +1049,6 @@ UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pca
}
videodata->ime_candpgsize = SDL_min(pgsize, MAX_CANDLIST);
videodata->ime_candsel = videodata->ime_candsel - pgstart;
-
- SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates));
for (i = pgstart, j = 0; (DWORD)i < count && j < videodata->ime_candpgsize; i++, j++) {
BSTR bstr;
if (SUCCEEDED(pcandlist->lpVtbl->GetString(pcandlist, i, &bstr))) {
@@ -1462,7 +1477,7 @@ IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc)
SelectObject(hdc, font);
for (i = 0; i < candcount; ++i) {
- const WCHAR *s = videodata->ime_candidates[i];
+ const WCHAR *s = &videodata->ime_candidates[i * MAX_CANDLENGTH];
if (!*s)
break;
@@ -1524,7 +1539,7 @@ IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc)
SetBkMode(hdc, TRANSPARENT);
for (i = 0; i < candcount; ++i) {
- const WCHAR *s = videodata->ime_candidates[i];
+ const WCHAR *s = &videodata->ime_candidates[i * MAX_CANDLENGTH];
int left, top, right, bottom;
if (!*s)
break;
diff --git a/src/video/windows/SDL_windowsvideo.h b/src/video/windows/SDL_windowsvideo.h
index 7dae16a..daf68e6 100644
--- a/src/video/windows/SDL_windowsvideo.h
+++ b/src/video/windows/SDL_windowsvideo.h
@@ -37,6 +37,7 @@
#define MAX_CANDLIST 10
#define MAX_CANDLENGTH 256
+#define MAX_CANDSIZE (sizeof(WCHAR) * MAX_CANDLIST * MAX_CANDLENGTH)
#include "SDL_windowsclipboard.h"
#include "SDL_windowsevents.h"
@@ -157,7 +158,7 @@ typedef struct SDL_VideoData
int ime_cursor;
SDL_bool ime_candlist;
- WCHAR ime_candidates[MAX_CANDLIST][MAX_CANDLENGTH];
+ WCHAR* ime_candidates;
DWORD ime_candcount;
DWORD ime_candref;
DWORD ime_candsel;