Probably needed to be handled in the emulator too. Looking in player.h I can see this code straight away:
Code:
// used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1<<bit_index) without (-1)
// can't use enum for uint64 values
#define PLAYER_TITLE_DISABLED UI64LIT(0x0000000000000000)
#define PLAYER_TITLE_NONE UI64LIT(0x0000000000000001)
#define PLAYER_TITLE_PRIVATE UI64LIT(0x0000000000000002) // 1
#define PLAYER_TITLE_CORPORAL UI64LIT(0x0000000000000004) // 2
#define PLAYER_TITLE_SERGEANT_A UI64LIT(0x0000000000000008) // 3
#define PLAYER_TITLE_MASTER_SERGEANT UI64LIT(0x0000000000000010) // 4
#define PLAYER_TITLE_SERGEANT_MAJOR UI64LIT(0x0000000000000020) // 5
#define PLAYER_TITLE_KNIGHT UI64LIT(0x0000000000000040) // 6
#define PLAYER_TITLE_KNIGHT_LIEUTENANT UI64LIT(0x0000000000000080) // 7
#define PLAYER_TITLE_KNIGHT_CAPTAIN UI64LIT(0x0000000000000100) // 8
#define PLAYER_TITLE_KNIGHT_CHAMPION UI64LIT(0x0000000000000200) // 9
#define PLAYER_TITLE_LIEUTENANT_COMMANDER UI64LIT(0x0000000000000400) // 10
#define PLAYER_TITLE_COMMANDER UI64LIT(0x0000000000000800) // 11
#define PLAYER_TITLE_MARSHAL UI64LIT(0x0000000000001000) // 12
#define PLAYER_TITLE_FIELD_MARSHAL UI64LIT(0x0000000000002000) // 13
#define PLAYER_TITLE_GRAND_MARSHAL UI64LIT(0x0000000000004000) // 14
#define PLAYER_TITLE_SCOUT UI64LIT(0x0000000000008000) // 15
#define PLAYER_TITLE_GRUNT UI64LIT(0x0000000000010000) // 16
#define PLAYER_TITLE_SERGEANT_H UI64LIT(0x0000000000020000) // 17
#define PLAYER_TITLE_SENIOR_SERGEANT UI64LIT(0x0000000000040000) // 18
#define PLAYER_TITLE_FIRST_SERGEANT UI64LIT(0x0000000000080000) // 19
#define PLAYER_TITLE_STONE_GUARD UI64LIT(0x0000000000100000) // 20
#define PLAYER_TITLE_BLOOD_GUARD UI64LIT(0x0000000000200000) // 21
#define PLAYER_TITLE_LEGIONNAIRE UI64LIT(0x0000000000400000) // 22
#define PLAYER_TITLE_CENTURION UI64LIT(0x0000000000800000) // 23
#define PLAYER_TITLE_CHAMPION UI64LIT(0x0000000001000000) // 24
#define PLAYER_TITLE_LIEUTENANT_GENERAL UI64LIT(0x0000000002000000) // 25
#define PLAYER_TITLE_GENERAL UI64LIT(0x0000000004000000) // 26
#define PLAYER_TITLE_WARLORD UI64LIT(0x0000000008000000) // 27
#define PLAYER_TITLE_HIGH_WARLORD UI64LIT(0x0000000010000000) // 28
#define PLAYER_TITLE_GLADIATOR UI64LIT(0x0000000020000000) // 29
#define PLAYER_TITLE_DUELIST UI64LIT(0x0000000040000000) // 30
#define PLAYER_TITLE_RIVAL UI64LIT(0x0000000080000000) // 31
#define PLAYER_TITLE_CHALLENGER UI64LIT(0x0000000100000000) // 32
#define PLAYER_TITLE_SCARAB_LORD UI64LIT(0x0000000200000000) // 33
#define PLAYER_TITLE_CONQUEROR UI64LIT(0x0000000400000000) // 34
#define PLAYER_TITLE_JUSTICAR UI64LIT(0x0000000800000000) // 35
#define PLAYER_TITLE_CHAMPION_OF_THE_NAARU UI64LIT(0x0000001000000000) // 36
#define PLAYER_TITLE_MERCILESS_GLADIATOR UI64LIT(0x0000002000000000) // 37
#define PLAYER_TITLE_OF_THE_SHATTERED_SUN UI64LIT(0x0000004000000000) // 38
#define PLAYER_TITLE_HAND_OF_ADAL UI64LIT(0x0000008000000000) // 39
#define PLAYER_TITLE_VENGEFUL_GLADIATOR UI64LIT(0x0000010000000000) // 40
#define KNOWN_TITLES_SIZE 3
#define MAX_TITLE_INDEX (KNOWN_TITLES_SIZE*64) // 3 uint64 fields
This looks to be for PvP I guess. There is probably an enum somewhere for titles.
It is also possible that titles must be inside a FrameXML\GlueXML file somewhere. But I don't think this is the case.
A limit may also be hardcoded into the binary. Again, I doubt this.