winport: tidy edit control sanitization

This commit is contained in:
zeromus 2022-08-21 15:06:03 -04:00
parent 319b365787
commit 26c3919358
2 changed files with 226 additions and 221 deletions

View File

@ -3283,6 +3283,198 @@ POINT CalcSubWindowPos(HWND hDlg, POINT* conf)
return pt;
}
bool IsInputLegal(bool (*IsLetterLegal)(char letter), char letter)
{
return !IsLetterLegal || letter == VK_BACK || GetKeyState(VK_CONTROL) & 0x8000 || IsLetterLegal(letter);
}
bool IsLetterLegalGG(char letter)
{
char ch = toupper(letter);
for (int i = 0; GameGenieLetters[i]; ++i)
if (GameGenieLetters[i] == ch)
return true;
return false;
}
bool IsLetterLegalHex(char letter)
{
return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f';
}
bool IsLetterLegalMemwatchAddress(char letter)
{
//accept normal hex stuff
if(letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f')
return true;
//accept prefixes
if(letter == 'x' || letter == 'X' || letter == '!')
return true;
return false;
}
bool IsLetterLegalHexList(char letter)
{
return IsLetterLegalHex(letter) || letter == ',' || letter == ' ';
}
bool IsLetterLegalCheat(char letter)
{
return letter >= '0' && letter <= ':' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '?';
}
bool IsLetterLegalSize(char letter)
{
return letter >= '0' && letter <= '9' || letter == 'm' || letter == 'M' || letter == 'k' || letter == 'K' || letter == 'b' || letter == 'B';
}
bool IsLetterLegalDec(char letter)
{
return letter >= '0' && letter <= '9' || letter == '-' || letter == '+';
}
bool IsLetterLegalFloat(char letter)
{
return letter >= '0' && letter <= '9' || letter == '.' || letter == '-' || letter == '+';
}
bool IsLetterLegalDecHexMixed(char letter)
{
return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '$' || letter == '-' || letter == '+';
}
bool IsLetterLegalUnsignedDecHexMixed(char letter)
{
return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '$';
}
wchar_t* GetLetterIllegalErrMsg(bool(*IsLetterLegal)(char letter))
{
if (IsLetterLegal == &IsLetterLegalGG)
return L"You can only type Game Genie characters:\nA P Z L G I T Y E O X U K S V N";
if (IsLetterLegal == &IsLetterLegalHex)
return L"You can only type characters for hexadecimal number (0-9,A-F).";
if (IsLetterLegal == &IsLetterLegalHexList)
return L"You can only type characters for hexademical number (0-9,A-F), each number is separated by a comma (,)";
if (IsLetterLegal == &IsLetterLegalCheat)
return
L"The cheat code comes into the following 2 formats:\n"
"AAAA:VV freezes the value in Address $AAAA to $VV.\n"
"AAAA?CC:VV changes the value in Address $AAAA to $VV only when it's $CC.\n"
"All the characters are hexadecimal number (0-9,A-F).\n";
if (IsLetterLegal == &IsLetterLegalFloat)
return L"You can only type decimal number (decimal point is acceptable).";
if (IsLetterLegal == &IsLetterLegalSize)
return L"You can only type decimal number followed with B, KB or MB.";
if (IsLetterLegal == &IsLetterLegalDec)
return L"You can only type decimal number (sign character is acceptable).";
if (IsLetterLegal == &IsLetterLegalDecHexMixed)
return
L"You can only type decimal or hexademical number\n"
"(sign character is acceptable).\n\n"
"When your number contains letter A-F,\n"
"it is regarded as hexademical number,\n"
"however, if you want to express a heademical number\n"
"but all the digits are in 0-9,\n"
"you must add a $ prefix to prevent ambiguous.\n"
"eg. 10 is a decimal number,\n"
"$10 means a hexademical number that is 16 in decimal.";
if (IsLetterLegal == &IsLetterLegalUnsignedDecHexMixed)
return
L"You can only type decimal or hexademical number.\n\n"
"When your number contains letter A-F,\n"
"it is regarded as hexademical number,\n"
"however, if you want to express a heademical number\n"
"but all the digits are in 0-9,\n"
"you must add a $ prefix to prevent ambiguous.\n"
"eg. 10 is a decimal number,\n"
"$10 means a hexademical number that is 16 in decimal.";
return L"Your input contains invalid characters.";
}
// return a letter legal checking function for the specified control with the given id
IsLetterLegalProc GetIsLetterLegalProc(UINT id)
{
switch (id)
{
// Game genie text in Cheat and Game Genie Encoder/Decoder
case IDC_CHEAT_GAME_GENIE_TEXT:
case IDC_GAME_GENIE_CODE:
return &IsLetterLegalGG;
// Addresses in Debugger
case IDC_DEBUGGER_VAL_PCSEEK:
case IDC_DEBUGGER_VAL_PC:
case IDC_DEBUGGER_VAL_A:
case IDC_DEBUGGER_VAL_X:
case IDC_DEBUGGER_VAL_Y:
case IDC_DEBUGGER_BOOKMARK:
// Debugger -> Add breakpoint
case IDC_ADDBP_ADDR_START: case IDC_ADDBP_ADDR_END:
// Array Size, Init value in Symbolic Name in Debugger
case IDC_EDIT_SYMBOLIC_ARRAY: case IDC_EDIT_SYMBOLIC_INIT:
// Address, Value, Compare, Known Value, Note equal, Greater than and Less than in Cheat
case IDC_CHEAT_ADDR: case IDC_CHEAT_VAL: case IDC_CHEAT_COM:
case IDC_CHEAT_VAL_KNOWN: case IDC_CHEAT_VAL_NE_BY:
case IDC_CHEAT_VAL_GT_BY: case IDC_CHEAT_VAL_LT_BY:
// Address, Value and Compare in Game Genie Encoder/Decoder
case IDC_GAME_GENIE_ADDR: case IDC_GAME_GENIE_VAL: case IDC_GAME_GENIE_COMP:
// Address controls in Memory watch
case MW_ADDR00: case MW_ADDR01: case MW_ADDR02: case MW_ADDR03:
case MW_ADDR04: case MW_ADDR05: case MW_ADDR06: case MW_ADDR07:
case MW_ADDR08: case MW_ADDR09: case MW_ADDR10: case MW_ADDR11:
case MW_ADDR12: case MW_ADDR13: case MW_ADDR14: case MW_ADDR15:
case MW_ADDR16: case MW_ADDR17: case MW_ADDR18: case MW_ADDR19:
case MW_ADDR20: case MW_ADDR21: case MW_ADDR22: case MW_ADDR23:
return &IsLetterLegalMemwatchAddress;
case IDC_EDIT_COMPAREADDRESS:
return &IsLetterLegalHex;
// Specific Address in RAM Search
// RAM Watch / RAM Search / Cheat -> Add watch (current only in adding watch operation)
case IDC_EDIT_COMPAREADDRESSES:
return &IsLetterLegalHexList;
// Size multiplier and TV Aspect in Video Config
case IDC_WINSIZE_MUL_X: case IDC_WINSIZE_MUL_Y:
case IDC_TVASPECT_X: case IDC_TVASPECT_Y:
return &IsLetterLegalFloat;
// Cheat code in Cheat
case IDC_CHEAT_TEXT:
return &IsLetterLegalCheat;
// PRG ROM, PRG RAM, PRG NVRAM, CHR ROM, CHR RAM and CHR NVRAM in NES Header Editor
case IDC_PRGROM_EDIT: case IDC_PRGRAM_EDIT: case IDC_PRGNVRAM_EDIT:
case IDC_CHRROM_EDIT: case IDC_CHRRAM_EDIT: case IDC_CHRNVRAM_EDIT:
return &IsLetterLegalSize;
// Specific value, Different by and Modulo in RAM search
case IDC_EDIT_COMPAREVALUE:
case IDC_EDIT_DIFFBY:
case IDC_EDIT_MODBY:
{
extern char rs_t;
switch (rs_t)
{
case 's': return &IsLetterLegalDecHexMixed;
case 'u': return &IsLetterLegalUnsignedDecHexMixed;
case 'h': return &IsLetterLegalHex;
}
}
}
return NULL;
}
LRESULT APIENTRY FilterEditCtrlProc(HWND hwnd, UINT msg, WPARAM wP, LPARAM lP)
{
bool through = true;
@ -3293,7 +3485,7 @@ LRESULT APIENTRY FilterEditCtrlProc(HWND hwnd, UINT msg, WPARAM wP, LPARAM lP)
case WM_PASTE:
{
bool (*IsLetterLegal)(char) = GetIsLetterLegal(GetDlgCtrlID(hwnd));
bool (*IsLetterLegal)(char) = GetIsLetterLegalProc(GetDlgCtrlID(hwnd));
if (IsLetterLegal)
{
@ -3325,97 +3517,19 @@ LRESULT APIENTRY FilterEditCtrlProc(HWND hwnd, UINT msg, WPARAM wP, LPARAM lP)
}
}
break;
case WM_CHAR:
{
bool(*IsLetterLegal)(char) = GetIsLetterLegal(GetDlgCtrlID(hwnd));
through = IsInputLegal(IsLetterLegal, wP);
IsLetterLegalProc isLetterLegal = GetIsLetterLegalProc(GetDlgCtrlID(hwnd));
through = IsInputLegal(isLetterLegal, wP);
if (!through)
ShowLetterIllegalBalloonTip(hwnd, IsLetterLegal);
ShowLetterIllegalBalloonTip(hwnd, isLetterLegal);
}
}
return through ? CallWindowProc(DefaultEditCtrlProc, hwnd, msg, wP, lP) : result;
}
// return a letter legal checking function for the specified control with the given id
bool inline (*GetIsLetterLegal(UINT id))(char letter)
{
switch (id)
{
// Game genie text in Cheat and Game Genie Encoder/Decoder
case IDC_CHEAT_GAME_GENIE_TEXT:
case IDC_GAME_GENIE_CODE:
return IsLetterLegalGG;
// Addresses in Debugger
case IDC_DEBUGGER_VAL_PCSEEK:
case IDC_DEBUGGER_VAL_PC:
case IDC_DEBUGGER_VAL_A:
case IDC_DEBUGGER_VAL_X:
case IDC_DEBUGGER_VAL_Y:
case IDC_DEBUGGER_BOOKMARK:
// Debugger -> Add breakpoint
case IDC_ADDBP_ADDR_START: case IDC_ADDBP_ADDR_END:
// Array Size, Init value in Symbolic Name in Debugger
case IDC_EDIT_SYMBOLIC_ARRAY: case IDC_EDIT_SYMBOLIC_INIT:
// Address, Value, Compare, Known Value, Note equal, Greater than and Less than in Cheat
case IDC_CHEAT_ADDR: case IDC_CHEAT_VAL: case IDC_CHEAT_COM:
case IDC_CHEAT_VAL_KNOWN: case IDC_CHEAT_VAL_NE_BY:
case IDC_CHEAT_VAL_GT_BY: case IDC_CHEAT_VAL_LT_BY:
// Address, Value and Compare in Game Genie Encoder/Decoder
case IDC_GAME_GENIE_ADDR: case IDC_GAME_GENIE_VAL: case IDC_GAME_GENIE_COMP:
// Address controls in Memory watch
case MW_ADDR00: case MW_ADDR01: case MW_ADDR02: case MW_ADDR03:
case MW_ADDR04: case MW_ADDR05: case MW_ADDR06: case MW_ADDR07:
case MW_ADDR08: case MW_ADDR09: case MW_ADDR10: case MW_ADDR11:
case MW_ADDR12: case MW_ADDR13: case MW_ADDR14: case MW_ADDR15:
case MW_ADDR16: case MW_ADDR17: case MW_ADDR18: case MW_ADDR19:
case MW_ADDR20: case MW_ADDR21: case MW_ADDR22: case MW_ADDR23:
case IDC_EDIT_COMPAREADDRESS:
return IsLetterLegalHex;
// Specific Address in RAM Search
// RAM Watch / RAM Search / Cheat -> Add watch (current only in adding watch operation)
case IDC_EDIT_COMPAREADDRESSES:
return IsLetterLegalHexList;
// Size multiplier and TV Aspect in Video Config
case IDC_WINSIZE_MUL_X: case IDC_WINSIZE_MUL_Y:
case IDC_TVASPECT_X: case IDC_TVASPECT_Y:
return IsLetterLegalFloat;
// Cheat code in Cheat
case IDC_CHEAT_TEXT:
return IsLetterLegalCheat;
// PRG ROM, PRG RAM, PRG NVRAM, CHR ROM, CHR RAM and CHR NVRAM in NES Header Editor
case IDC_PRGROM_EDIT: case IDC_PRGRAM_EDIT: case IDC_PRGNVRAM_EDIT:
case IDC_CHRROM_EDIT: case IDC_CHRRAM_EDIT: case IDC_CHRNVRAM_EDIT:
return IsLetterLegalSize;
// Specific value, Different by and Modulo in RAM search
case IDC_EDIT_COMPAREVALUE:
case IDC_EDIT_DIFFBY:
case IDC_EDIT_MODBY:
{
extern char rs_t;
switch (rs_t)
{
case 's': return IsLetterLegalDecHexMixed;
case 'u': return IsLetterLegalUnsignedDecHexMixed;
case 'h': return IsLetterLegalHex;
}
}
}
return NULL;
}
void ShowLetterIllegalBalloonTip(HWND hwnd, bool(*IsLetterLegal)(char letter))
{
wchar_t* title = L"Unacceptable Character";
@ -3431,102 +3545,3 @@ void ShowLetterIllegalBalloonTip(HWND hwnd, bool(*IsLetterLegal)(char letter))
// make a sound
MessageBeep(0xFFFFFFFF);
}
inline wchar_t* GetLetterIllegalErrMsg(bool(*IsLetterLegal)(char letter))
{
if (IsLetterLegal == IsLetterLegalGG)
return L"You can only type Game Genie characters:\nA P Z L G I T Y E O X U K S V N";
if (IsLetterLegal == IsLetterLegalHex)
return L"You can only type characters for hexadecimal number (0-9,A-F).";
if (IsLetterLegal == IsLetterLegalHexList)
return L"You can only type characters for hexademical number (0-9,A-F), each number is separated by a comma (,)";
if (IsLetterLegal == IsLetterLegalCheat)
return
L"The cheat code comes into the following 2 formats:\n"
"AAAA:VV freezes the value in Address $AAAA to $VV.\n"
"AAAA?CC:VV changes the value in Address $AAAA to $VV only when it's $CC.\n"
"All the characters are hexadecimal number (0-9,A-F).\n";
if (IsLetterLegal == IsLetterLegalFloat)
return L"You can only type decimal number (decimal point is acceptable).";
if (IsLetterLegal == IsLetterLegalSize)
return L"You can only type decimal number followed with B, KB or MB.";
if (IsLetterLegal == IsLetterLegalDec)
return L"You can only type decimal number (sign character is acceptable).";
if (IsLetterLegal == IsLetterLegalDecHexMixed)
return
L"You can only type decimal or hexademical number\n"
"(sign character is acceptable).\n\n"
"When your number contains letter A-F,\n"
"it is regarded as hexademical number,\n"
"however, if you want to express a heademical number\n"
"but all the digits are in 0-9,\n"
"you must add a $ prefix to prevent ambiguous.\n"
"eg. 10 is a decimal number,\n"
"$10 means a hexademical number that is 16 in decimal.";
if (IsLetterLegal == IsLetterLegalUnsignedDecHexMixed)
return
L"You can only type decimal or hexademical number.\n\n"
"When your number contains letter A-F,\n"
"it is regarded as hexademical number,\n"
"however, if you want to express a heademical number\n"
"but all the digits are in 0-9,\n"
"you must add a $ prefix to prevent ambiguous.\n"
"eg. 10 is a decimal number,\n"
"$10 means a hexademical number that is 16 in decimal.";
return L"Your input contains invalid characters.";
}
inline bool IsInputLegal(bool (*IsLetterLegal)(char letter), char letter)
{
return !IsLetterLegal || letter == VK_BACK || GetKeyState(VK_CONTROL) & 0x8000 || IsLetterLegal(letter);
}
inline bool IsLetterLegalGG(char letter)
{
char ch = toupper(letter);
for (int i = 0; GameGenieLetters[i]; ++i)
if (GameGenieLetters[i] == ch)
return true;
return false;
}
inline bool IsLetterLegalHex(char letter)
{
return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f';
}
inline bool IsLetterLegalHexList(char letter)
{
return IsLetterLegalHex(letter) || letter == ',' || letter == ' ';
}
inline bool IsLetterLegalCheat(char letter)
{
return letter >= '0' && letter <= ':' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '?';
}
inline bool IsLetterLegalSize(char letter)
{
return letter >= '0' && letter <= '9' || letter == 'm' || letter == 'M' || letter == 'k' || letter == 'K' || letter == 'b' || letter == 'B';
}
inline bool IsLetterLegalDec(char letter)
{
return letter >= '0' && letter <= '9' || letter == '-' || letter == '+';
}
inline bool IsLetterLegalFloat(char letter)
{
return letter >= '0' && letter <= '9' || letter == '.' || letter == '-' || letter == '+';
}
inline bool IsLetterLegalDecHexMixed(char letter)
{
return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '$' || letter == '-' || letter == '+';
}
inline bool IsLetterLegalUnsignedDecHexMixed(char letter)
{
return letter >= '0' && letter <= '9' || letter >= 'A' && letter <= 'F' || letter >= 'a' && letter <= 'f' || letter == '$';
}

