- MotdParser: cap lineCount to 64 to prevent unbounded memory allocation,
add bounds check before each string read
- UpdateObjectParser: add bounds validation before each update mask block
and field value read to prevent reading past packet boundary
Add upfront validation and per-field bounds checking to prevent
undefined behavior when parsing truncated SMSG_CHAR_ENUM packets.
Gracefully handle missing character data with safe defaults.
SMSG_PARTY_COMMAND_RESULT improvements:
- Validate 8-byte minimum for command + result + name string
- Graceful handling of truncated result field
SMSG_GROUP_DECLINE improvements:
- Validate 1-byte minimum for playerName CString
- Prevent reading from empty packets
Ensures consistent error handling for group system packets.
SMSG_AUCTION_LIST_RESULT (Classic/TBC/WotLK) improvements:
- Cap auction count to 256 (prevents unbounded memory allocation)
- Each entry is 80-104 bytes depending on expansion
- Prevents DoS from servers sending huge auction lists
- Log warning when cap is reached
Prevents memory exhaustion from malformed auction house packets.
SMSG_GOSSIP_MESSAGE (3.3.5a) improvements:
- Validate 20-byte minimum for npcGuid + menuId + titleTextId + optionCount
- Cap optionCount to 64 (prevents unbounded memory allocation)
- Validate 12-byte minimum before each option read (fixed fields + 2 strings)
- Cap questCount to 64 (prevents unbounded memory allocation)
- Validate 18-byte minimum before each quest read (fixed fields + title string)
- Graceful truncation with partial list support
Prevents DoS from servers sending malformed gossip menus with huge option/quest lists.
SMSG_SPELL_COOLDOWN (3.3.5a) improvements:
- Validate 9-byte minimum for guid + flags
- Cap cooldown entries to 512 (each entry is 8 bytes: spellId + ms)
- Prevent unbounded memory allocation from malformed packets
- Log warning when cap is reached with remaining data ignored
Prevents DoS from servers sending malformed cooldown lists.
WotLK SMSG_AURA_UPDATE (3.3.5a) improvements:
- Cap entry count to 512 (isAll) or 1 (single) to prevent unbounded loop DoS
- Validate 5-byte minimum before each slot+spellId read
- Validate 3-byte minimum before flags/level/charges read
- Validate space before casterGuid packed GUID read
- Validate 8-byte minimum before duration field reads
- Validate 4-byte minimum before each effect amount read
- Graceful truncation with field initialization and partial read support
- Log all truncation events with entry index information
Prevents DoS and undefined behavior from high-frequency aura update packets.
Add DoS protection to Classic and TBC parseSpellGo implementations:
- Cap hitCount and missCount to 128 each (prevents OOM from huge arrays)
- Track actual reads vs expected counts
- Log truncation warnings with index information
- Graceful truncation with count updates
Ensures consistent hardening across all expansion variants (Vanilla/TBC/WotLK).
WotLK SMSG_SPELL_START (3.3.5a) improvements:
- Validate 22-byte minimum for packed GUIDs + fixed fields
- Validate targetFlags read (4 bytes)
- Validate targetGuid packed read with size check
WotLK SMSG_SPELL_GO (3.3.5a) improvements:
- Validate 24-byte minimum for core fields
- Cap hitCount to 128 to prevent OOM from huge target lists
- Cap missCount to 128 with same protection
- In-loop validation: check 8 bytes before each hit GUID read
- In-loop validation: check 2 bytes minimum before each miss entry (packed GUID + type)
- Graceful truncation with partial read support and count updates
Prevents DoS and undefined behavior from servers sending malformed combat packets.
Add upfront and in-loop validation for the WotLK variant of name query responses:
- Validate packed GUID and found flag reads (minimum 2 bytes)
- Validate strings can be read before attempting parse
- Validate 3 final uint8 fields (race/gender/class) exist before reading
- Graceful truncation handling with field initialization
Prevents undefined behavior from servers sending truncated/malformed packets.
Improve robustness of creature query response parsing by adding defensive
size checks to both WotLK/TBC and Classic variants:
- WotLK/TBC (world_packets.cpp): Add upfront validation for entry field,
validate minimum size (16 bytes) before reading fixed fields
(typeFlags, creatureType, family, rank), graceful truncation handling
- Classic (packet_parsers_classic.cpp): Add upfront entry validation,
enhance existing truncation check with default field initialization,
improve logging consistency
- Both variants now initialize fields to 0 on truncation and log warnings
with entry context
Part of ongoing Tier 2 work to improve multi-expansion packet parsing robustness
against malformed or truncated server packets.
Improve robustness of monster move spline parsing by capping the pointCount
field to prevent excessive iteration from malformed or malicious packets.
- WotLK: Cap pointCount to 1000 waypoints (realistic maximum for movement)
- Vanilla (Turtle): Reduce existing cap from 16384 to 1000 and add warning
logging when cap is applied
- Both variants now log warnings when cap is exceeded, including guid context
A malicious or corrupted server sending an unrealistic pointCount value (e.g.
uint32_max) could previously cause the client to allocate excessive memory or
iterate excessively. The 1000-waypoint cap aligns with realistic movement
paths while protecting against DoS vectors.
Part of ongoing Tier 2 work to improve multi-expansion packet parsing robustness.
Improve robustness of game object query response parsing by adding defensive
size checks to both WotLK/TBC and Classic variants:
- WotLK/TBC (world_packets.cpp): Add upfront validation for entry, type,
displayId fields, and improved in-loop handling for variable-length data
array with partial data graceful degradation
- Classic (packet_parsers_classic.cpp): Add upfront validation for entry,
type, displayId fields, and enhanced in-loop data array read with
truncation detection
- Both variants now log warnings when data fields are truncated
Part of ongoing Tier 2 work to improve multi-expansion packet parsing robustness
against malformed or truncated server packets.
Improve robustness of initial spells parsing by adding defensive size checks:
- Validate minimum packet size for header (talentSpec + spellCount)
- Cap spellCount to max 256 spells to prevent excessive iteration
- Add in-loop size checks for each spell entry before reading (4 bytes
vanilla, 6 bytes TBC/WotLK)
- Validate minimum size for cooldownCount field (optional, gracefully
handles truncation before it)
- Cap cooldownCount to max 256 cooldowns to prevent excessive iteration
- Add in-loop size checks for each cooldown entry before reading (14 bytes
vanilla, 16 bytes TBC/WotLK)
- Log warnings on packet truncation with clear context
Applies to both vanilla format (Classic) and TBC/WotLK format variants.
Part of ongoing Tier 2 work to improve multi-expansion packet parsing
robustness against malformed or truncated server packets.
Improve robustness of item query response parsing across all three expansions
by adding defensive size checks and bounds validation:
- WotLK (world_packets.cpp): Add upfront validation for fixed-size fields,
bounds cap on statsCount (max 10), in-loop size checks for stat pairs,
and improved logging for truncation detection
- Classic (packet_parsers_classic.cpp): Add upfront validation for fixed fields,
in-loop checks for 10 fixed stat pairs and 5 damage entries, and graceful
truncation handling
- TBC (packet_parsers_tbc.cpp): Add upfront validation, statsCount bounds cap,
and in-loop size checks for variable-length stats and fixed damage entries
All changes are backward compatible and log warnings on packet truncation.
This is part of ongoing Tier 2 work to improve multi-expansion packet parsing
robustness against malformed or truncated server packets.
Improve gossip message parser robustness by:
- Adding count caps (max 256 options/quests) to prevent excessive memory allocation
- Adding in-loop size validation to detect truncated packets
- Gracefully breaking loops instead of reading garbage when packet runs out
- Logging warnings when packet truncation is detected
Applies to both Classic and TBC parseGossipMessage implementations.
Part of Tier 1/2 work to improve parser robustness across multi-expansion support.
Improve parser robustness by adding defensive size checks to prevent reading
beyond packet boundaries. Specifically:
- parseCharEnum (Classic/TBC): Add packet size validation and character count cap
(max 32 chars) to prevent truncated packets from silently parsing garbage data
- parseMovementBlock (Classic/TBC): Add early validation for minimum packet size
before reading updateFlags to catch empty packets early
- All changes are backward compatible and log warnings on truncation
This is part of Tier 1/2 work to improve multi-expansion packet parsing robustness
and prevent undefined behavior from malformed or truncated server packets.
Add view-frustum intersection testing to QuestMarkerRenderer::render() using
Frustum::intersectsSphere(), bringing quest marker culling in line with the
character instance and WMO group frustum culling improvements. Reduces marker
visibility testing overhead in scenes with many off-screen quest givers.
Replace ad-hoc cone-based backface culling with proper view-frustum intersection
testing using Frustum::intersectsSphere(). Characters are now culled based on
visibility within the view frustum, improving accuracy in complex scenes and
reducing overdraw. Maintains distance-based culling for broad radius filtering.
Replace the basic forward-vector culling (which only culls when all AABB
corners are behind the camera) with proper frustum-AABB intersection testing
for more accurate and aggressive visibility culling. This reduces overdraw
and improves rendering performance in WMO-heavy scenes (dungeons, buildings).
Enable shadows in character preview with 0.5 strength for a subtle
lighting effect that improves visual accuracy. Removes clearShadowMap()
call and enables shadowParams in preview UBO. Enhances character
appearance fidelity when viewing equipment and customization options.
Look up tabard display ID from CreatureDisplayInfoExtra and map to
geoset variant via ItemDisplayInfo.dbc to select correct tabard
meshes. Falls back to hardcoded 1201 if DBC lookup unavailable.
Improves NPC appearance variety with proper scope handling.
Move ShadowParamsUBO from 5 separate shadow rendering functions (2 in
m2_renderer, 1 in terrain_renderer, 1 in wmo_renderer) into shared
vk_frame_data.hpp header. Eliminates 5 identical local struct definitions
and improves consistency across all shadow pass implementations. Structure
layout matches shader std140 uniform buffer requirements.
Move envSizeMBOrDefault and envSizeOrDefault from 4 separate rendering
modules (character_renderer, m2_renderer, terrain_renderer, wmo_renderer)
into shared vk_utils.hpp header as inline functions. Use the most robust
version which includes overflow checking for MB-to-bytes conversion. This
eliminates 7 identical local function definitions and improves consistency
across all rendering modules.
Move ShadowPush from 4 separate rendering modules (character_renderer,
m2_renderer, terrain_renderer, wmo_renderer) into shared vk_frame_data.hpp
header. This eliminates 4 identical local struct definitions and ensures
consistency across all shadow rendering passes. Add vk_frame_data.hpp include
to character_renderer.cpp.
Consolidated duplicate attachment point resolution code used by both
attachWeapon() and getAttachmentTransform(). New findAttachmentBone()
helper encapsulates the complete lookup chain: attachment by ID, fallback
scan, key-bone fallback, and validation. Eliminates ~55 lines of duplicate
code while improving maintainability and consistency.
Consolidated identical key-bone lookup logic that appeared at lines 3076
and 3099. Both performed the same search for weapon attachment points
(ID 1/2 for right/left hand). Removed duplication while preserving
behavior and improving code clarity with better comments.
The itExtra variable is not in scope at the tabard rendering site.
Reverted to original hardcoded 1201 fallback which is working reliably.
DBC variant approach requires refactoring variable scope.
Reads equipped tabard display ID from CreatureDisplayInfoExtra (slot 9)
and looks up the corresponding geoset group in ItemDisplayInfo.dbc to
select the correct tabard variant. Falls back to hardcoded 1201 if DBC
unavailable. Improves NPC appearance variety without risky features.
Remove redundant helmet attachment code path (lines 6490-6566) that was
disabled and inferior to the main path. The main path (enabled in Loop 25)
provides better fallback logic by trying attachment points 0 and 11,
includes proper logging, and has undergone validation.
This consolidation reduces code duplication by 78 lines, improves
maintainability, and eliminates potentially wasteful spawn-time overhead
from the disabled path.
Add fallback logic to use bone 0 for head attachment point (ID 11) when models
don't have it explicitly defined. This improves helmet rendering compatibility
on humanoid NPC models that lack explicit attachment 11 definitions. Re-enable
helmet attachments now that the fallback logic is in place.
- Add showMinimap_ and showRaidFrames_ visibility flags to GameScreen
- Wire up TOGGLE_MINIMAP (M key) to toggle minimap visibility
- Wire up TOGGLE_RAID_FRAMES (F key) to toggle party/raid frame visibility
- Conditional rendering of minimap markers and party frames
- Completes keybinding manager integration for all 15 customizable actions
- Replace hardcoded SDL_SCANCODE_ESCAPE with TOGGLE_SETTINGS keybinding
- Replace hardcoded SDL_SCANCODE_RETURN with TOGGLE_CHAT keybinding
- Allows customization of these keys through Settings UI
- Add TOGGLE_BAGS action to keybinding manager (B key default)
- Update inventory_screen.cpp to use keybinding manager for bag and character toggles
- Maintain consistent keybinding system across all UI windows
The keybinding manager had incorrect default key assignments:
- TOGGLE_SPELLBOOK was S (should be P - WoW standard)
- TOGGLE_TALENTS was K (should be N - WoW standard)
These mismatched the actual hardcoded keys in spellbook_screen.cpp (P) and
talent_screen.cpp (N), as well as user expectations from standard WoW.
Update keybinding defaults to align with WoW conventions and the actual UI
implementations that are using these keys.
The quest log screen was using a hardcoded SDL_SCANCODE_L key check instead of
the keybinding manager system, preventing users from customizing the keybinding.
Update to use KeybindingManager::Action::TOGGLE_QUESTS (bound to L by default),
allowing users to customize the quest log toggle key through the Settings UI
while maintaining the default WoW key binding.
This enables consistency with other customizable window toggles that already use
the keybinding system (Character Screen, Inventory, Spellbook, World Map, etc.).
The R key was previously assigned to TOGGLE_RAID_FRAMES in the keybinding
manager but was never actually implemented (raid frames had no visibility
toggle). Loop 10 implemented R for camera reset, creating a conflict.
Reassign TOGGLE_RAID_FRAMES to F (an unused key) to prevent the conflict.
This aligns with the intention that R is now the standard camera reset key.
Allow R key to reset camera position/rotation when chat input is not active.
Previously disabled due to conflict with chat reply command. Now uses the same
safety check as movement keys (ImGui::GetIO().WantTextInput).
Implements edge-triggered reset on R key press, matching X key (sit) pattern.
Implement showWorldMap_ state variable and TOGGLE_WORLD_MAP keybinding
integration to allow players to customize the W key binding for opening/
closing the World Map, consistent with other window toggles like Nameplates
(V key) and Guild Roster (O key).
Enable tabard mesh rendering for NPCs by reading geoset variant from
ItemDisplayInfo.dbc (slot 9). Tabards now render like other equipment
instead of being disabled due to the previous flickering issue.
- Add World Map (W), Nameplates (V), Raid Frames (R), Quest Log (Q) to
KeybindingManager enum with customizable default bindings
- Replace hard-coded V key check for nameplate toggle with
KeybindingManager::isActionPressed() to support customization
- Update config file persistence to handle new bindings
- Infrastructure in place for implementing visibility toggles on other
windows (World Map, Raid Frames, Quest Log) with future UI refactoring
- Extended KeybindingManager enum with TOGGLE_GUILD_ROSTER (O) and
TOGGLE_DUNGEON_FINDER (J) to replace hard-coded key checks
- Added Controls tab in Settings UI for rebinding all 10 customizable actions
- Implemented real-time key capture and binding with visual feedback
- Integrated keybinding persistence with main settings.cfg file
- Replaced hard-coded O key (Guild Roster) and I key (Dungeon Finder) checks
with KeybindingManager::isActionPressed() calls
- Added Reset to Defaults button for restoring original keybindings