validate nickname characters within gen4 (#4382)

pkmnclassic has recently had some pokemon traded that cause game
crashes when viewing the pokemon's information, or when trying to
remove the pokemon for these boxes. most of these pokemon were reported
legal by pkhex however. this fixes the biggest use of these we've seen
actively traded (some of the other checks require more validation, as
they seemed to be buggy, we intend to validate those & send more PRs if
needed).

this check effectively covers "NULL Bytes" within the trainers name,
or the pokemon's nickname. We have attached an example pk4 that was
traded through our service that exhibits this issue, a couple notes:

- Generation 5+ seem to not be affected and replace character names with
  '?'
- Not all screens crash inside of Generation 4, the big ones our users
  noticed were viewing the pokemons information, and removal from the
  boxes.
- I also got a crash in pokemon ranch, but my testing setup was pretty
  hacky, and I'm not confident it wasn't something else, but we know
  it's potentially possible.

- We check for the terminator character '\uffff' which the pkhex string
  converter inserts implicitly when encountering an invalid character,
  but the actual underlying character when performing a hex dump is
  `\0`.
This commit is contained in:
Cynthia Coan 2024-11-11 20:28:01 -08:00 committed by GitHub
parent fced599119
commit f2a6abbb6c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 10 additions and 0 deletions

View file

@ -24,6 +24,11 @@ public sealed class NicknameVerifier : Verifier
return;
}
nickname = nickname[..len];
if (nickname.Contains('\uffff') && pk is { Format: 4 })
{
data.AddLine(GetInvalid(LNickInvalidChar));
return;
}
var enc = data.EncounterOriginal;
if (enc is ILangNicknamedTemplate n)

View file

@ -31,6 +31,11 @@ public sealed class TrainerNameVerifier : Verifier
return;
}
trainer = trainer[..len];
if (trainer.Contains('\uffff') && pk is { Format: 4 })
{
data.AddLine(GetInvalid("Trainer Name: Unkown Character"));
return;
}
if (IsOTNameSuspicious(trainer))
{