View File

@ -128,19 +128,9 @@ struct HOTKEYMENUINDEX {
void UpdateMenuHotkeys(FCEUMENU_INDEX index);
int GetCurrentContextIndex();
inline bool (*GetIsLetterLegal(UINT id))(char letter);
inline wchar_t* GetLetterIllegalErrMsg(bool(*IsLetterLegal)(char letter));
void ShowLetterIllegalBalloonTip(HWND hwnd, bool(*IsLetterLegal)(char letter));
inline bool IsInputLegal(bool(*IsLetterLegal)(char letter), char letter);
inline bool IsLetterLegalGG(char letter);
inline bool IsLetterLegalHex(char letter);
inline bool IsLetterLegalHexList(char letter);
inline bool IsLetterLegalCheat(char letter);
inline bool IsLetterLegalDec(char letter);
inline bool IsLetterLegalSize(char letter);
inline bool IsLetterLegalFloat(char letter);
inline bool IsLetterLegalDecHexMixed(char letter);
inline bool IsLetterLegalUnsignedDecHexMixed(char letter);
typedef bool (*IsLetterLegalProc)(char);
bool IsLetterLegalHex(char letter);
void ShowLetterIllegalBalloonTip(HWND hwnd, IsLetterLegalProc);
extern WNDPROC DefaultEditCtrlProc;
extern LRESULT APIENTRY FilterEditCtrlProc(HWND hDlg, UINT msg, WPARAM wP, LPARAM lP);