Cheats: Add check for valid game genie code format
- Partially reverts changes in 0b362afcc0
- Checks the codestring if its a valid game genie code before attempting
to decode it. If code fails, then assume it to be a pro action replay
cheat.
Issue: Cheats where failing because a value of 0 in the decoder does not
mean an error.
Fix https://github.com/libretro/libretro-fceumm/issues/384
This commit is contained in:
@@ -332,33 +332,27 @@ int FCEUI_DecodeGG(const char *str, uint16 *a, uint8 *v, int *c) {
|
||||
if (s != 6 && s != 8) return(0);
|
||||
|
||||
t = GGtobin(*str++);
|
||||
if (!t) return (0);
|
||||
V |= (t & 0x07);
|
||||
V |= (t & 0x08) << 4;
|
||||
|
||||
t = GGtobin(*str++);
|
||||
if (!t) return (0);
|
||||
V |= (t & 0x07) << 4;
|
||||
A |= (t & 0x08) << 4;
|
||||
|
||||
t = GGtobin(*str++);
|
||||
if (!t) return (0);
|
||||
A |= (t & 0x07) << 4;
|
||||
/* if(t&0x08) return(0); */ /* 8-character code?! */
|
||||
|
||||
t = GGtobin(*str++);
|
||||
if (!t) return (0);
|
||||
A |= (t & 0x07) << 12;
|
||||
A |= (t & 0x08);
|
||||
|
||||
t = GGtobin(*str++);
|
||||
if (!t) return (0);
|
||||
A |= (t & 0x07);
|
||||
A |= (t & 0x08) << 8;
|
||||
|
||||
if (s == 6) {
|
||||
t = GGtobin(*str++);
|
||||
if (!t) return (0);
|
||||
A |= (t & 0x07) << 8;
|
||||
V |= (t & 0x08);
|
||||
|
||||
@@ -368,17 +362,14 @@ int FCEUI_DecodeGG(const char *str, uint16 *a, uint8 *v, int *c) {
|
||||
return(1);
|
||||
} else {
|
||||
t = GGtobin(*str++);
|
||||
if (!t) return (0);
|
||||
A |= (t & 0x07) << 8;
|
||||
C |= (t & 0x08);
|
||||
|
||||
t = GGtobin(*str++);
|
||||
if (!t) return (0);
|
||||
C |= (t & 0x07);
|
||||
C |= (t & 0x08) << 4;
|
||||
|
||||
t = GGtobin(*str++);
|
||||
if (!t) return (0);
|
||||
C |= (t & 0x07) << 4;
|
||||
V |= (t & 0x08);
|
||||
*a = A;
|
||||
|
||||
@@ -1958,6 +1958,31 @@ bool retro_unserialize(const void * data, size_t size)
|
||||
return true;
|
||||
}
|
||||
|
||||
static int checkGG(char c)
|
||||
{
|
||||
static const char lets[16] = { 'A', 'P', 'Z', 'L', 'G', 'I', 'T', 'Y', 'E', 'O', 'X', 'U', 'K', 'S', 'V', 'N' };
|
||||
int x;
|
||||
|
||||
for (x = 0; x < 16; x++)
|
||||
if (lets[x] == toupper(c))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int GGisvalid(const char *code)
|
||||
{
|
||||
size_t len = strlen(code);
|
||||
int i;
|
||||
|
||||
if (len != 6 && len != 8)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (!checkGG(code[i]))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void retro_cheat_reset(void)
|
||||
{
|
||||
FCEU_ResetCheats();
|
||||
@@ -2010,7 +2035,7 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code)
|
||||
if (a < 0x0100) type = 0;
|
||||
FCEUI_AddCheat(name, a, v, c, type);
|
||||
}
|
||||
else if (FCEUI_DecodeGG(codepart, &a, &v, &c))
|
||||
else if (GGisvalid(codepart) && FCEUI_DecodeGG(codepart, &a, &v, &c))
|
||||
{
|
||||
FCEUI_AddCheat(name, a, v, c, type);
|
||||
log_cb.log(RETRO_LOG_DEBUG, "Cheat code added: '%s' (GG)\n", codepart);
|
||||
@@ -2020,6 +2045,8 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code)
|
||||
FCEUI_AddCheat(name, a, v, c, type);
|
||||
log_cb.log(RETRO_LOG_DEBUG, "Cheat code added: '%s' (PAR)\n", codepart);
|
||||
}
|
||||
else
|
||||
log_cb.log(RETRO_LOG_DEBUG, "Invalid or unknown code: '%s'\n", codepart);
|
||||
codepart = strtok(NULL,"+,;._ ");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user