Fix crash when using backspace/delete/arrow keys at string boundaries in text input fields

- Added bounds checking to VK_BACK, VK_DELETE, VK_LEFT, VK_RIGHT handlers
- Fixed out-of-bounds array access in CharPrev/CharNext calls
- Fixed GetSubString() to calculate correct substring length
- Prevents crash when cursor is at end of string in login/chat/input fields
This commit is contained in:
2025-12-02 23:38:05 +09:00
parent 1f5d035273
commit 95bdc3b6e7
2 changed files with 39 additions and 26 deletions

View File

@@ -118,7 +118,7 @@ void GMIMEPACK::InitIme( HWND hMainWnd, UINT unStringLimit )
m_vtCandidateList.reserve( m_unCandidateOnceRetrieveCount ); // '9' is basic windows default retrieve count
m_vtCandidateList.clear();
// <20>±<EFBFBD><C2B1>϶<EFBFBD><CFB6><EFBFBD> LID_THAI<41>ִ´<D6B4>.
// <20>±<EFBFBD><C2B1>϶<EFBFBD><CFB6><EFBFBD> LID_THAI<41>ִ´<D6B4>.
if ( CRYLNetworkData::Instance()->m_eInternationalCode == GameRYL::THAILAND )
OnInputLangChange( 0, ZIme::LID_THAI ); // check current keyboard layout
else
@@ -179,21 +179,21 @@ bool GMIMEPACK::GetIMEMessage( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam
case WM_IME_STARTCOMPOSITION:
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><ECBFA1> <20>۾<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><ECBFA1> <20>۾<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
return OnImeStartComposition( wParam, lParam );
}
break;
case WM_IME_COMPOSITION:
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>۾<EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>۾<EFBFBD>
return OnImeComposition( wParam, lParam );
}
break;
case WM_IME_ENDCOMPOSITION:
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>
return OnImeEndComposition( wParam, lParam );
}
break;
@@ -217,11 +217,11 @@ void GMIMEPACK::OpenIme()
ImmSetOpenStatus( m_hImc, true );
/* <09><><EFBFBD><EFBFBD> / <20>ݰ<EFBFBD> <20><>ȯ<EFBFBD>ҷ<EFBFBD><D2B7><EFBFBD> <20>ص<EFBFBD> <20>ӽ<EFBFBD> <20>ڵ<EFBFBD>
/* <09><><EFBFBD><EFBFBD> / <20>ݰ<EFBFBD> <20><>ȯ<EFBFBD>ҷ<EFBFBD><D2B7><EFBFBD> <20>ص<EFBFBD> <20>ӽ<EFBFBD> <20>ڵ<EFBFBD>
DWORD dwConv, dwSent ;
::ImmGetConversionStatus( m_hImc, &dwConv, &dwSent ) ;
//dwConv = IME_CMODE_FULLSHAPE ;
dwConv &= ~IME_CMODE_FULLSHAPE; //<2F>ݰ<EFBFBD>
dwConv &= ~IME_CMODE_FULLSHAPE; //<2F>ݰ<EFBFBD>
::ImmSetConversionStatus( m_hImc, dwConv, dwSent ) ;
*/
@@ -370,14 +370,18 @@ bool GMIMEPACK::OnKeyDown( WPARAM wParam, LPARAM lParam )
case VK_LEFT:
{
LPSTR buf = CharPrev( &m_strCurrentString[ 0 ], &m_strCurrentString[ m_unCaretPos ] );
if( m_unCaretPos > 0 && m_unCaretPos <= m_strCurrentString.length() )
{
UINT safePos = (m_unCaretPos > m_strCurrentString.length()) ? static_cast<UINT>(m_strCurrentString.length()) : m_unCaretPos;
LPSTR buf = CharPrev( &m_strCurrentString[ 0 ], &m_strCurrentString[ 0 ] + safePos );
UINT unPos = static_cast<UINT>( &m_strCurrentString[ m_unCaretPos ] - buf );
UINT unPos = static_cast<UINT>( (&m_strCurrentString[ 0 ] + safePos) - buf );
if( unPos != 0 && m_unPrimaryLanguage == ZIme::KEY_THAI )
unPos = 1;
m_unCaretPos -= unPos;
}
// when shift key was pushed, select string
if( m_bShiftPushed )
@@ -423,14 +427,17 @@ bool GMIMEPACK::OnKeyDown( WPARAM wParam, LPARAM lParam )
case VK_RIGHT:
{
LPSTR buf = CharNext( &m_strCurrentString[ m_unCaretPos ] );
if( m_unCaretPos < m_strCurrentString.length() )
{
LPSTR buf = CharNext( &m_strCurrentString[ 0 ] + m_unCaretPos );
UINT unPos = static_cast<UINT>( buf - &m_strCurrentString[ m_unCaretPos ] );
UINT unPos = static_cast<UINT>( buf - (&m_strCurrentString[ 0 ] + m_unCaretPos) );
if( unPos != 0 && m_unPrimaryLanguage == ZIme::KEY_THAI )
unPos = 1;
m_unCaretPos += unPos;
}
// when shift key was pushed, select string
if( m_bShiftPushed )
@@ -489,10 +496,11 @@ bool GMIMEPACK::OnKeyDown( WPARAM wParam, LPARAM lParam )
m_bTextSelecting = false;
}
else
else if( m_unCaretPos > 0 && m_unCaretPos <= m_strCurrentString.length() )
{
LPSTR buf = CharPrev( &m_strCurrentString[ 0 ], &m_strCurrentString[ m_unCaretPos ] );
UINT unPos = static_cast<UINT>( &m_strCurrentString[ m_unCaretPos ] - buf );
UINT safePos = (m_unCaretPos > m_strCurrentString.length()) ? static_cast<UINT>(m_strCurrentString.length()) : m_unCaretPos;
LPSTR buf = CharPrev( &m_strCurrentString[ 0 ], &m_strCurrentString[ 0 ] + safePos );
UINT unPos = static_cast<UINT>( (&m_strCurrentString[ 0 ] + safePos) - buf );
if( unPos != 0 && m_unPrimaryLanguage == ZIme::KEY_THAI )
unPos = 1;
@@ -522,10 +530,10 @@ bool GMIMEPACK::OnKeyDown( WPARAM wParam, LPARAM lParam )
m_bTextSelecting = false;
}
else
else if( m_unCaretPos < m_strCurrentString.length() )
{
LPSTR buf = CharNext( &m_strCurrentString[ m_unCaretPos ] );
UINT unPos = static_cast<UINT>( buf - &m_strCurrentString[ m_unCaretPos ] );
LPSTR buf = CharNext( &m_strCurrentString[ 0 ] + m_unCaretPos );
UINT unPos = static_cast<UINT>( buf - (&m_strCurrentString[ 0 ] + m_unCaretPos) );
if( unPos != 0 && m_unPrimaryLanguage == ZIme::KEY_THAI )
unPos = 1;
@@ -793,7 +801,7 @@ bool GMIMEPACK::OnInputLangChange( WPARAM wParam, LPARAM lParam )
}
break;
// Traditional Chinese(<28>븸)
// Traditional Chinese(<28>븸)
case ZIme::LID_TRADITIONAL_CHINESE:
{
m_unPrimaryLanguage = ZIme::KEY_TRADITIONAL_CHINESE;
@@ -832,7 +840,7 @@ bool GMIMEPACK::OnInputLangChange( WPARAM wParam, LPARAM lParam )
}
break;
// Simplified Chinese(<28>߱<EFBFBD>)
// Simplified Chinese(<28>߱<EFBFBD>)
case ZIme::LID_SIMPLIFIED_CHINESE:
{
m_unPrimaryLanguage = ZIme::KEY_SIMPLIFIED_CHINESE;

View File

@@ -57,7 +57,7 @@ private:
//-----------------------------------------------------------------------------------------------------
// concerned with copy & paste, cut
static string m_strCopyString; // custom string clipboard ( <20><>CAUTION<4F><4E> THIS IS STATIC MEMBER!!! Every IME Instance share this string )
static string m_strCopyString; // custom string clipboard ( <20><>CAUTION<4F><4E> THIS IS STATIC MEMBER!!! Every IME Instance share this string )
UINT m_unSelectStartPos; // caret position where selection start ( smaller than end pos )
UINT m_unSelectEndPos; // caret position where selection end ( larger than start pos )
@@ -117,7 +117,12 @@ public:
//-----------------------------------------------------------------------------------------------------
// get something
inline const char* GetString() { return m_strCurrentString.c_str(); }
inline const string GetSubString( unsigned int unStartPos, unsigned int unEndPos ) { return m_strCurrentString.substr( unStartPos, unEndPos ); }
inline const string GetSubString( unsigned int unStartPos, unsigned int unEndPos ) {
if (unStartPos > m_strCurrentString.length()) return "";
if (unEndPos > m_strCurrentString.length()) unEndPos = m_strCurrentString.length();
if (unStartPos > unEndPos) return "";
return m_strCurrentString.substr( unStartPos, unEndPos - unStartPos );
}
inline const UINT GetStringLength() { return static_cast<UINT>( m_strCurrentString.length() ); }
inline const char* GetBackupString() { return m_strBackupString.c_str(); }
inline const UINT GetBackupStrinLength() { return static_cast<UINT>( m_strBackupString.length() ); }